From 36b273c6d27221f2de7283f0fa8640c2bbc87adb Mon Sep 17 00:00:00 2001 From: Michael Fletcher Date: Tue, 19 Nov 2024 15:51:24 +0000 Subject: [PATCH 1/8] Base changes --- .../src/v0.8/llo-feeds/v0.5.0/FeeManager.sol | 507 +++++++++++ .../v0.8/llo-feeds/v0.5.0/RewardManager.sol | 321 +++++++ .../src/v0.8/llo-feeds/v0.5.0/Verifier.sol | 559 +++++++++++++ .../v0.8/llo-feeds/v0.5.0/VerifierProxy.sol | 229 +++++ .../v0.5.0/interfaces/IFeeManager.sol | 78 ++ .../v0.5.0/interfaces/IRewardManager.sol | 69 ++ .../llo-feeds/v0.5.0/interfaces/IVerifier.sol | 123 +++ .../v0.5.0/interfaces/IVerifierFeeManager.sol | 37 + .../v0.5.0/interfaces/IVerifierProxy.sol | 80 ++ .../test/fee-manager/BaseFeeManager.t.sol | 379 +++++++++ .../test/fee-manager/FeeManager.general.t.sol | 242 ++++++ .../FeeManager.getFeeAndReward.t.sol | 606 ++++++++++++++ .../fee-manager/FeeManager.processFee.t.sol | 492 +++++++++++ .../FeeManager.processFeeBulk.t.sol | 193 +++++ .../v0.5.0/test/gas/Gas_VerifierTest.t.sol | 230 +++++ .../v0.5.0/test/mocks/ErroredVerifier.sol | 95 +++ .../v0.5.0/test/mocks/ExposedVerifier.sol | 69 ++ .../v0.5.0/test/mocks/FeeManagerProxy.sol | 20 + .../reward-manager/BaseRewardManager.t.sol | 262 ++++++ .../reward-manager/RewardManager.claim.t.sol | 790 ++++++++++++++++++ .../RewardManager.general.t.sol | 69 ++ .../RewardManager.payRecipients.t.sol | 194 +++++ .../RewardManager.setRecipients.t.sol | 148 ++++ ...RewardManager.updateRewardRecipients.t.sol | 450 ++++++++++ .../test/verifier/BaseVerifierTest.t.sol | 502 +++++++++++ .../verifier/VerifierActivateConfigTest.t.sol | 63 ++ .../verifier/VerifierDeactivateFeedTest.t.sol | 108 +++ .../VerifierProxyConstructorTest.t.sol | 24 + .../VerifierProxyInitializeVerifierTest.t.sol | 30 + ...VerifierProxySetAccessControllerTest.t.sol | 34 + .../VerifierProxySetVerifierTest.t.sol | 41 + .../test/verifier/VerifierProxyTest.t.sol | 23 + .../VerifierProxyUnsetVerifierTest.t.sol | 42 + .../VerifierSetConfigFromSourceTest.t.sol | 134 +++ .../test/verifier/VerifierSetConfigTest.t.sol | 243 ++++++ .../v0.5.0/test/verifier/VerifierTest.t.sol | 42 + .../verifier/VerifierTestBillingReport.t.sol | 218 +++++ .../verifier/VerifierUnsetConfigTest.t.sol | 56 ++ .../test/verifier/VerifierVerifyTest.t.sol | 314 +++++++ 39 files changed, 8116 insertions(+) create mode 100644 contracts/src/v0.8/llo-feeds/v0.5.0/FeeManager.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.5.0/RewardManager.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.5.0/Verifier.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.5.0/VerifierProxy.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.5.0/interfaces/IFeeManager.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.5.0/interfaces/IRewardManager.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.5.0/interfaces/IVerifier.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.5.0/interfaces/IVerifierFeeManager.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.5.0/interfaces/IVerifierProxy.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.5.0/test/fee-manager/BaseFeeManager.t.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.5.0/test/fee-manager/FeeManager.general.t.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.5.0/test/fee-manager/FeeManager.getFeeAndReward.t.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.5.0/test/fee-manager/FeeManager.processFee.t.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.5.0/test/fee-manager/FeeManager.processFeeBulk.t.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.5.0/test/gas/Gas_VerifierTest.t.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.5.0/test/mocks/ErroredVerifier.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.5.0/test/mocks/ExposedVerifier.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.5.0/test/mocks/FeeManagerProxy.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.5.0/test/reward-manager/BaseRewardManager.t.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.5.0/test/reward-manager/RewardManager.claim.t.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.5.0/test/reward-manager/RewardManager.general.t.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.5.0/test/reward-manager/RewardManager.payRecipients.t.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.5.0/test/reward-manager/RewardManager.setRecipients.t.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.5.0/test/reward-manager/RewardManager.updateRewardRecipients.t.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/BaseVerifierTest.t.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierActivateConfigTest.t.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierDeactivateFeedTest.t.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierProxyConstructorTest.t.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierProxyInitializeVerifierTest.t.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierProxySetAccessControllerTest.t.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierProxySetVerifierTest.t.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierProxyTest.t.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierProxyUnsetVerifierTest.t.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierSetConfigFromSourceTest.t.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierSetConfigTest.t.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierTest.t.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierTestBillingReport.t.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierUnsetConfigTest.t.sol create mode 100644 contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierVerifyTest.t.sol diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/FeeManager.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/FeeManager.sol new file mode 100644 index 00000000000..44f550e3253 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/FeeManager.sol @@ -0,0 +1,507 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.19; + +import {ConfirmedOwner} from "../../shared/access/ConfirmedOwner.sol"; +import {IFeeManager} from "./interfaces/IFeeManager.sol"; +import {TypeAndVersionInterface} from "../../interfaces/TypeAndVersionInterface.sol"; +import {IERC165} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; +import {Common} from "../libraries/Common.sol"; +import {IRewardManager} from "./interfaces/IRewardManager.sol"; +import {IWERC20} from "../../shared/interfaces/IWERC20.sol"; +import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC20.sol"; +import {Math} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/math/Math.sol"; +import {SafeERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol"; +import {IVerifierFeeManager} from "./interfaces/IVerifierFeeManager.sol"; + +/** + * @title FeeManager + * @author Michael Fletcher + * @author Austin Born + * @notice This contract is used for the handling of fees required for users verifying reports. + */ +contract FeeManager is IFeeManager, ConfirmedOwner, TypeAndVersionInterface { + using SafeERC20 for IERC20; + + /// @notice list of subscribers and their discounts subscriberDiscounts[subscriber][feedId][token] + mapping(address => mapping(bytes32 => mapping(address => uint256))) public s_subscriberDiscounts; + + /// @notice keep track of any subsidised link that is owed to the reward manager. + mapping(bytes32 => uint256) public s_linkDeficit; + + /// @notice the total discount that can be applied to a fee, 1e18 = 100% discount + uint64 private constant PERCENTAGE_SCALAR = 1e18; + + /// @notice the LINK token address + address public immutable i_linkAddress; + + /// @notice the native token address + address public immutable i_nativeAddress; + + /// @notice the proxy address + address public immutable i_proxyAddress; + + /// @notice the reward manager address + IRewardManager public immutable i_rewardManager; + + // @notice the mask to apply to get the report version + bytes32 private constant REPORT_VERSION_MASK = 0xffff000000000000000000000000000000000000000000000000000000000000; + + // @notice the different report versions + bytes32 private constant REPORT_V1 = 0x0001000000000000000000000000000000000000000000000000000000000000; + + /// @notice the surcharge fee to be paid if paying in native + uint256 public s_nativeSurcharge; + + /// @notice the error thrown if the discount or surcharge is invalid + error InvalidSurcharge(); + + /// @notice the error thrown if the discount is invalid + error InvalidDiscount(); + + /// @notice the error thrown if the address is invalid + error InvalidAddress(); + + /// @notice thrown if msg.value is supplied with a bad quote + error InvalidDeposit(); + + /// @notice thrown if a report has expired + error ExpiredReport(); + + /// @notice thrown if a report has no quote + error InvalidQuote(); + + // @notice thrown when the caller is not authorized + error Unauthorized(); + + // @notice thrown when trying to clear a zero deficit + error ZeroDeficit(); + + /// @notice thrown when trying to pay an address that cannot except funds + error InvalidReceivingAddress(); + + /// @notice Emitted whenever a subscriber's discount is updated + /// @param subscriber address of the subscriber to update discounts for + /// @param feedId Feed ID for the discount + /// @param token Token address for the discount + /// @param discount Discount to apply, in relation to the PERCENTAGE_SCALAR + event SubscriberDiscountUpdated(address indexed subscriber, bytes32 indexed feedId, address token, uint64 discount); + + /// @notice Emitted when updating the native surcharge + /// @param newSurcharge Surcharge amount to apply relative to PERCENTAGE_SCALAR + event NativeSurchargeUpdated(uint64 newSurcharge); + + /// @notice Emits when this contract does not have enough LINK to send to the reward manager when paying in native + /// @param rewards Config digest and link fees which could not be subsidised + event InsufficientLink(IRewardManager.FeePayment[] rewards); + + /// @notice Emitted when funds are withdrawn + /// @param adminAddress Address of the admin + /// @param recipient Address of the recipient + /// @param assetAddress Address of the asset withdrawn + /// @param quantity Amount of the asset withdrawn + event Withdraw(address adminAddress, address recipient, address assetAddress, uint192 quantity); + + /// @notice Emits when a deficit has been cleared for a particular config digest + /// @param configDigest Config digest of the deficit cleared + /// @param linkQuantity Amount of LINK required to pay the deficit + event LinkDeficitCleared(bytes32 indexed configDigest, uint256 linkQuantity); + + /// @notice Emits when a fee has been processed + /// @param configDigest Config digest of the fee processed + /// @param subscriber Address of the subscriber who paid the fee + /// @param fee Fee paid + /// @param reward Reward paid + /// @param appliedDiscount Discount applied to the fee + event DiscountApplied( + bytes32 indexed configDigest, + address indexed subscriber, + Common.Asset fee, + Common.Asset reward, + uint256 appliedDiscount + ); + + /** + * @notice Construct the FeeManager contract + * @param _linkAddress The address of the LINK token + * @param _nativeAddress The address of the wrapped ERC-20 version of the native token (represents fee in native or wrapped) + * @param _proxyAddress The address of the proxy contract + * @param _rewardManagerAddress The address of the reward manager contract + */ + constructor( + address _linkAddress, + address _nativeAddress, + address _proxyAddress, + address _rewardManagerAddress + ) ConfirmedOwner(msg.sender) { + if ( + _linkAddress == address(0) || + _nativeAddress == address(0) || + _proxyAddress == address(0) || + _rewardManagerAddress == address(0) + ) revert InvalidAddress(); + + i_linkAddress = _linkAddress; + i_nativeAddress = _nativeAddress; + i_proxyAddress = _proxyAddress; + i_rewardManager = IRewardManager(_rewardManagerAddress); + + IERC20(i_linkAddress).approve(address(i_rewardManager), type(uint256).max); + } + + modifier onlyOwnerOrProxy() { + if (msg.sender != i_proxyAddress && msg.sender != owner()) revert Unauthorized(); + _; + } + + modifier onlyProxy() { + if (msg.sender != i_proxyAddress) revert Unauthorized(); + _; + } + + /// @inheritdoc TypeAndVersionInterface + function typeAndVersion() external pure override returns (string memory) { + return "FeeManager 2.0.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 payload, + bytes calldata parameterPayload, + address subscriber + ) external payable override onlyProxy { + (Common.Asset memory fee, Common.Asset memory reward, uint256 appliedDiscount) = _processFee( + payload, + parameterPayload, + subscriber + ); + + if (fee.amount == 0) { + _tryReturnChange(subscriber, msg.value); + return; + } + + IFeeManager.FeeAndReward[] memory feeAndReward = new IFeeManager.FeeAndReward[](1); + feeAndReward[0] = IFeeManager.FeeAndReward(bytes32(payload), fee, reward, appliedDiscount); + + if (fee.assetAddress == i_linkAddress) { + _handleFeesAndRewards(subscriber, feeAndReward, 1, 0); + } else { + _handleFeesAndRewards(subscriber, feeAndReward, 0, 1); + } + } + + /// @inheritdoc IVerifierFeeManager + function processFeeBulk( + bytes[] calldata payloads, + bytes calldata parameterPayload, + address subscriber + ) external payable override onlyProxy { + FeeAndReward[] memory feesAndRewards = new IFeeManager.FeeAndReward[](payloads.length); + + //keep track of the number of fees to prevent over initialising the FeePayment array within _convertToLinkAndNativeFees + uint256 numberOfLinkFees; + uint256 numberOfNativeFees; + + uint256 feesAndRewardsIndex; + for (uint256 i; i < payloads.length; ++i) { + (Common.Asset memory fee, Common.Asset memory reward, uint256 appliedDiscount) = _processFee( + payloads[i], + parameterPayload, + subscriber + ); + + if (fee.amount != 0) { + feesAndRewards[feesAndRewardsIndex++] = IFeeManager.FeeAndReward( + bytes32(payloads[i]), + fee, + reward, + appliedDiscount + ); + + unchecked { + //keep track of some tallys to make downstream calculations more efficient + if (fee.assetAddress == i_linkAddress) { + ++numberOfLinkFees; + } else { + ++numberOfNativeFees; + } + } + } + } + + if (numberOfLinkFees != 0 || numberOfNativeFees != 0) { + _handleFeesAndRewards(subscriber, feesAndRewards, numberOfLinkFees, numberOfNativeFees); + } else { + _tryReturnChange(subscriber, msg.value); + } + } + + /// @inheritdoc IFeeManager + function getFeeAndReward( + address subscriber, + bytes memory report, + address quoteAddress + ) public view returns (Common.Asset memory, Common.Asset memory, uint256) { + Common.Asset memory fee; + Common.Asset memory reward; + + //get the feedId from the report + bytes32 feedId = bytes32(report); + + //the report needs to be a support version + bytes32 reportVersion = _getReportVersion(feedId); + + //version 1 of the reports don't require quotes, so the fee will be 0 + if (reportVersion == REPORT_V1) { + fee.assetAddress = i_nativeAddress; + reward.assetAddress = i_linkAddress; + return (fee, reward, 0); + } + + //verify the quote payload is a supported token + if (quoteAddress != i_nativeAddress && quoteAddress != i_linkAddress) { + revert InvalidQuote(); + } + + //decode the report depending on the version + uint256 linkQuantity; + uint256 nativeQuantity; + uint256 expiresAt; + (, , , nativeQuantity, linkQuantity, expiresAt) = abi.decode( + report, + (bytes32, uint32, uint32, uint192, uint192, uint32) + ); + + //read the timestamp bytes from the report data and verify it has not expired + if (expiresAt < block.timestamp) { + revert ExpiredReport(); + } + + //get the discount being applied + uint256 discount = s_subscriberDiscounts[subscriber][feedId][quoteAddress]; + + //the reward is always set in LINK + reward.assetAddress = i_linkAddress; + reward.amount = Math.ceilDiv(linkQuantity * (PERCENTAGE_SCALAR - discount), PERCENTAGE_SCALAR); + + //calculate either the LINK fee or native fee if it's within the report + if (quoteAddress == i_linkAddress) { + fee.assetAddress = i_linkAddress; + fee.amount = reward.amount; + } else { + uint256 surchargedFee = Math.ceilDiv(nativeQuantity * (PERCENTAGE_SCALAR + s_nativeSurcharge), PERCENTAGE_SCALAR); + + fee.assetAddress = i_nativeAddress; + fee.amount = Math.ceilDiv(surchargedFee * (PERCENTAGE_SCALAR - discount), PERCENTAGE_SCALAR); + } + + //return the fee + return (fee, reward, discount); + } + + /// @inheritdoc IVerifierFeeManager + function setFeeRecipients( + bytes32 configDigest, + Common.AddressAndWeight[] calldata rewardRecipientAndWeights + ) external onlyOwnerOrProxy { + i_rewardManager.setRewardRecipients(configDigest, rewardRecipientAndWeights); + } + + /// @inheritdoc IFeeManager + function setNativeSurcharge(uint64 surcharge) external onlyOwner { + if (surcharge > PERCENTAGE_SCALAR) revert InvalidSurcharge(); + + s_nativeSurcharge = surcharge; + + emit NativeSurchargeUpdated(surcharge); + } + + /// @inheritdoc IFeeManager + function updateSubscriberDiscount( + address subscriber, + bytes32 feedId, + address token, + uint64 discount + ) external onlyOwner { + //make sure the discount is not greater than the total discount that can be applied + if (discount > PERCENTAGE_SCALAR) revert InvalidDiscount(); + //make sure the token is either LINK or native + if (token != i_linkAddress && token != i_nativeAddress) revert InvalidAddress(); + + s_subscriberDiscounts[subscriber][feedId][token] = discount; + + emit SubscriberDiscountUpdated(subscriber, feedId, token, discount); + } + + /// @inheritdoc IFeeManager + function withdraw(address assetAddress, address recipient, uint192 quantity) external onlyOwner { + //address 0 is used to withdraw native in the context of withdrawing + if (assetAddress == address(0)) { + (bool success, ) = payable(recipient).call{value: quantity}(""); + + if (!success) revert InvalidReceivingAddress(); + return; + } + + //withdraw the requested asset + IERC20(assetAddress).safeTransfer(recipient, quantity); + + //emit event when funds are withdrawn + emit Withdraw(msg.sender, recipient, assetAddress, uint192(quantity)); + } + + /// @inheritdoc IFeeManager + function linkAvailableForPayment() external view returns (uint256) { + //return the amount of LINK this contact has available to pay rewards + return IERC20(i_linkAddress).balanceOf(address(this)); + } + + /** + * @notice Gets the current version of the report that is encoded as the last two bytes of the feed + * @param feedId feed id to get the report version for + */ + function _getReportVersion(bytes32 feedId) internal pure returns (bytes32) { + return REPORT_VERSION_MASK & feedId; + } + + function _processFee( + bytes calldata payload, + bytes calldata parameterPayload, + address subscriber + ) internal view returns (Common.Asset memory, Common.Asset memory, uint256) { + if (subscriber == address(this)) revert InvalidAddress(); + + //decode the report from the payload + (, bytes memory report) = abi.decode(payload, (bytes32[3], bytes)); + + //get the feedId from the report + bytes32 feedId = bytes32(report); + + //v1 doesn't need a quote payload, so skip the decoding + address quote; + if (_getReportVersion(feedId) != REPORT_V1) { + //decode the quote from the bytes + (quote) = abi.decode(parameterPayload, (address)); + } + + //decode the fee, it will always be native or LINK + return getFeeAndReward(subscriber, report, quote); + } + + function _handleFeesAndRewards( + address subscriber, + FeeAndReward[] memory feesAndRewards, + uint256 numberOfLinkFees, + uint256 numberOfNativeFees + ) internal { + IRewardManager.FeePayment[] memory linkRewards = new IRewardManager.FeePayment[](numberOfLinkFees); + IRewardManager.FeePayment[] memory nativeFeeLinkRewards = new IRewardManager.FeePayment[](numberOfNativeFees); + + uint256 totalNativeFee; + uint256 totalNativeFeeLinkValue; + + uint256 linkRewardsIndex; + uint256 nativeFeeLinkRewardsIndex; + + uint256 totalNumberOfFees = numberOfLinkFees + numberOfNativeFees; + for (uint256 i; i < totalNumberOfFees; ++i) { + if (feesAndRewards[i].fee.assetAddress == i_linkAddress) { + linkRewards[linkRewardsIndex++] = IRewardManager.FeePayment( + feesAndRewards[i].configDigest, + uint192(feesAndRewards[i].reward.amount) + ); + } else { + nativeFeeLinkRewards[nativeFeeLinkRewardsIndex++] = IRewardManager.FeePayment( + feesAndRewards[i].configDigest, + uint192(feesAndRewards[i].reward.amount) + ); + totalNativeFee += feesAndRewards[i].fee.amount; + totalNativeFeeLinkValue += feesAndRewards[i].reward.amount; + } + + if (feesAndRewards[i].appliedDiscount != 0) { + emit DiscountApplied( + feesAndRewards[i].configDigest, + subscriber, + feesAndRewards[i].fee, + feesAndRewards[i].reward, + feesAndRewards[i].appliedDiscount + ); + } + } + + //keep track of change in case of any over payment + uint256 change; + + if (msg.value != 0) { + //there must be enough to cover the fee + if (totalNativeFee > msg.value) revert InvalidDeposit(); + + //wrap the amount required to pay the fee & approve as the subscriber paid in wrapped native + IWERC20(i_nativeAddress).deposit{value: totalNativeFee}(); + + unchecked { + //msg.value is always >= to fee.amount + change = msg.value - totalNativeFee; + } + } else { + if (totalNativeFee != 0) { + //subscriber has paid in wrapped native, so transfer the native to this contract + IERC20(i_nativeAddress).safeTransferFrom(subscriber, address(this), totalNativeFee); + } + } + + if (linkRewards.length != 0) { + i_rewardManager.onFeePaid(linkRewards, subscriber); + } + + if (nativeFeeLinkRewards.length != 0) { + //distribute subsidised fees paid in Native + if (totalNativeFeeLinkValue > IERC20(i_linkAddress).balanceOf(address(this))) { + // If not enough LINK on this contract to forward for rewards, tally the deficit to be paid by out-of-band LINK + for (uint256 i; i < nativeFeeLinkRewards.length; ++i) { + unchecked { + //we have previously tallied the fees, any overflows would have already reverted + s_linkDeficit[nativeFeeLinkRewards[i].poolId] += nativeFeeLinkRewards[i].amount; + } + } + + emit InsufficientLink(nativeFeeLinkRewards); + } else { + //distribute the fees + i_rewardManager.onFeePaid(nativeFeeLinkRewards, address(this)); + } + } + + // a refund may be needed if the payee has paid in excess of the fee + _tryReturnChange(subscriber, change); + } + + function _tryReturnChange(address subscriber, uint256 quantity) internal { + if (quantity != 0) { + payable(subscriber).transfer(quantity); + } + } + + /// @inheritdoc IFeeManager + function payLinkDeficit(bytes32 configDigest) external onlyOwner { + uint256 deficit = s_linkDeficit[configDigest]; + + if (deficit == 0) revert ZeroDeficit(); + + delete s_linkDeficit[configDigest]; + + IRewardManager.FeePayment[] memory deficitFeePayment = new IRewardManager.FeePayment[](1); + + deficitFeePayment[0] = IRewardManager.FeePayment(configDigest, uint192(deficit)); + + i_rewardManager.onFeePaid(deficitFeePayment, address(this)); + + emit LinkDeficitCleared(configDigest, deficit); + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/RewardManager.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/RewardManager.sol new file mode 100644 index 00000000000..49fef51c569 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/RewardManager.sol @@ -0,0 +1,321 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.19; + +import {ConfirmedOwner} from "../../shared/access/ConfirmedOwner.sol"; +import {IRewardManager} from "./interfaces/IRewardManager.sol"; +import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC20.sol"; +import {TypeAndVersionInterface} from "../../interfaces/TypeAndVersionInterface.sol"; +import {Common} from "../libraries/Common.sol"; +import {SafeERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol"; + +/** + * @title RewardManager + * @author Michael Fletcher + * @author Austin Born + * @notice This contract will be used to reward any configured recipients within a pool. Recipients will receive a share of their pool relative to their configured weight. + */ +contract RewardManager is IRewardManager, ConfirmedOwner, TypeAndVersionInterface { + using SafeERC20 for IERC20; + + // @dev The mapping of total fees collected for a particular pot: s_totalRewardRecipientFees[poolId] + mapping(bytes32 => uint256) public s_totalRewardRecipientFees; + + // @dev The mapping of fee balances for each pot last time the recipient claimed: s_totalRewardRecipientFeesLastClaimedAmounts[poolId][recipient] + mapping(bytes32 => mapping(address => uint256)) public s_totalRewardRecipientFeesLastClaimedAmounts; + + // @dev The mapping of RewardRecipient weights for a particular poolId: s_rewardRecipientWeights[poolId][rewardRecipient]. + mapping(bytes32 => mapping(address => uint256)) public s_rewardRecipientWeights; + + // @dev Keep track of the reward recipient weights that have been set to prevent duplicates + mapping(bytes32 => bool) public s_rewardRecipientWeightsSet; + + // @dev Store a list of pool ids that have been registered, to make off chain lookups easier + bytes32[] public s_registeredPoolIds; + + // @dev The address for the LINK contract + address public immutable i_linkAddress; + + // The total weight of all RewardRecipients. 1e18 = 100% of the pool fees + uint64 private constant PERCENTAGE_SCALAR = 1e18; + + // The fee manager address + address public s_feeManagerAddress; + + // @notice Thrown whenever the RewardRecipient weights are invalid + error InvalidWeights(); + + // @notice Thrown when any given address is invalid + error InvalidAddress(); + + // @notice Thrown when the pool id is invalid + error InvalidPoolId(); + + // @notice Thrown when the calling contract is not within the authorized contracts + error Unauthorized(); + + // @notice Thrown when getAvailableRewardPoolIds parameters are incorrectly set + error InvalidPoolLength(); + + // Events emitted upon state change + event RewardRecipientsUpdated(bytes32 indexed poolId, Common.AddressAndWeight[] newRewardRecipients); + event RewardsClaimed(bytes32 indexed poolId, address indexed recipient, uint192 quantity); + event FeeManagerUpdated(address newFeeManagerAddress); + event FeePaid(FeePayment[] payments, address payer); + + /** + * @notice Constructor + * @param linkAddress address of the wrapped LINK token + */ + constructor(address linkAddress) ConfirmedOwner(msg.sender) { + //ensure that the address ia not zero + if (linkAddress == address(0)) revert InvalidAddress(); + + i_linkAddress = linkAddress; + } + + // @inheritdoc TypeAndVersionInterface + function typeAndVersion() external pure override returns (string memory) { + return "RewardManager 1.1.0"; + } + + // @inheritdoc IERC165 + function supportsInterface(bytes4 interfaceId) external pure override returns (bool) { + return interfaceId == this.onFeePaid.selector; + } + + modifier onlyOwnerOrFeeManager() { + if (msg.sender != owner() && msg.sender != s_feeManagerAddress) revert Unauthorized(); + _; + } + + modifier onlyOwnerOrRecipientInPool(bytes32 poolId) { + if (msg.sender != owner() && s_rewardRecipientWeights[poolId][msg.sender] == 0) revert Unauthorized(); + _; + } + + modifier onlyFeeManager() { + if (msg.sender != s_feeManagerAddress) revert Unauthorized(); + _; + } + + /// @inheritdoc IRewardManager + function onFeePaid(FeePayment[] calldata payments, address payer) external override onlyFeeManager { + uint256 totalFeeAmount; + for (uint256 i; i < payments.length; ++i) { + unchecked { + //the total amount for any ERC-20 asset cannot exceed 2^256 - 1 + //see https://github.com/OpenZeppelin/openzeppelin-contracts/blob/36bf1e46fa811f0f07d38eb9cfbc69a955f300ce/contracts/token/ERC20/ERC20.sol#L266 + //for example implementation. + s_totalRewardRecipientFees[payments[i].poolId] += payments[i].amount; + + //tally the total payable fees + totalFeeAmount += payments[i].amount; + } + } + + //transfer the fees to this contract + IERC20(i_linkAddress).safeTransferFrom(payer, address(this), totalFeeAmount); + + emit FeePaid(payments, payer); + } + + /// @inheritdoc IRewardManager + function claimRewards(bytes32[] memory poolIds) external override { + _claimRewards(msg.sender, poolIds); + } + + // wrapper impl for claimRewards + function _claimRewards(address recipient, bytes32[] memory poolIds) internal returns (uint256) { + //get the total amount claimable for this recipient + uint256 claimAmount; + + //loop and claim all the rewards in the poolId pot + for (uint256 i; i < poolIds.length; ++i) { + //get the poolId to be claimed + bytes32 poolId = poolIds[i]; + + //get the total fees for the pot + uint256 totalFeesInPot = s_totalRewardRecipientFees[poolId]; + + unchecked { + //avoid unnecessary storage reads if there's no fees in the pot + if (totalFeesInPot == 0) continue; + + //get the claimable amount for this recipient, this calculation will never exceed the amount in the pot + uint256 claimableAmount = totalFeesInPot - s_totalRewardRecipientFeesLastClaimedAmounts[poolId][recipient]; + + //calculate the recipients share of the fees, which is their weighted share of the difference between the last amount they claimed and the current amount in the pot. This can never be more than the total amount in existence + uint256 recipientShare = (claimableAmount * s_rewardRecipientWeights[poolId][recipient]) / PERCENTAGE_SCALAR; + + //if there's no fees to claim, continue as there's nothing to update + if (recipientShare == 0) continue; + + //keep track of the total amount claimable, this can never be more than the total amount in existence + claimAmount += recipientShare; + + //set the current total amount of fees in the pot as it's used to calculate future claims + s_totalRewardRecipientFeesLastClaimedAmounts[poolId][recipient] = totalFeesInPot; + + //emit event if the recipient has rewards to claim + emit RewardsClaimed(poolIds[i], recipient, uint192(recipientShare)); + } + } + + //check if there's any rewards to claim in the given poolId + if (claimAmount != 0) { + //transfer the reward to the recipient + IERC20(i_linkAddress).safeTransfer(recipient, claimAmount); + } + + return claimAmount; + } + + /// @inheritdoc IRewardManager + function setRewardRecipients( + bytes32 poolId, + Common.AddressAndWeight[] calldata rewardRecipientAndWeights + ) external override onlyOwnerOrFeeManager { + //revert if there are no recipients to set + if (rewardRecipientAndWeights.length == 0) revert InvalidAddress(); + + //check that the weights have not been previously set + if (s_rewardRecipientWeightsSet[poolId]) revert InvalidPoolId(); + + //keep track of the registered poolIds to make off chain lookups easier + s_registeredPoolIds.push(poolId); + + //keep track of which pools have had their reward recipients set + s_rewardRecipientWeightsSet[poolId] = true; + + //set the reward recipients, this will only be called once and contain the full set of RewardRecipients with a total weight of 100% + _setRewardRecipientWeights(poolId, rewardRecipientAndWeights, PERCENTAGE_SCALAR); + + emit RewardRecipientsUpdated(poolId, rewardRecipientAndWeights); + } + + function _setRewardRecipientWeights( + bytes32 poolId, + Common.AddressAndWeight[] calldata rewardRecipientAndWeights, + uint256 expectedWeight + ) internal { + //we can't update the weights if it contains duplicates + if (Common._hasDuplicateAddresses(rewardRecipientAndWeights)) revert InvalidAddress(); + + //loop all the reward recipients and validate the weight and address + uint256 totalWeight; + for (uint256 i; i < rewardRecipientAndWeights.length; ++i) { + //get the weight + uint256 recipientWeight = rewardRecipientAndWeights[i].weight; + //get the address + address recipientAddress = rewardRecipientAndWeights[i].addr; + + //ensure the reward recipient address is not zero + if (recipientAddress == address(0)) revert InvalidAddress(); + + //save/overwrite the weight for the reward recipient + s_rewardRecipientWeights[poolId][recipientAddress] = recipientWeight; + + unchecked { + //keep track of the cumulative weight, this cannot overflow as the total weight is restricted at 1e18 + totalWeight += recipientWeight; + } + } + + //if total weight is not met, the fees will either be under or over distributed + if (totalWeight != expectedWeight) revert InvalidWeights(); + } + + /// @inheritdoc IRewardManager + function updateRewardRecipients( + bytes32 poolId, + Common.AddressAndWeight[] calldata newRewardRecipients + ) external override onlyOwner { + //create an array of poolIds to pass to _claimRewards if required + bytes32[] memory poolIds = new bytes32[](1); + poolIds[0] = poolId; + + //loop all the reward recipients and claim their rewards before updating their weights + uint256 existingTotalWeight; + for (uint256 i; i < newRewardRecipients.length; ++i) { + //get the address + address recipientAddress = newRewardRecipients[i].addr; + //get the existing weight + uint256 existingWeight = s_rewardRecipientWeights[poolId][recipientAddress]; + + //if a recipient is updated, the rewards must be claimed first as they can't claim previous fees at the new weight + _claimRewards(newRewardRecipients[i].addr, poolIds); + + unchecked { + //keep tally of the weights so that the expected collective weight is known + existingTotalWeight += existingWeight; + } + } + + //update the reward recipients, if the new collective weight isn't equal to the previous collective weight, the fees will either be under or over distributed + _setRewardRecipientWeights(poolId, newRewardRecipients, existingTotalWeight); + + //emit event + emit RewardRecipientsUpdated(poolId, newRewardRecipients); + } + + /// @inheritdoc IRewardManager + function payRecipients(bytes32 poolId, address[] calldata recipients) external onlyOwnerOrRecipientInPool(poolId) { + //convert poolIds to an array to match the interface of _claimRewards + bytes32[] memory poolIdsArray = new bytes32[](1); + poolIdsArray[0] = poolId; + + //loop each recipient and claim the rewards for each of the pools and assets + for (uint256 i; i < recipients.length; ++i) { + _claimRewards(recipients[i], poolIdsArray); + } + } + + /// @inheritdoc IRewardManager + function setFeeManager(address newFeeManagerAddress) external onlyOwner { + if (newFeeManagerAddress == address(0)) revert InvalidAddress(); + + s_feeManagerAddress = newFeeManagerAddress; + + emit FeeManagerUpdated(newFeeManagerAddress); + } + + /// @inheritdoc IRewardManager + function getAvailableRewardPoolIds( + address recipient, + uint256 startIndex, + uint256 endIndex + ) external view returns (bytes32[] memory) { + //get the length of the pool ids which we will loop through and potentially return + uint256 registeredPoolIdsLength = s_registeredPoolIds.length; + + uint256 lastIndex = endIndex > registeredPoolIdsLength ? registeredPoolIdsLength : endIndex; + + if (startIndex > lastIndex) revert InvalidPoolLength(); + + //create a new array with the maximum amount of potential pool ids + bytes32[] memory claimablePoolIds = new bytes32[](lastIndex - startIndex); + //we want the pools which a recipient has funds for to be sequential, so we need to keep track of the index + uint256 poolIdArrayIndex; + + //loop all the pool ids, and check if the recipient has a registered weight and a claimable amount + for (uint256 i = startIndex; i < lastIndex; ++i) { + //get the poolId + bytes32 poolId = s_registeredPoolIds[i]; + + //if the recipient has a weight, they are a recipient of this poolId + if (s_rewardRecipientWeights[poolId][recipient] != 0) { + //get the total in this pool + uint256 totalPoolAmount = s_totalRewardRecipientFees[poolId]; + //if the recipient has any LINK, then add the poolId to the array + unchecked { + //s_totalRewardRecipientFeesLastClaimedAmounts can never exceed total pool amount, and the number of pools can't exceed the max array length + if (totalPoolAmount - s_totalRewardRecipientFeesLastClaimedAmounts[poolId][recipient] != 0) { + claimablePoolIds[poolIdArrayIndex++] = poolId; + } + } + } + } + + return claimablePoolIds; + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/Verifier.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/Verifier.sol new file mode 100644 index 00000000000..fe5742108a5 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/Verifier.sol @@ -0,0 +1,559 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.19; + +import {ConfirmedOwner} from "../../shared/access/ConfirmedOwner.sol"; +import {IVerifier} from "./interfaces/IVerifier.sol"; +import {IVerifierProxy} from "./interfaces/IVerifierProxy.sol"; +import {TypeAndVersionInterface} from "../../interfaces/TypeAndVersionInterface.sol"; +import {IERC165} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; +import {Common} from "../libraries/Common.sol"; + +// OCR2 standard +uint256 constant MAX_NUM_ORACLES = 31; + +/* + * The verifier contract is used to verify offchain reports signed + * by DONs. A report consists of a price, block number and feed Id. It + * represents the observed price of an asset at a specified block number for + * a feed. The verifier contract is used to verify that such reports have + * been signed by the correct signers. + **/ +contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface { + // The first byte of the mask can be 0, because we only ever have 31 oracles + uint256 internal constant ORACLE_MASK = 0x0001010101010101010101010101010101010101010101010101010101010101; + + enum Role { + // Default role for an oracle address. This means that the oracle address + // is not a signer + Unset, + // Role given to an oracle address that is allowed to sign feed data + Signer + } + + struct Signer { + // Index of oracle in a configuration + uint8 index; + // The oracle's role + Role role; + } + + struct Config { + // Fault tolerance + uint8 f; + // Marks whether or not a configuration is active + bool isActive; + // Map of signer addresses to oracles + mapping(address => Signer) oracles; + } + + struct VerifierState { + // The number of times a new configuration + /// has been set + uint32 configCount; + // The block number of the block the last time + /// the configuration was updated. + uint32 latestConfigBlockNumber; + // The latest epoch a report was verified for + uint32 latestEpoch; + // Whether or not the verifier for this feed has been deactivated + bool isDeactivated; + /// The latest config digest set + bytes32 latestConfigDigest; + /// The historical record of all previously set configs by feedId + mapping(bytes32 => Config) s_verificationDataConfigs; + } + + /// @notice This event is emitted when a new report is verified. + /// It is used to keep a historical record of verified reports. + event ReportVerified(bytes32 indexed feedId, address requester); + + /// @notice This event is emitted whenever a new configuration is set for a feed. It triggers a new run of the offchain reporting protocol. + event ConfigSet( + bytes32 indexed feedId, + uint32 previousConfigBlockNumber, + bytes32 configDigest, + uint64 configCount, + address[] signers, + bytes32[] offchainTransmitters, + uint8 f, + bytes onchainConfig, + uint64 offchainConfigVersion, + bytes offchainConfig + ); + + /// @notice This event is emitted whenever a configuration is deactivated + event ConfigDeactivated(bytes32 indexed feedId, bytes32 configDigest); + + /// @notice This event is emitted whenever a configuration is activated + event ConfigActivated(bytes32 indexed feedId, bytes32 configDigest); + + /// @notice This event is emitted whenever a feed is activated + event FeedActivated(bytes32 indexed feedId); + + /// @notice This event is emitted whenever a feed is deactivated + event FeedDeactivated(bytes32 indexed feedId); + + /// @notice This error is thrown whenever an address tries + /// to exeecute a transaction that it is not authorized to do so + error AccessForbidden(); + + /// @notice This error is thrown whenever a zero address is passed + error ZeroAddress(); + + /// @notice This error is thrown whenever the feed ID passed in + /// a signed report is empty + error FeedIdEmpty(); + + /// @notice This error is thrown whenever the config digest + /// is empty + error DigestEmpty(); + + /// @notice This error is thrown whenever the config digest + /// passed in has not been set in this verifier + /// @param feedId The feed ID in the signed report + /// @param configDigest The config digest that has not been set + error DigestNotSet(bytes32 feedId, bytes32 configDigest); + + /// @notice This error is thrown whenever the config digest + /// has been deactivated + /// @param feedId The feed ID in the signed report + /// @param configDigest The config digest that is inactive + error DigestInactive(bytes32 feedId, bytes32 configDigest); + + /// @notice This error is thrown whenever trying to set a config + /// with a fault tolerance of 0 + error FaultToleranceMustBePositive(); + + /// @notice This error is thrown whenever a report is signed + /// with more than the max number of signers + /// @param numSigners The number of signers who have signed the report + /// @param maxSigners The maximum number of signers that can sign a report + error ExcessSigners(uint256 numSigners, uint256 maxSigners); + + /// @notice This error is thrown whenever a report is signed + /// with less than the minimum number of signers + /// @param numSigners The number of signers who have signed the report + /// @param minSigners The minimum number of signers that need to sign a report + error InsufficientSigners(uint256 numSigners, uint256 minSigners); + + /// @notice This error is thrown whenever a report is signed + /// with an incorrect number of signers + /// @param numSigners The number of signers who have signed the report + /// @param expectedNumSigners The expected number of signers that need to sign + /// a report + error IncorrectSignatureCount(uint256 numSigners, uint256 expectedNumSigners); + + /// @notice This error is thrown whenever the R and S signer components + /// have different lengths + /// @param rsLength The number of r signature components + /// @param ssLength The number of s signature components + error MismatchedSignatures(uint256 rsLength, uint256 ssLength); + + /// @notice This error is thrown whenever setting a config with duplicate signatures + error NonUniqueSignatures(); + + /// @notice This error is thrown whenever a report fails to verify due to bad or duplicate signatures + error BadVerification(); + + /// @notice This error is thrown whenever the admin tries to deactivate + /// the latest config digest + /// @param feedId The feed ID in the signed report + /// @param configDigest The latest config digest + error CannotDeactivateLatestConfig(bytes32 feedId, bytes32 configDigest); + + /// @notice This error is thrown whenever the feed ID passed in is deactivated + /// @param feedId The feed ID + error InactiveFeed(bytes32 feedId); + + /// @notice This error is thrown whenever the feed ID passed in is not found + /// @param feedId The feed ID + error InvalidFeed(bytes32 feedId); + + /// @notice The address of the verifier proxy + address private immutable i_verifierProxyAddr; + + /// @notice Verifier states keyed on Feed ID + mapping(bytes32 => VerifierState) internal s_feedVerifierStates; + + /// @param verifierProxyAddr The address of the VerifierProxy contract + constructor(address verifierProxyAddr) ConfirmedOwner(msg.sender) { + if (verifierProxyAddr == address(0)) revert ZeroAddress(); + i_verifierProxyAddr = verifierProxyAddr; + } + + modifier checkConfigValid(uint256 numSigners, uint256 f) { + if (f == 0) revert FaultToleranceMustBePositive(); + if (numSigners > MAX_NUM_ORACLES) revert ExcessSigners(numSigners, MAX_NUM_ORACLES); + if (numSigners <= 3 * f) revert InsufficientSigners(numSigners, 3 * f + 1); + _; + } + + /// @inheritdoc IERC165 + function supportsInterface(bytes4 interfaceId) external pure override returns (bool isVerifier) { + return interfaceId == this.verify.selector; + } + + /// @inheritdoc TypeAndVersionInterface + function typeAndVersion() external pure override returns (string memory) { + return "Verifier 1.2.0"; + } + + /// @inheritdoc IVerifier + function verify( + bytes calldata signedReport, + address sender + ) external override returns (bytes memory verifierResponse) { + if (msg.sender != i_verifierProxyAddr) revert AccessForbidden(); + ( + bytes32[3] memory reportContext, + bytes memory reportData, + bytes32[] memory rs, + bytes32[] memory ss, + bytes32 rawVs + ) = abi.decode(signedReport, (bytes32[3], bytes, bytes32[], bytes32[], bytes32)); + + // The feed ID is the first 32 bytes of the report data. + bytes32 feedId = bytes32(reportData); + + VerifierState storage feedVerifierState = s_feedVerifierStates[feedId]; + + // If the feed has been deactivated, do not verify the report + if (feedVerifierState.isDeactivated) { + revert InactiveFeed(feedId); + } + + // reportContext consists of: + // reportContext[0]: ConfigDigest + // reportContext[1]: 27 byte padding, 4-byte epoch and 1-byte round + // reportContext[2]: ExtraHash + bytes32 configDigest = reportContext[0]; + Config storage s_config = feedVerifierState.s_verificationDataConfigs[configDigest]; + + _validateReport(feedId, configDigest, rs, ss, s_config); + _updateEpoch(reportContext, feedVerifierState); + + bytes32 hashedReport = keccak256(reportData); + + _verifySignatures(hashedReport, reportContext, rs, ss, rawVs, s_config); + emit ReportVerified(feedId, sender); + + return reportData; + } + + /// @notice Validates parameters of the report + /// @param feedId Feed ID from the report + /// @param configDigest Config digest from the report + /// @param rs R components from the report + /// @param ss S components from the report + /// @param config Config for the given feed ID keyed on the config digest + function _validateReport( + bytes32 feedId, + bytes32 configDigest, + bytes32[] memory rs, + bytes32[] memory ss, + Config storage config + ) private view { + uint8 expectedNumSignatures = config.f + 1; + + if (!config.isActive) revert DigestInactive(feedId, configDigest); + if (rs.length != expectedNumSignatures) revert IncorrectSignatureCount(rs.length, expectedNumSignatures); + if (rs.length != ss.length) revert MismatchedSignatures(rs.length, ss.length); + } + + /** + * @notice Conditionally update the epoch for a feed + * @param reportContext Report context containing the epoch and round + * @param feedVerifierState Feed verifier state to conditionally update + */ + function _updateEpoch(bytes32[3] memory reportContext, VerifierState storage feedVerifierState) private { + uint40 epochAndRound = uint40(uint256(reportContext[1])); + uint32 epoch = uint32(epochAndRound >> 8); + if (epoch > feedVerifierState.latestEpoch) { + feedVerifierState.latestEpoch = epoch; + } + } + + /// @notice Verifies that a report has been signed by the correct + /// signers and that enough signers have signed the reports. + /// @param hashedReport The keccak256 hash of the raw report's bytes + /// @param reportContext The context the report was signed in + /// @param rs ith element is the R components of the ith signature on report. Must have at most MAX_NUM_ORACLES entries + /// @param ss ith element is the S components of the ith signature on report. Must have at most MAX_NUM_ORACLES entries + /// @param rawVs ith element is the the V component of the ith signature + /// @param s_config The config digest the report was signed for + function _verifySignatures( + bytes32 hashedReport, + bytes32[3] memory reportContext, + bytes32[] memory rs, + bytes32[] memory ss, + bytes32 rawVs, + Config storage s_config + ) private view { + bytes32 h = keccak256(abi.encodePacked(hashedReport, reportContext)); + // i-th byte counts number of sigs made by i-th signer + uint256 signedCount; + + Signer memory o; + address signerAddress; + uint256 numSigners = rs.length; + for (uint256 i; i < numSigners; ++i) { + signerAddress = ecrecover(h, uint8(rawVs[i]) + 27, rs[i], ss[i]); + o = s_config.oracles[signerAddress]; + if (o.role != Role.Signer) revert BadVerification(); + unchecked { + signedCount += 1 << (8 * o.index); + } + } + + if (signedCount & ORACLE_MASK != signedCount) revert BadVerification(); + } + + /// @inheritdoc IVerifier + function setConfig( + bytes32 feedId, + address[] memory signers, + bytes32[] memory offchainTransmitters, + uint8 f, + bytes memory onchainConfig, + uint64 offchainConfigVersion, + bytes memory offchainConfig, + Common.AddressAndWeight[] memory recipientAddressesAndWeights + ) external override checkConfigValid(signers.length, f) onlyOwner { + _setConfig( + feedId, + block.chainid, + address(this), + 0, // 0 defaults to feedConfig.configCount + 1 + signers, + offchainTransmitters, + f, + onchainConfig, + offchainConfigVersion, + offchainConfig, + recipientAddressesAndWeights + ); + } + + /// @inheritdoc IVerifier + function setConfigFromSource( + bytes32 feedId, + uint256 sourceChainId, + address sourceAddress, + uint32 newConfigCount, + address[] memory signers, + bytes32[] memory offchainTransmitters, + uint8 f, + bytes memory onchainConfig, + uint64 offchainConfigVersion, + bytes memory offchainConfig, + Common.AddressAndWeight[] memory recipientAddressesAndWeights + ) external override checkConfigValid(signers.length, f) onlyOwner { + _setConfig( + feedId, + sourceChainId, + sourceAddress, + newConfigCount, + signers, + offchainTransmitters, + f, + onchainConfig, + offchainConfigVersion, + offchainConfig, + recipientAddressesAndWeights + ); + } + + /// @notice Sets config based on the given arguments + /// @param feedId Feed ID to set config for + /// @param sourceChainId Chain ID of source config + /// @param sourceAddress Address of source config Verifier + /// @param newConfigCount Optional param to force the new config count + /// @param signers addresses with which oracles sign the reports + /// @param offchainTransmitters CSA key for the ith Oracle + /// @param f number of faulty oracles the system can tolerate + /// @param onchainConfig serialized configuration used by the contract (and possibly oracles) + /// @param offchainConfigVersion version number for offchainEncoding schema + /// @param offchainConfig serialized configuration used by the oracles exclusively and only passed through the contract + /// @param recipientAddressesAndWeights the addresses and weights of all the recipients to receive rewards + function _setConfig( + bytes32 feedId, + uint256 sourceChainId, + address sourceAddress, + uint32 newConfigCount, + address[] memory signers, + bytes32[] memory offchainTransmitters, + uint8 f, + bytes memory onchainConfig, + uint64 offchainConfigVersion, + bytes memory offchainConfig, + Common.AddressAndWeight[] memory recipientAddressesAndWeights + ) internal { + VerifierState storage feedVerifierState = s_feedVerifierStates[feedId]; + + // Increment the number of times a config has been set first + if (newConfigCount > 0) feedVerifierState.configCount = newConfigCount; + else feedVerifierState.configCount++; + + bytes32 configDigest = _configDigestFromConfigData( + feedId, + sourceChainId, + sourceAddress, + feedVerifierState.configCount, + signers, + offchainTransmitters, + f, + onchainConfig, + offchainConfigVersion, + offchainConfig + ); + + feedVerifierState.s_verificationDataConfigs[configDigest].f = f; + feedVerifierState.s_verificationDataConfigs[configDigest].isActive = true; + for (uint8 i; i < signers.length; ++i) { + address signerAddr = signers[i]; + if (signerAddr == address(0)) revert ZeroAddress(); + + // All signer roles are unset by default for a new config digest. + // Here the contract checks to see if a signer's address has already + // been set to ensure that the group of signer addresses that will + // sign reports with the config digest are unique. + bool isSignerAlreadySet = feedVerifierState.s_verificationDataConfigs[configDigest].oracles[signerAddr].role != + Role.Unset; + if (isSignerAlreadySet) revert NonUniqueSignatures(); + feedVerifierState.s_verificationDataConfigs[configDigest].oracles[signerAddr] = Signer({ + role: Role.Signer, + index: i + }); + } + + IVerifierProxy(i_verifierProxyAddr).setVerifier( + feedVerifierState.latestConfigDigest, + configDigest, + recipientAddressesAndWeights + ); + + emit ConfigSet( + feedId, + feedVerifierState.latestConfigBlockNumber, + configDigest, + feedVerifierState.configCount, + signers, + offchainTransmitters, + f, + onchainConfig, + offchainConfigVersion, + offchainConfig + ); + + feedVerifierState.latestEpoch = 0; + feedVerifierState.latestConfigBlockNumber = uint32(block.number); + feedVerifierState.latestConfigDigest = configDigest; + } + + /// @notice Generates the config digest from config data + /// @param feedId Feed ID to set config for + /// @param sourceChainId Chain ID of source config + /// @param sourceAddress Address of source config Verifier + /// @param configCount ordinal number of this config setting among all config settings over the life of this contract + /// @param signers ith element is address ith oracle uses to sign a report + /// @param offchainTransmitters ith element is address ith oracle used to transmit reports (in this case used for flexible additional field, such as CSA pub keys) + /// @param f maximum number of faulty/dishonest oracles the protocol can tolerate while still working correctly + /// @param onchainConfig serialized configuration used by the contract (and possibly oracles) + /// @param offchainConfigVersion version of the serialization format used for "offchainConfig" parameter + /// @param offchainConfig serialized configuration used by the oracles exclusively and only passed through the contract + /// @dev This function is a modified version of the method from OCR2Abstract + function _configDigestFromConfigData( + bytes32 feedId, + uint256 sourceChainId, + address sourceAddress, + uint64 configCount, + address[] memory signers, + bytes32[] memory offchainTransmitters, + uint8 f, + bytes memory onchainConfig, + uint64 offchainConfigVersion, + bytes memory offchainConfig + ) internal pure returns (bytes32) { + uint256 h = uint256( + keccak256( + abi.encode( + feedId, + sourceChainId, + sourceAddress, + configCount, + signers, + offchainTransmitters, + f, + onchainConfig, + offchainConfigVersion, + offchainConfig + ) + ) + ); + uint256 prefixMask = type(uint256).max << (256 - 16); // 0xFFFF00..00 + // 0x0006 corresponds to ConfigDigestPrefixMercuryV02 in libocr + uint256 prefix = 0x0006 << (256 - 16); // 0x000600..00 + return bytes32((prefix & prefixMask) | (h & ~prefixMask)); + } + + /// @inheritdoc IVerifier + function activateConfig(bytes32 feedId, bytes32 configDigest) external onlyOwner { + VerifierState storage feedVerifierState = s_feedVerifierStates[feedId]; + + if (configDigest == bytes32("")) revert DigestEmpty(); + if (feedVerifierState.s_verificationDataConfigs[configDigest].f == 0) revert DigestNotSet(feedId, configDigest); + feedVerifierState.s_verificationDataConfigs[configDigest].isActive = true; + emit ConfigActivated(feedId, configDigest); + } + + /// @inheritdoc IVerifier + function deactivateConfig(bytes32 feedId, bytes32 configDigest) external onlyOwner { + VerifierState storage feedVerifierState = s_feedVerifierStates[feedId]; + + if (configDigest == bytes32("")) revert DigestEmpty(); + if (feedVerifierState.s_verificationDataConfigs[configDigest].f == 0) revert DigestNotSet(feedId, configDigest); + if (configDigest == feedVerifierState.latestConfigDigest) { + revert CannotDeactivateLatestConfig(feedId, configDigest); + } + feedVerifierState.s_verificationDataConfigs[configDigest].isActive = false; + emit ConfigDeactivated(feedId, configDigest); + } + + /// @inheritdoc IVerifier + function activateFeed(bytes32 feedId) external onlyOwner { + VerifierState storage feedVerifierState = s_feedVerifierStates[feedId]; + + if (feedVerifierState.configCount == 0) revert InvalidFeed(feedId); + feedVerifierState.isDeactivated = false; + emit FeedActivated(feedId); + } + + /// @inheritdoc IVerifier + function deactivateFeed(bytes32 feedId) external onlyOwner { + VerifierState storage feedVerifierState = s_feedVerifierStates[feedId]; + + if (feedVerifierState.configCount == 0) revert InvalidFeed(feedId); + feedVerifierState.isDeactivated = true; + emit FeedDeactivated(feedId); + } + + /// @inheritdoc IVerifier + function latestConfigDigestAndEpoch( + bytes32 feedId + ) external view override returns (bool scanLogs, bytes32 configDigest, uint32 epoch) { + VerifierState storage feedVerifierState = s_feedVerifierStates[feedId]; + return (false, feedVerifierState.latestConfigDigest, feedVerifierState.latestEpoch); + } + + /// @inheritdoc IVerifier + function latestConfigDetails( + bytes32 feedId + ) external view override returns (uint32 configCount, uint32 blockNumber, bytes32 configDigest) { + VerifierState storage feedVerifierState = s_feedVerifierStates[feedId]; + return ( + feedVerifierState.configCount, + feedVerifierState.latestConfigBlockNumber, + feedVerifierState.latestConfigDigest + ); + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/VerifierProxy.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/VerifierProxy.sol new file mode 100644 index 00000000000..c06312dd7be --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/VerifierProxy.sol @@ -0,0 +1,229 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.19; + +import {ConfirmedOwner} from "../../shared/access/ConfirmedOwner.sol"; +import {IVerifierProxy} from "./interfaces/IVerifierProxy.sol"; +import {IVerifier} from "./interfaces/IVerifier.sol"; +import {TypeAndVersionInterface} from "../../interfaces/TypeAndVersionInterface.sol"; +import {AccessControllerInterface} from "../../shared/interfaces/AccessControllerInterface.sol"; +import {IERC165} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; +import {IVerifierFeeManager} from "./interfaces/IVerifierFeeManager.sol"; +import {Common} from "../libraries/Common.sol"; + +/** + * The verifier proxy contract is the gateway for all report verification requests + * on a chain. It is responsible for taking in a verification request and routing + * it to the correct verifier contract. + */ +contract VerifierProxy is IVerifierProxy, ConfirmedOwner, TypeAndVersionInterface { + /// @notice This event is emitted whenever a new verifier contract is set + /// @param oldConfigDigest The config digest that was previously the latest config + /// digest of the verifier contract at the verifier address. + /// @param oldConfigDigest The latest config digest of the verifier contract + /// at the verifier address. + /// @param verifierAddress The address of the verifier contract that verifies reports for + /// a given digest + event VerifierSet(bytes32 oldConfigDigest, bytes32 newConfigDigest, address verifierAddress); + + /// @notice This event is emitted whenever a new verifier contract is initialized + /// @param verifierAddress The address of the verifier contract that verifies reports + event VerifierInitialized(address verifierAddress); + + /// @notice This event is emitted whenever a verifier is unset + /// @param configDigest The config digest that was unset + /// @param verifierAddress The Verifier contract address unset + event VerifierUnset(bytes32 configDigest, address verifierAddress); + + /// @notice This event is emitted when a new access controller is set + /// @param oldAccessController The old access controller address + /// @param newAccessController The new access controller address + event AccessControllerSet(address oldAccessController, address newAccessController); + + /// @notice This event is emitted when a new fee manager is set + /// @param oldFeeManager The old fee manager address + /// @param newFeeManager The new fee manager address + event FeeManagerSet(address oldFeeManager, address newFeeManager); + + /// @notice This error is thrown whenever an address tries + /// to exeecute a transaction that it is not authorized to do so + error AccessForbidden(); + + /// @notice This error is thrown whenever a zero address is passed + error ZeroAddress(); + + /// @notice This error is thrown when trying to set a verifier address + /// for a digest that has already been initialized + /// @param configDigest The digest for the verifier that has + /// already been set + /// @param verifier The address of the verifier the digest was set for + error ConfigDigestAlreadySet(bytes32 configDigest, address verifier); + + /// @notice This error is thrown when trying to set a verifier address that has already been initialized + error VerifierAlreadyInitialized(address verifier); + + /// @notice This error is thrown when the verifier at an address does + /// not conform to the verifier interface + error VerifierInvalid(); + + /// @notice This error is thrown when the fee manager at an address does + /// not conform to the fee manager interface + error FeeManagerInvalid(); + + /// @notice This error is thrown whenever a verifier is not found + /// @param configDigest The digest for which a verifier is not found + error VerifierNotFound(bytes32 configDigest); + + /// @notice This error is thrown whenever billing fails. + error BadVerification(); + + /// @notice Mapping of authorized verifiers + mapping(address => bool) private s_initializedVerifiers; + + /// @notice Mapping between config digests and verifiers + mapping(bytes32 => address) private s_verifiersByConfig; + + /// @notice The contract to control addresses that are allowed to verify reports + AccessControllerInterface public s_accessController; + + /// @notice The contract to control fees for report verification + IVerifierFeeManager public s_feeManager; + + constructor(AccessControllerInterface accessController) ConfirmedOwner(msg.sender) { + s_accessController = accessController; + } + + modifier checkAccess() { + AccessControllerInterface ac = s_accessController; + if (address(ac) != address(0) && !ac.hasAccess(msg.sender, msg.data)) revert AccessForbidden(); + _; + } + + modifier onlyInitializedVerifier() { + if (!s_initializedVerifiers[msg.sender]) revert AccessForbidden(); + _; + } + + modifier onlyValidVerifier(address verifierAddress) { + if (verifierAddress == address(0)) revert ZeroAddress(); + if (!IERC165(verifierAddress).supportsInterface(IVerifier.verify.selector)) revert VerifierInvalid(); + _; + } + + modifier onlyUnsetConfigDigest(bytes32 configDigest) { + address configDigestVerifier = s_verifiersByConfig[configDigest]; + if (configDigestVerifier != address(0)) revert ConfigDigestAlreadySet(configDigest, configDigestVerifier); + _; + } + + /// @inheritdoc TypeAndVersionInterface + function typeAndVersion() external pure override returns (string memory) { + return "VerifierProxy 2.0.0"; + } + + /// @inheritdoc IVerifierProxy + function verify( + bytes calldata payload, + bytes calldata parameterPayload + ) external payable checkAccess returns (bytes memory) { + IVerifierFeeManager feeManager = s_feeManager; + + // Bill the verifier + if (address(feeManager) != address(0)) { + feeManager.processFee{value: msg.value}(payload, parameterPayload, msg.sender); + } + + return _verify(payload); + } + + /// @inheritdoc IVerifierProxy + function verifyBulk( + bytes[] calldata payloads, + bytes calldata parameterPayload + ) external payable checkAccess returns (bytes[] memory verifiedReports) { + IVerifierFeeManager feeManager = s_feeManager; + + // Bill the verifier + if (address(feeManager) != address(0)) { + feeManager.processFeeBulk{value: msg.value}(payloads, parameterPayload, msg.sender); + } + + //verify the reports + verifiedReports = new bytes[](payloads.length); + for (uint256 i; i < payloads.length; ++i) { + verifiedReports[i] = _verify(payloads[i]); + } + + return verifiedReports; + } + + function _verify(bytes calldata payload) internal returns (bytes memory verifiedReport) { + // First 32 bytes of the signed report is the config digest + bytes32 configDigest = bytes32(payload); + address verifierAddress = s_verifiersByConfig[configDigest]; + if (verifierAddress == address(0)) revert VerifierNotFound(configDigest); + + return IVerifier(verifierAddress).verify(payload, msg.sender); + } + + /// @inheritdoc IVerifierProxy + function initializeVerifier(address verifierAddress) external override onlyOwner onlyValidVerifier(verifierAddress) { + if (s_initializedVerifiers[verifierAddress]) revert VerifierAlreadyInitialized(verifierAddress); + + s_initializedVerifiers[verifierAddress] = true; + emit VerifierInitialized(verifierAddress); + } + + /// @inheritdoc IVerifierProxy + function setVerifier( + bytes32 currentConfigDigest, + bytes32 newConfigDigest, + Common.AddressAndWeight[] calldata addressesAndWeights + ) external override onlyUnsetConfigDigest(newConfigDigest) onlyInitializedVerifier { + s_verifiersByConfig[newConfigDigest] = msg.sender; + + // Empty recipients array will be ignored and must be set off chain + if (addressesAndWeights.length > 0) { + if (address(s_feeManager) == address(0)) { + revert ZeroAddress(); + } + + s_feeManager.setFeeRecipients(newConfigDigest, addressesAndWeights); + } + + emit VerifierSet(currentConfigDigest, newConfigDigest, msg.sender); + } + + /// @inheritdoc IVerifierProxy + function unsetVerifier(bytes32 configDigest) external override onlyOwner { + address verifierAddress = s_verifiersByConfig[configDigest]; + if (verifierAddress == address(0)) revert VerifierNotFound(configDigest); + delete s_verifiersByConfig[configDigest]; + emit VerifierUnset(configDigest, verifierAddress); + } + + /// @inheritdoc IVerifierProxy + function getVerifier(bytes32 configDigest) external view override returns (address) { + return s_verifiersByConfig[configDigest]; + } + + /// @inheritdoc IVerifierProxy + function setAccessController(AccessControllerInterface accessController) external onlyOwner { + address oldAccessController = address(s_accessController); + s_accessController = accessController; + emit AccessControllerSet(oldAccessController, address(accessController)); + } + + /// @inheritdoc IVerifierProxy + function setFeeManager(IVerifierFeeManager feeManager) external onlyOwner { + if (address(feeManager) == address(0)) revert ZeroAddress(); + + if ( + !IERC165(feeManager).supportsInterface(IVerifierFeeManager.processFee.selector) || + !IERC165(feeManager).supportsInterface(IVerifierFeeManager.processFeeBulk.selector) + ) revert FeeManagerInvalid(); + + address oldFeeManager = address(s_feeManager); + s_feeManager = IVerifierFeeManager(feeManager); + emit FeeManagerSet(oldFeeManager, address(feeManager)); + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/interfaces/IFeeManager.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/interfaces/IFeeManager.sol new file mode 100644 index 00000000000..818a3a09a4c --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/interfaces/IFeeManager.sol @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.19; + +import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; +import {Common} from "../../libraries/Common.sol"; +import {IVerifierFeeManager} from "./IVerifierFeeManager.sol"; + +interface IFeeManager is IERC165, IVerifierFeeManager { + /** + * @notice Calculate the applied fee and the reward from a report. If the sender is a subscriber, they will receive a discount. + * @param subscriber address trying to verify + * @param report report to calculate the fee for + * @param quoteAddress address of the quote payment token + * @return (fee, reward, totalDiscount) fee and the reward data with the discount applied + */ + function getFeeAndReward( + address subscriber, + bytes memory report, + address quoteAddress + ) external returns (Common.Asset memory, Common.Asset memory, uint256); + + /** + * @notice Sets the native surcharge + * @param surcharge surcharge to be paid if paying in native + */ + function setNativeSurcharge(uint64 surcharge) external; + + /** + * @notice Adds a subscriber to the fee manager + * @param subscriber address of the subscriber + * @param feedId feed id to apply the discount to + * @param token token to apply the discount to + * @param discount discount to be applied to the fee + */ + function updateSubscriberDiscount(address subscriber, bytes32 feedId, address token, uint64 discount) external; + + /** + * @notice Withdraws any native or LINK rewards to the owner address + * @param assetAddress address of the asset to withdraw + * @param recipientAddress address to withdraw to + * @param quantity quantity to withdraw + */ + function withdraw(address assetAddress, address recipientAddress, uint192 quantity) external; + + /** + * @notice Returns the link balance of the fee manager + * @return link balance of the fee manager + */ + function linkAvailableForPayment() external returns (uint256); + + /** + * @notice Admin function to pay the LINK deficit for a given config digest + * @param configDigest the config digest to pay the deficit for + */ + function payLinkDeficit(bytes32 configDigest) external; + + /** + * @notice The structure to hold a fee and reward to verify a report + * @param digest the digest linked to the fee and reward + * @param fee the fee paid to verify the report + * @param reward the reward paid upon verification + & @param appliedDiscount the discount applied to the reward + */ + struct FeeAndReward { + bytes32 configDigest; + Common.Asset fee; + Common.Asset reward; + uint256 appliedDiscount; + } + + /** + * @notice The structure to hold quote metadata + * @param quoteAddress the address of the quote + */ + struct Quote { + address quoteAddress; + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/interfaces/IRewardManager.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/interfaces/IRewardManager.sol new file mode 100644 index 00000000000..f08ce34db29 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/interfaces/IRewardManager.sol @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.19; + +import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; +import {Common} from "../../libraries/Common.sol"; + +interface IRewardManager is IERC165 { + /** + * @notice Record the fee received for a particular pool + * @param payments array of structs containing pool id and amount + * @param payee the user the funds should be retrieved from + */ + function onFeePaid(FeePayment[] calldata payments, address payee) external; + + /** + * @notice Claims the rewards in a specific pool + * @param poolIds array of poolIds to claim rewards for + */ + function claimRewards(bytes32[] calldata poolIds) external; + + /** + * @notice Set the RewardRecipients and weights for a specific pool. This should only be called once per pool Id. Else updateRewardRecipients should be used. + * @param poolId poolId to set RewardRecipients and weights for + * @param rewardRecipientAndWeights array of each RewardRecipient and associated weight + */ + function setRewardRecipients(bytes32 poolId, Common.AddressAndWeight[] calldata rewardRecipientAndWeights) external; + + /** + * @notice Updates a subset the reward recipients for a specific poolId. The collective weight of the recipients should add up to the recipients existing weights. Any recipients with a weight of 0 will be removed. + * @param poolId the poolId to update + * @param newRewardRecipients array of new reward recipients + */ + function updateRewardRecipients(bytes32 poolId, Common.AddressAndWeight[] calldata newRewardRecipients) external; + + /** + * @notice Pays all the recipients for each of the pool ids + * @param poolId the pool id to pay recipients for + * @param recipients array of recipients to pay within the pool + */ + function payRecipients(bytes32 poolId, address[] calldata recipients) external; + + /** + * @notice Sets the fee manager. This needs to be done post construction to prevent a circular dependency. + * @param newFeeManager address of the new verifier proxy + */ + function setFeeManager(address newFeeManager) external; + + /** + * @notice Gets a list of pool ids which have reward for a specific recipient. + * @param recipient address of the recipient to get pool ids for + * @param startIndex the index to start from + * @param endIndex the index to stop at + */ + function getAvailableRewardPoolIds( + address recipient, + uint256 startIndex, + uint256 endIndex + ) external view returns (bytes32[] memory); + + /** + * @notice The structure to hold a fee payment notice + * @param poolId the poolId receiving the payment + * @param amount the amount being paid + */ + struct FeePayment { + bytes32 poolId; + uint192 amount; + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/interfaces/IVerifier.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/interfaces/IVerifier.sol new file mode 100644 index 00000000000..94b260399ea --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/interfaces/IVerifier.sol @@ -0,0 +1,123 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.19; + +import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; +import {Common} from "../../libraries/Common.sol"; + +interface IVerifier is IERC165 { + /** + * @notice Verifies that the data encoded has been signed + * correctly by routing to the correct verifier. + * @param signedReport The encoded data to be verified. + * @param sender The address that requested to verify the contract. + * This is only used for logging purposes. + * @dev Verification is typically only done through the proxy contract so + * we can't just use msg.sender to log the requester as the msg.sender + * contract will always be the proxy. + * @return verifierResponse The encoded verified response. + */ + function verify(bytes calldata signedReport, address sender) external returns (bytes memory verifierResponse); + + /** + * @notice sets offchain reporting protocol configuration incl. participating oracles + * @param feedId Feed ID to set config for + * @param signers addresses with which oracles sign the reports + * @param offchainTransmitters CSA key for the ith Oracle + * @param f number of faulty oracles the system can tolerate + * @param onchainConfig serialized configuration used by the contract (and possibly oracles) + * @param offchainConfigVersion version number for offchainEncoding schema + * @param offchainConfig serialized configuration used by the oracles exclusively and only passed through the contract + * @param recipientAddressesAndWeights the addresses and weights of all the recipients to receive rewards + */ + function setConfig( + bytes32 feedId, + address[] memory signers, + bytes32[] memory offchainTransmitters, + uint8 f, + bytes memory onchainConfig, + uint64 offchainConfigVersion, + bytes memory offchainConfig, + Common.AddressAndWeight[] memory recipientAddressesAndWeights + ) external; + + /** + * @notice identical to `setConfig` except with args for sourceChainId and sourceAddress + * @param feedId Feed ID to set config for + * @param sourceChainId Chain ID of source config + * @param sourceAddress Address of source config Verifier + * @param newConfigCount Param to force the new config count + * @param signers addresses with which oracles sign the reports + * @param offchainTransmitters CSA key for the ith Oracle + * @param f number of faulty oracles the system can tolerate + * @param onchainConfig serialized configuration used by the contract (and possibly oracles) + * @param offchainConfigVersion version number for offchainEncoding schema + * @param offchainConfig serialized configuration used by the oracles exclusively and only passed through the contract + * @param recipientAddressesAndWeights the addresses and weights of all the recipients to receive rewards + */ + function setConfigFromSource( + bytes32 feedId, + uint256 sourceChainId, + address sourceAddress, + uint32 newConfigCount, + address[] memory signers, + bytes32[] memory offchainTransmitters, + uint8 f, + bytes memory onchainConfig, + uint64 offchainConfigVersion, + bytes memory offchainConfig, + Common.AddressAndWeight[] memory recipientAddressesAndWeights + ) external; + + /** + * @notice Activates the configuration for a config digest + * @param feedId Feed ID to activate config for + * @param configDigest The config digest to activate + * @dev This function can be called by the contract admin to activate a configuration. + */ + function activateConfig(bytes32 feedId, bytes32 configDigest) external; + + /** + * @notice Deactivates the configuration for a config digest + * @param feedId Feed ID to deactivate config for + * @param configDigest The config digest to deactivate + * @dev This function can be called by the contract admin to deactivate an incorrect configuration. + */ + function deactivateConfig(bytes32 feedId, bytes32 configDigest) external; + + /** + * @notice Activates the given feed + * @param feedId Feed ID to activated + * @dev This function can be called by the contract admin to activate a feed + */ + function activateFeed(bytes32 feedId) external; + + /** + * @notice Deactivates the given feed + * @param feedId Feed ID to deactivated + * @dev This function can be called by the contract admin to deactivate a feed + */ + function deactivateFeed(bytes32 feedId) external; + + /** + * @notice returns the latest config digest and epoch for a feed + * @param feedId Feed ID to fetch data for + * @return scanLogs indicates whether to rely on the configDigest and epoch + * returned or whether to scan logs for the Transmitted event instead. + * @return configDigest + * @return epoch + */ + function latestConfigDigestAndEpoch( + bytes32 feedId + ) external view returns (bool scanLogs, bytes32 configDigest, uint32 epoch); + + /** + * @notice information about current offchain reporting protocol configuration + * @param feedId Feed ID to fetch data for + * @return configCount ordinal number of current config, out of all configs applied to this contract so far + * @return blockNumber block at which this config was set + * @return configDigest domain-separation tag for current config + */ + function latestConfigDetails( + bytes32 feedId + ) external view returns (uint32 configCount, uint32 blockNumber, bytes32 configDigest); +} diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/interfaces/IVerifierFeeManager.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/interfaces/IVerifierFeeManager.sol new file mode 100644 index 00000000000..da3fdfac153 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/interfaces/IVerifierFeeManager.sol @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.19; + +import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; +import {Common} from "../../libraries/Common.sol"; + +interface IVerifierFeeManager is IERC165 { + /** + * @notice Handles fees for a report from the subscriber and manages rewards + * @param payload report to process the fee for + * @param parameterPayload fee payload + * @param subscriber address of the fee will be applied + */ + function processFee(bytes calldata payload, bytes calldata parameterPayload, address subscriber) external payable; + + /** + * @notice Processes the fees for each report in the payload, billing the subscriber and paying the reward manager + * @param payloads reports to process + * @param parameterPayload fee payload + * @param subscriber address of the user to process fee for + */ + function processFeeBulk( + bytes[] calldata payloads, + bytes calldata parameterPayload, + address subscriber + ) external payable; + + /** + * @notice Sets the fee recipients according to the fee manager + * @param configDigest digest of the configuration + * @param rewardRecipientAndWeights the address and weights of all the recipients to receive rewards + */ + function setFeeRecipients( + bytes32 configDigest, + Common.AddressAndWeight[] calldata rewardRecipientAndWeights + ) external; +} diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/interfaces/IVerifierProxy.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/interfaces/IVerifierProxy.sol new file mode 100644 index 00000000000..6609e4869ae --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/interfaces/IVerifierProxy.sol @@ -0,0 +1,80 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.19; + +import {Common} from "../../libraries/Common.sol"; +import {AccessControllerInterface} from "../../../shared/interfaces/AccessControllerInterface.sol"; +import {IVerifierFeeManager} from "./IVerifierFeeManager.sol"; + +interface IVerifierProxy { + /** + * @notice Verifies that the data encoded has been signed + * correctly by routing to the correct verifier, and bills the user if applicable. + * @param payload The encoded data to be verified, including the signed + * report. + * @param parameterPayload fee metadata for billing + * @return verifierResponse The encoded report from the verifier. + */ + function verify( + bytes calldata payload, + bytes calldata parameterPayload + ) external payable returns (bytes memory verifierResponse); + + /** + * @notice Bulk verifies that the data encoded has been signed + * correctly by routing to the correct verifier, and bills the user if applicable. + * @param payloads The encoded payloads to be verified, including the signed + * report. + * @param parameterPayload fee metadata for billing + * @return verifiedReports The encoded reports from the verifier. + */ + function verifyBulk( + bytes[] calldata payloads, + bytes calldata parameterPayload + ) external payable returns (bytes[] memory verifiedReports); + + /** + * @notice Sets the verifier address initially, allowing `setVerifier` to be set by this Verifier in the future + * @param verifierAddress The address of the verifier contract to initialize + */ + function initializeVerifier(address verifierAddress) external; + + /** + * @notice Sets a new verifier for a config digest + * @param currentConfigDigest The current config digest + * @param newConfigDigest The config digest to set + * @param addressesAndWeights The addresses and weights of reward recipients + * reports for a given config digest. + */ + function setVerifier( + bytes32 currentConfigDigest, + bytes32 newConfigDigest, + Common.AddressAndWeight[] memory addressesAndWeights + ) external; + + /** + * @notice Removes a verifier for a given config digest + * @param configDigest The config digest of the verifier to remove + */ + function unsetVerifier(bytes32 configDigest) external; + + /** + * @notice Retrieves the verifier address that verifies reports + * for a config digest. + * @param configDigest The config digest to query for + * @return verifierAddress The address of the verifier contract that verifies + * reports for a given config digest. + */ + function getVerifier(bytes32 configDigest) external view returns (address verifierAddress); + + /** + * @notice Called by the admin to set an access controller contract + * @param accessController The new access controller to set + */ + function setAccessController(AccessControllerInterface accessController) external; + + /** + * @notice Updates the fee manager + * @param feeManager The new fee manager + */ + function setFeeManager(IVerifierFeeManager feeManager) external; +} diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/fee-manager/BaseFeeManager.t.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/fee-manager/BaseFeeManager.t.sol new file mode 100644 index 00000000000..0d598cdac52 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/fee-manager/BaseFeeManager.t.sol @@ -0,0 +1,379 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import {Test} from "forge-std/Test.sol"; +import {FeeManager} from "../../FeeManager.sol"; +import {RewardManager} from "../../RewardManager.sol"; +import {Common} from "../../../libraries/Common.sol"; +import {ERC20Mock} from "../../../../vendor/openzeppelin-solidity/v4.8.3/contracts/mocks/ERC20Mock.sol"; +import {WERC20Mock} from "../../../../shared/mocks/WERC20Mock.sol"; +import {IRewardManager} from "../../interfaces/IRewardManager.sol"; +import {FeeManagerProxy} from "../mocks/FeeManagerProxy.sol"; + +/** + * @title BaseFeeManagerTest + * @author Michael Fletcher + * @notice Base class for all feeManager tests + * @dev This contract is intended to be inherited from and not used directly. It contains functionality to setup the feeManager + */ +contract BaseFeeManagerTest is Test { + //contracts + FeeManager internal feeManager; + RewardManager internal rewardManager; + FeeManagerProxy internal feeManagerProxy; + + ERC20Mock internal link; + WERC20Mock internal native; + + //erc20 config + uint256 internal constant DEFAULT_LINK_MINT_QUANTITY = 100 ether; + uint256 internal constant DEFAULT_NATIVE_MINT_QUANTITY = 100 ether; + + //contract owner + address internal constant INVALID_ADDRESS = address(0); + address internal constant ADMIN = address(uint160(uint256(keccak256("ADMIN")))); + address internal constant USER = address(uint160(uint256(keccak256("USER")))); + address internal constant PROXY = address(uint160(uint256(keccak256("PROXY")))); + + //version masks + bytes32 internal constant V_MASK = 0x0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff; + bytes32 internal constant V1_BITMASK = 0x0001000000000000000000000000000000000000000000000000000000000000; + bytes32 internal constant V2_BITMASK = 0x0002000000000000000000000000000000000000000000000000000000000000; + bytes32 internal constant V3_BITMASK = 0x0003000000000000000000000000000000000000000000000000000000000000; + + //feed ids & config digests + bytes32 internal constant DEFAULT_FEED_1_V1 = (keccak256("ETH-USD") & V_MASK) | V1_BITMASK; + bytes32 internal constant DEFAULT_FEED_1_V2 = (keccak256("ETH-USD") & V_MASK) | V2_BITMASK; + bytes32 internal constant DEFAULT_FEED_1_V3 = (keccak256("ETH-USD") & V_MASK) | V3_BITMASK; + + bytes32 internal constant DEFAULT_FEED_2_V3 = (keccak256("LINK-USD") & V_MASK) | V3_BITMASK; + bytes32 internal constant DEFAULT_CONFIG_DIGEST = keccak256("DEFAULT_CONFIG_DIGEST"); + + //report + uint256 internal constant DEFAULT_REPORT_LINK_FEE = 1e10; + uint256 internal constant DEFAULT_REPORT_NATIVE_FEE = 1e12; + + //rewards + uint64 internal constant FEE_SCALAR = 1e18; + + address internal constant NATIVE_WITHDRAW_ADDRESS = address(0); + + //the selector for each error + bytes4 internal immutable INVALID_DISCOUNT_ERROR = FeeManager.InvalidDiscount.selector; + bytes4 internal immutable INVALID_ADDRESS_ERROR = FeeManager.InvalidAddress.selector; + bytes4 internal immutable INVALID_SURCHARGE_ERROR = FeeManager.InvalidSurcharge.selector; + bytes4 internal immutable EXPIRED_REPORT_ERROR = FeeManager.ExpiredReport.selector; + bytes4 internal immutable INVALID_DEPOSIT_ERROR = FeeManager.InvalidDeposit.selector; + bytes4 internal immutable INVALID_QUOTE_ERROR = FeeManager.InvalidQuote.selector; + bytes4 internal immutable UNAUTHORIZED_ERROR = FeeManager.Unauthorized.selector; + bytes internal constant ONLY_CALLABLE_BY_OWNER_ERROR = "Only callable by owner"; + bytes internal constant INSUFFICIENT_ALLOWANCE_ERROR = "ERC20: insufficient allowance"; + bytes4 internal immutable ZERO_DEFICIT = FeeManager.ZeroDeficit.selector; + + //events emitted + event SubscriberDiscountUpdated(address indexed subscriber, bytes32 indexed feedId, address token, uint64 discount); + event NativeSurchargeUpdated(uint64 newSurcharge); + event InsufficientLink(IRewardManager.FeePayment[] feesAndRewards); + event Withdraw(address adminAddress, address recipient, address assetAddress, uint192 quantity); + event LinkDeficitCleared(bytes32 indexed configDigest, uint256 linkQuantity); + event DiscountApplied( + bytes32 indexed configDigest, + address indexed subscriber, + Common.Asset fee, + Common.Asset reward, + uint256 appliedDiscountQuantity + ); + + function setUp() public virtual { + //change to admin user + vm.startPrank(ADMIN); + + //init required contracts + _initializeContracts(); + } + + function _initializeContracts() internal { + link = new ERC20Mock("LINK", "LINK", ADMIN, 0); + native = new WERC20Mock(); + + feeManagerProxy = new FeeManagerProxy(); + rewardManager = new RewardManager(address(link)); + feeManager = new FeeManager(address(link), address(native), address(feeManagerProxy), address(rewardManager)); + + //link the feeManager to the proxy + feeManagerProxy.setFeeManager(feeManager); + + //link the feeManager to the reward manager + rewardManager.setFeeManager(address(feeManager)); + + //mint some tokens to the admin + link.mint(ADMIN, DEFAULT_LINK_MINT_QUANTITY); + native.mint(ADMIN, DEFAULT_NATIVE_MINT_QUANTITY); + vm.deal(ADMIN, DEFAULT_NATIVE_MINT_QUANTITY); + + //mint some tokens to the user + link.mint(USER, DEFAULT_LINK_MINT_QUANTITY); + native.mint(USER, DEFAULT_NATIVE_MINT_QUANTITY); + vm.deal(USER, DEFAULT_NATIVE_MINT_QUANTITY); + + //mint some tokens to the proxy + link.mint(PROXY, DEFAULT_LINK_MINT_QUANTITY); + native.mint(PROXY, DEFAULT_NATIVE_MINT_QUANTITY); + vm.deal(PROXY, DEFAULT_NATIVE_MINT_QUANTITY); + } + + function setSubscriberDiscount( + address subscriber, + bytes32 feedId, + address token, + uint256 discount, + address sender + ) internal { + //record the current address and switch to the recipient + address originalAddr = msg.sender; + changePrank(sender); + + //set the discount + feeManager.updateSubscriberDiscount(subscriber, feedId, token, uint64(discount)); + + //change back to the original address + changePrank(originalAddr); + } + + function setNativeSurcharge(uint256 surcharge, address sender) public { + //record the current address and switch to the recipient + address originalAddr = msg.sender; + changePrank(sender); + + //set the surcharge + feeManager.setNativeSurcharge(uint64(surcharge)); + + //change back to the original address + changePrank(originalAddr); + } + + // solium-disable-next-line no-unused-vars + function getFee(bytes memory report, address quote, address subscriber) public view returns (Common.Asset memory) { + //get the fee + (Common.Asset memory fee, , ) = feeManager.getFeeAndReward(subscriber, report, quote); + + return fee; + } + + function getReward(bytes memory report, address quote, address subscriber) public view returns (Common.Asset memory) { + //get the reward + (, Common.Asset memory reward, ) = feeManager.getFeeAndReward(subscriber, report, quote); + + return reward; + } + + function getAppliedDiscount(bytes memory report, address quote, address subscriber) public view returns (uint256) { + //get the reward + (, , uint256 appliedDiscount) = feeManager.getFeeAndReward(subscriber, report, quote); + + return appliedDiscount; + } + + function getV1Report(bytes32 feedId) public pure returns (bytes memory) { + return abi.encode(feedId, uint32(0), int192(0), int192(0), int192(0), uint64(0), bytes32(0), uint64(0), uint64(0)); + } + + function getV2Report(bytes32 feedId) public view returns (bytes memory) { + return + abi.encode( + feedId, + uint32(0), + uint32(0), + uint192(DEFAULT_REPORT_NATIVE_FEE), + uint192(DEFAULT_REPORT_LINK_FEE), + uint32(block.timestamp), + int192(0) + ); + } + + function getV3Report(bytes32 feedId) public view returns (bytes memory) { + return + abi.encode( + feedId, + uint32(0), + uint32(0), + uint192(DEFAULT_REPORT_NATIVE_FEE), + uint192(DEFAULT_REPORT_LINK_FEE), + uint32(block.timestamp), + int192(0), + int192(0), + int192(0) + ); + } + + function getV3ReportWithCustomExpiryAndFee( + bytes32 feedId, + uint256 expiry, + uint256 linkFee, + uint256 nativeFee + ) public pure returns (bytes memory) { + return + abi.encode( + feedId, + uint32(0), + uint32(0), + uint192(nativeFee), + uint192(linkFee), + uint32(expiry), + int192(0), + int192(0), + int192(0) + ); + } + + function getLinkQuote() public view returns (address) { + return address(link); + } + + function getNativeQuote() public view returns (address) { + return address(native); + } + + function withdraw(address assetAddress, address recipient, uint256 amount, address sender) public { + //record the current address and switch to the recipient + address originalAddr = msg.sender; + changePrank(sender); + + //set the surcharge + feeManager.withdraw(assetAddress, recipient, uint192(amount)); + + //change back to the original address + changePrank(originalAddr); + } + + function getLinkBalance(address balanceAddress) public view returns (uint256) { + return link.balanceOf(balanceAddress); + } + + function getNativeBalance(address balanceAddress) public view returns (uint256) { + return native.balanceOf(balanceAddress); + } + + function getNativeUnwrappedBalance(address balanceAddress) public view returns (uint256) { + return balanceAddress.balance; + } + + function mintLink(address recipient, uint256 amount) public { + //record the current address and switch to the recipient + address originalAddr = msg.sender; + changePrank(ADMIN); + + //mint the link to the recipient + link.mint(recipient, amount); + + //change back to the original address + changePrank(originalAddr); + } + + function mintNative(address recipient, uint256 amount, address sender) public { + //record the current address and switch to the recipient + address originalAddr = msg.sender; + changePrank(sender); + + //mint the native to the recipient + native.mint(recipient, amount); + + //change back to the original address + changePrank(originalAddr); + } + + function issueUnwrappedNative(address recipient, uint256 quantity) public { + vm.deal(recipient, quantity); + } + + function ProcessFeeAsUser( + bytes memory payload, + address subscriber, + address tokenAddress, + uint256 wrappedNativeValue, + address sender + ) public { + //record the current address and switch to the recipient + address originalAddr = msg.sender; + changePrank(sender); + + //process the fee + feeManager.processFee{value: wrappedNativeValue}(payload, abi.encode(tokenAddress), subscriber); + + //change ProcessFeeAsUserback to the original address + changePrank(originalAddr); + } + + function processFee(bytes memory payload, address subscriber, address feeAddress, uint256 wrappedNativeValue) public { + //record the current address and switch to the recipient + address originalAddr = msg.sender; + changePrank(subscriber); + + //process the fee + feeManagerProxy.processFee{value: wrappedNativeValue}(payload, abi.encode(feeAddress)); + + //change back to the original address + changePrank(originalAddr); + } + + function processFee( + bytes[] memory payloads, + address subscriber, + address feeAddress, + uint256 wrappedNativeValue + ) public { + //record the current address and switch to the recipient + address originalAddr = msg.sender; + changePrank(subscriber); + + //process the fee + feeManagerProxy.processFeeBulk{value: wrappedNativeValue}(payloads, abi.encode(feeAddress)); + + //change back to the original address + changePrank(originalAddr); + } + + function getPayload(bytes memory reportPayload) public pure returns (bytes memory) { + return abi.encode([DEFAULT_CONFIG_DIGEST, 0, 0], reportPayload, new bytes32[](1), new bytes32[](1), bytes32("")); + } + + function approveLink(address spender, uint256 quantity, address sender) public { + //record the current address and switch to the recipient + address originalAddr = msg.sender; + changePrank(sender); + + //approve the link to be transferred + link.approve(spender, quantity); + + //change back to the original address + changePrank(originalAddr); + } + + function approveNative(address spender, uint256 quantity, address sender) public { + //record the current address and switch to the recipient + address originalAddr = msg.sender; + changePrank(sender); + + //approve the link to be transferred + native.approve(spender, quantity); + + //change back to the original address + changePrank(originalAddr); + } + + function payLinkDeficit(bytes32 configDigest, address sender) public { + //record the current address and switch to the recipient + address originalAddr = msg.sender; + changePrank(sender); + + //approve the link to be transferred + feeManager.payLinkDeficit(configDigest); + + //change back to the original address + changePrank(originalAddr); + } + + function getLinkDeficit(bytes32 configDigest) public view returns (uint256) { + return feeManager.s_linkDeficit(configDigest); + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/fee-manager/FeeManager.general.t.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/fee-manager/FeeManager.general.t.sol new file mode 100644 index 00000000000..571d34823f4 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/fee-manager/FeeManager.general.t.sol @@ -0,0 +1,242 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import "./BaseFeeManager.t.sol"; + +/** + * @title BaseFeeManagerTest + * @author Michael Fletcher + * @notice This contract will test the setup functionality of the feemanager + */ +contract FeeManagerProcessFeeTest is BaseFeeManagerTest { + function setUp() public override { + super.setUp(); + } + + function test_WithdrawERC20() public { + //simulate a fee + mintLink(address(feeManager), DEFAULT_LINK_MINT_QUANTITY); + + //get the balances to ne used for comparison + uint256 contractBalance = getLinkBalance(address(feeManager)); + uint256 adminBalance = getLinkBalance(ADMIN); + + //the amount to withdraw + uint256 withdrawAmount = contractBalance / 2; + + //withdraw some balance + withdraw(address(link), ADMIN, withdrawAmount, ADMIN); + + //check the balance has been reduced + uint256 newContractBalance = getLinkBalance(address(feeManager)); + uint256 newAdminBalance = getLinkBalance(ADMIN); + + //check the balance is greater than zero + assertGt(newContractBalance, 0); + //check the balance has been reduced by the correct amount + assertEq(newContractBalance, contractBalance - withdrawAmount); + //check the admin balance has increased by the correct amount + assertEq(newAdminBalance, adminBalance + withdrawAmount); + } + + function test_WithdrawUnwrappedNative() public { + //issue funds straight to the contract to bypass the lack of fallback function + issueUnwrappedNative(address(feeManager), DEFAULT_NATIVE_MINT_QUANTITY); + + //get the balances to be used for comparison + uint256 contractBalance = getNativeUnwrappedBalance(address(feeManager)); + uint256 adminBalance = getNativeUnwrappedBalance(ADMIN); + + //the amount to withdraw + uint256 withdrawAmount = contractBalance / 2; + + //withdraw some balance + withdraw(NATIVE_WITHDRAW_ADDRESS, ADMIN, withdrawAmount, ADMIN); + + //check the balance has been reduced + uint256 newContractBalance = getNativeUnwrappedBalance(address(feeManager)); + uint256 newAdminBalance = getNativeUnwrappedBalance(ADMIN); + + //check the balance is greater than zero + assertGt(newContractBalance, 0); + //check the balance has been reduced by the correct amount + assertEq(newContractBalance, contractBalance - withdrawAmount); + //check the admin balance has increased by the correct amount + assertEq(newAdminBalance, adminBalance + withdrawAmount); + } + + function test_WithdrawNonAdminAddr() public { + //simulate a fee + mintLink(address(feeManager), DEFAULT_LINK_MINT_QUANTITY); + + //should revert if not admin + vm.expectRevert(ONLY_CALLABLE_BY_OWNER_ERROR); + + //withdraw some balance + withdraw(address(link), ADMIN, DEFAULT_LINK_MINT_QUANTITY, USER); + } + + function test_eventIsEmittedAfterSurchargeIsSet() public { + //native surcharge + uint64 nativeSurcharge = FEE_SCALAR / 5; + + //expect an emit + vm.expectEmit(); + + //emit the event that is expected to be emitted + emit NativeSurchargeUpdated(nativeSurcharge); + + //set the surcharge + setNativeSurcharge(nativeSurcharge, ADMIN); + } + + function test_subscriberDiscountEventIsEmittedOnUpdate() public { + //native surcharge + uint64 discount = FEE_SCALAR / 3; + + //an event should be emitted + vm.expectEmit(); + + //emit the event that is expected to be emitted + emit SubscriberDiscountUpdated(USER, DEFAULT_FEED_1_V3, address(native), discount); + + //set the surcharge + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), discount, ADMIN); + } + + function test_eventIsEmittedUponWithdraw() public { + //simulate a fee + mintLink(address(feeManager), DEFAULT_LINK_MINT_QUANTITY); + + //the amount to withdraw + uint192 withdrawAmount = 1; + + //expect an emit + vm.expectEmit(); + + //the event to be emitted + emit Withdraw(ADMIN, ADMIN, address(link), withdrawAmount); + + //withdraw some balance + withdraw(address(link), ADMIN, withdrawAmount, ADMIN); + } + + function test_linkAvailableForPaymentReturnsLinkBalance() public { + //simulate a deposit of link for the conversion pool + mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE); + + //check there's a balance + assertGt(getLinkBalance(address(feeManager)), 0); + + //check the link available for payment is the link balance + assertEq(feeManager.linkAvailableForPayment(), getLinkBalance(address(feeManager))); + } + + function test_payLinkDeficit() public { + //get the default payload + bytes memory payload = getPayload(getV2Report(DEFAULT_FEED_1_V3)); + + approveNative(address(feeManager), DEFAULT_REPORT_NATIVE_FEE, USER); + + //not enough funds in the reward pool should trigger an insufficient link event + vm.expectEmit(); + + IRewardManager.FeePayment[] memory contractFees = new IRewardManager.FeePayment[](1); + contractFees[0] = IRewardManager.FeePayment(DEFAULT_CONFIG_DIGEST, uint192(DEFAULT_REPORT_LINK_FEE)); + + emit InsufficientLink(contractFees); + + //process the fee + processFee(payload, USER, address(native), 0); + + //double check the rewardManager balance is 0 + assertEq(getLinkBalance(address(rewardManager)), 0); + + //simulate a deposit of link to cover the deficit + mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE); + + vm.expectEmit(); + emit LinkDeficitCleared(DEFAULT_CONFIG_DIGEST, DEFAULT_REPORT_LINK_FEE); + + //pay the deficit which will transfer link from the rewardManager to the rewardManager + payLinkDeficit(DEFAULT_CONFIG_DIGEST, ADMIN); + + //check the rewardManager received the link + assertEq(getLinkBalance(address(rewardManager)), DEFAULT_REPORT_LINK_FEE); + } + + function test_payLinkDeficitTwice() public { + //get the default payload + bytes memory payload = getPayload(getV2Report(DEFAULT_FEED_1_V3)); + + approveNative(address(feeManager), DEFAULT_REPORT_NATIVE_FEE, USER); + + //not enough funds in the reward pool should trigger an insufficient link event + vm.expectEmit(); + + IRewardManager.FeePayment[] memory contractFees = new IRewardManager.FeePayment[](1); + contractFees[0] = IRewardManager.FeePayment(DEFAULT_CONFIG_DIGEST, uint192(DEFAULT_REPORT_LINK_FEE)); + + //emit the event that is expected to be emitted + emit InsufficientLink(contractFees); + + //process the fee + processFee(payload, USER, address(native), 0); + + //double check the rewardManager balance is 0 + assertEq(getLinkBalance(address(rewardManager)), 0); + + //simulate a deposit of link to cover the deficit + mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE); + + vm.expectEmit(); + emit LinkDeficitCleared(DEFAULT_CONFIG_DIGEST, DEFAULT_REPORT_LINK_FEE); + + //pay the deficit which will transfer link from the rewardManager to the rewardManager + payLinkDeficit(DEFAULT_CONFIG_DIGEST, ADMIN); + + //check the rewardManager received the link + assertEq(getLinkBalance(address(rewardManager)), DEFAULT_REPORT_LINK_FEE); + + //paying again should revert with 0 + vm.expectRevert(ZERO_DEFICIT); + + payLinkDeficit(DEFAULT_CONFIG_DIGEST, ADMIN); + } + + function test_payLinkDeficitPaysAllFeesProcessed() public { + //get the default payload + bytes memory payload = getPayload(getV2Report(DEFAULT_FEED_1_V3)); + + //approve the native to be transferred from the user + approveNative(address(feeManager), DEFAULT_REPORT_NATIVE_FEE * 2, USER); + + //processing the fee will transfer the native from the user to the feeManager + processFee(payload, USER, address(native), 0); + processFee(payload, USER, address(native), 0); + + //check the deficit has been increased twice + assertEq(getLinkDeficit(DEFAULT_CONFIG_DIGEST), DEFAULT_REPORT_LINK_FEE * 2); + + //double check the rewardManager balance is 0 + assertEq(getLinkBalance(address(rewardManager)), 0); + + //simulate a deposit of link to cover the deficit + mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE * 2); + + vm.expectEmit(); + emit LinkDeficitCleared(DEFAULT_CONFIG_DIGEST, DEFAULT_REPORT_LINK_FEE * 2); + + //pay the deficit which will transfer link from the rewardManager to the rewardManager + payLinkDeficit(DEFAULT_CONFIG_DIGEST, ADMIN); + + //check the rewardManager received the link + assertEq(getLinkBalance(address(rewardManager)), DEFAULT_REPORT_LINK_FEE * 2); + } + + function test_payLinkDeficitOnlyCallableByAdmin() public { + vm.expectRevert(ONLY_CALLABLE_BY_OWNER_ERROR); + + payLinkDeficit(DEFAULT_CONFIG_DIGEST, USER); + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/fee-manager/FeeManager.getFeeAndReward.t.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/fee-manager/FeeManager.getFeeAndReward.t.sol new file mode 100644 index 00000000000..1b0f95d51bd --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/fee-manager/FeeManager.getFeeAndReward.t.sol @@ -0,0 +1,606 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import {Common} from "../../../libraries/Common.sol"; +import "./BaseFeeManager.t.sol"; + +/** + * @title BaseFeeManagerTest + * @author Michael Fletcher + * @notice This contract will test the functionality of the feeManager's getFeeAndReward + */ +contract FeeManagerProcessFeeTest is BaseFeeManagerTest { + function test_baseFeeIsAppliedForNative() public view { + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //fee should be the default + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE); + } + + function test_baseFeeIsAppliedForLink() public view { + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER); + + //fee should be the default + assertEq(fee.amount, DEFAULT_REPORT_LINK_FEE); + } + + function test_discountAIsNotAppliedWhenSetForOtherUsers() public { + //set the subscriber discount for another user + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(link), FEE_SCALAR / 2, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), INVALID_ADDRESS); + + //fee should be the default + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE); + } + + function test_discountIsNotAppliedForInvalidTokenAddress() public { + //should revert with invalid address as it's not a configured token + vm.expectRevert(INVALID_ADDRESS_ERROR); + + //set the subscriber discount for another user + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, INVALID_ADDRESS, FEE_SCALAR / 2, ADMIN); + } + + function test_discountIsAppliedForLink() public { + //set the subscriber discount to 50% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(link), FEE_SCALAR / 2, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER); + + //fee should be half the default + assertEq(fee.amount, DEFAULT_REPORT_LINK_FEE / 2); + } + + function test_DiscountIsAppliedForNative() public { + //set the subscriber discount to 50% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), FEE_SCALAR / 2, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //fee should be half the default + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE / 2); + } + + function test_discountIsNoLongerAppliedAfterRemoving() public { + //set the subscriber discount to 50% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(link), FEE_SCALAR / 2, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER); + + //fee should be half the default + assertEq(fee.amount, DEFAULT_REPORT_LINK_FEE / 2); + + //remove the discount + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(link), 0, ADMIN); + + //get the fee required by the feeManager + fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER); + + //fee should be the default + assertEq(fee.amount, DEFAULT_REPORT_LINK_FEE); + } + + function test_surchargeIsApplied() public { + //native surcharge + uint256 nativeSurcharge = FEE_SCALAR / 5; + + //set the surcharge + setNativeSurcharge(nativeSurcharge, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //calculate the expected surcharge + uint256 expectedSurcharge = ((DEFAULT_REPORT_NATIVE_FEE * nativeSurcharge) / FEE_SCALAR); + + //expected fee should the base fee offset by the surcharge and discount + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE + expectedSurcharge); + } + + function test_surchargeIsNotAppliedForLinkFee() public { + //native surcharge + uint256 nativeSurcharge = FEE_SCALAR / 5; + + //set the surcharge + setNativeSurcharge(nativeSurcharge, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER); + + //fee should be the default + assertEq(fee.amount, DEFAULT_REPORT_LINK_FEE); + } + + function test_surchargeIsNoLongerAppliedAfterRemoving() public { + //native surcharge + uint256 nativeSurcharge = FEE_SCALAR / 5; + + //set the surcharge + setNativeSurcharge(nativeSurcharge, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //calculate the expected surcharge + uint256 expectedSurcharge = ((DEFAULT_REPORT_NATIVE_FEE * nativeSurcharge) / FEE_SCALAR); + + //expected fee should be the base fee offset by the surcharge and discount + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE + expectedSurcharge); + + //remove the surcharge + setNativeSurcharge(0, ADMIN); + + //get the fee required by the feeManager + fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //fee should be the default + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE); + } + + function test_feeIsUpdatedAfterNewSurchargeIsApplied() public { + //native surcharge + uint256 nativeSurcharge = FEE_SCALAR / 5; + + //set the surcharge + setNativeSurcharge(nativeSurcharge, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //calculate the expected surcharge + uint256 expectedSurcharge = ((DEFAULT_REPORT_NATIVE_FEE * nativeSurcharge) / FEE_SCALAR); + + //expected fee should the base fee offset by the surcharge and discount + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE + expectedSurcharge); + + //change the surcharge + setNativeSurcharge(nativeSurcharge, ADMIN); + + //get the fee required by the feeManager + fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //calculate the expected surcharge + expectedSurcharge = ((DEFAULT_REPORT_NATIVE_FEE * nativeSurcharge) / FEE_SCALAR); + + //expected fee should the base fee offset by the surcharge and discount + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE + expectedSurcharge); + } + + function test_surchargeIsAppliedForNativeFeeWithDiscount() public { + //native surcharge + uint256 nativeSurcharge = FEE_SCALAR / 5; + + //set the subscriber discount to 50% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), FEE_SCALAR / 2, ADMIN); + + //set the surcharge + setNativeSurcharge(nativeSurcharge, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //calculate the expected surcharge quantity + uint256 expectedSurcharge = ((DEFAULT_REPORT_NATIVE_FEE * nativeSurcharge) / FEE_SCALAR); + + //calculate the expected discount quantity + uint256 expectedDiscount = ((DEFAULT_REPORT_NATIVE_FEE + expectedSurcharge) / 2); + + //expected fee should the base fee offset by the surcharge and discount + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE + expectedSurcharge - expectedDiscount); + } + + function test_emptyQuoteRevertsWithError() public { + //expect a revert + vm.expectRevert(INVALID_QUOTE_ERROR); + + //get the fee required by the feeManager + getFee(getV3Report(DEFAULT_FEED_1_V3), address(0), USER); + } + + function test_nativeSurcharge100Percent() public { + //set the surcharge + setNativeSurcharge(FEE_SCALAR, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //fee should be twice the base fee + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE * 2); + } + + function test_nativeSurcharge0Percent() public { + //set the surcharge + setNativeSurcharge(0, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //fee should base fee + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE); + } + + function test_nativeSurchargeCannotExceed100Percent() public { + //should revert if surcharge is greater than 100% + vm.expectRevert(INVALID_SURCHARGE_ERROR); + + //set the surcharge above the max + setNativeSurcharge(FEE_SCALAR + 1, ADMIN); + } + + function test_discountIsAppliedWith100PercentSurcharge() public { + //set the subscriber discount to 50% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), FEE_SCALAR / 2, ADMIN); + + //set the surcharge + setNativeSurcharge(FEE_SCALAR, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //calculate the expected discount quantity + uint256 expectedDiscount = DEFAULT_REPORT_NATIVE_FEE; + + //fee should be twice the surcharge minus the discount + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE * 2 - expectedDiscount); + } + + function test_feeIsZeroWith100PercentDiscount() public { + //set the subscriber discount to 100% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), FEE_SCALAR, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //fee should be zero + assertEq(fee.amount, 0); + } + + function test_feeIsUpdatedAfterDiscountIsRemoved() public { + //set the subscriber discount to 50% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), FEE_SCALAR / 2, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //calculate the expected discount quantity + uint256 expectedDiscount = DEFAULT_REPORT_NATIVE_FEE / 2; + + //fee should be 50% of the base fee + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE - expectedDiscount); + + //remove the discount + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), 0, ADMIN); + + //get the fee required by the feeManager + fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //fee should be the base fee + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE); + } + + function test_feeIsUpdatedAfterNewDiscountIsApplied() public { + //set the subscriber discount to 50% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), FEE_SCALAR / 2, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //calculate the expected discount quantity + uint256 expectedDiscount = DEFAULT_REPORT_NATIVE_FEE / 2; + + //fee should be 50% of the base fee + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE - expectedDiscount); + + //change the discount to 25% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), FEE_SCALAR / 4, ADMIN); + + //get the fee required by the feeManager + fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //expected discount is now 25% + expectedDiscount = DEFAULT_REPORT_NATIVE_FEE / 4; + + //fee should be the base fee minus the expected discount + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE - expectedDiscount); + } + + function test_setDiscountOver100Percent() public { + //should revert with invalid discount + vm.expectRevert(INVALID_DISCOUNT_ERROR); + + //set the subscriber discount to over 100% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), FEE_SCALAR + 1, ADMIN); + } + + function test_surchargeIsNotAppliedWith100PercentDiscount() public { + //native surcharge + uint256 nativeSurcharge = FEE_SCALAR / 5; + + //set the subscriber discount to 100% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), FEE_SCALAR, ADMIN); + + //set the surcharge + setNativeSurcharge(nativeSurcharge, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //fee should be zero + assertEq(fee.amount, 0); + } + + function test_nonAdminUserCanNotSetDiscount() public { + //should revert with unauthorized + vm.expectRevert(ONLY_CALLABLE_BY_OWNER_ERROR); + + //set the subscriber discount to 50% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), FEE_SCALAR, USER); + } + + function test_surchargeFeeRoundsUpWhenUneven() public { + //native surcharge + uint256 nativeSurcharge = FEE_SCALAR / 3; + + //set the surcharge + setNativeSurcharge(nativeSurcharge, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //calculate the expected surcharge quantity + uint256 expectedSurcharge = (DEFAULT_REPORT_NATIVE_FEE * nativeSurcharge) / FEE_SCALAR; + + //expected fee should the base fee offset by the expected surcharge + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE + expectedSurcharge + 1); + } + + function test_discountFeeRoundsDownWhenUneven() public { + //native surcharge + uint256 discount = FEE_SCALAR / 3; + + //set the subscriber discount to 33.333% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), discount, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //calculate the expected quantity + uint256 expectedDiscount = ((DEFAULT_REPORT_NATIVE_FEE * discount) / FEE_SCALAR); + + //expected fee should the base fee offset by the expected surcharge + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE - expectedDiscount); + } + + function test_reportWithNoExpiryOrFeeReturnsZero() public view { + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV1Report(DEFAULT_FEED_1_V1), getNativeQuote(), USER); + + //fee should be zero + assertEq(fee.amount, 0); + } + + function test_correctDiscountIsAppliedWhenBothTokensAreDiscounted() public { + //set the subscriber and native discounts + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(link), FEE_SCALAR / 4, ADMIN); + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), FEE_SCALAR / 2, ADMIN); + + //get the fee required by the feeManager for both tokens + Common.Asset memory linkFee = getFee(getV3Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER); + Common.Asset memory nativeFee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //calculate the expected discount quantity for each token + uint256 expectedDiscountLink = (DEFAULT_REPORT_LINK_FEE * FEE_SCALAR) / 4 / FEE_SCALAR; + uint256 expectedDiscountNative = (DEFAULT_REPORT_NATIVE_FEE * FEE_SCALAR) / 2 / FEE_SCALAR; + + //check the fee calculation for each token + assertEq(linkFee.amount, DEFAULT_REPORT_LINK_FEE - expectedDiscountLink); + assertEq(nativeFee.amount, DEFAULT_REPORT_NATIVE_FEE - expectedDiscountNative); + } + + function test_discountIsNotAppliedToOtherFeeds() public { + //set the subscriber discount to 50% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), FEE_SCALAR / 2, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_2_V3), getNativeQuote(), USER); + + //fee should be the base fee + assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE); + } + + function test_noFeeIsAppliedWhenReportHasZeroFee() public { + //set the subscriber discount to 50% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), FEE_SCALAR / 2, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee( + getV3ReportWithCustomExpiryAndFee(DEFAULT_FEED_1_V3, uint32(block.timestamp), 0, 0), + getNativeQuote(), + USER + ); + + //fee should be zero + assertEq(fee.amount, 0); + } + + function test_noFeeIsAppliedWhenReportHasZeroFeeAndDiscountAndSurchargeIsSet() public { + //set the subscriber discount to 50% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), FEE_SCALAR / 2, ADMIN); + + //set the surcharge + setNativeSurcharge(FEE_SCALAR / 2, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee( + getV3ReportWithCustomExpiryAndFee(DEFAULT_FEED_1_V3, uint32(block.timestamp), 0, 0), + getNativeQuote(), + USER + ); + + //fee should be zero + assertEq(fee.amount, 0); + } + + function test_nativeSurchargeEventIsEmittedOnUpdate() public { + //native surcharge + uint64 nativeSurcharge = FEE_SCALAR / 3; + + //an event should be emitted + vm.expectEmit(); + + //emit the event that is expected to be emitted + emit NativeSurchargeUpdated(nativeSurcharge); + + //set the surcharge + setNativeSurcharge(nativeSurcharge, ADMIN); + } + + function test_getBaseRewardWithLinkQuote() public view { + //get the fee required by the feeManager + Common.Asset memory reward = getReward(getV3Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER); + + //the reward should equal the base fee + assertEq(reward.amount, DEFAULT_REPORT_LINK_FEE); + } + + function test_getRewardWithLinkQuoteAndLinkDiscount() public { + //set the link discount + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(link), FEE_SCALAR / 2, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory reward = getReward(getV3Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER); + + //the reward should equal the discounted base fee + assertEq(reward.amount, DEFAULT_REPORT_LINK_FEE / 2); + } + + function test_getRewardWithNativeQuote() public view { + //get the fee required by the feeManager + Common.Asset memory reward = getReward(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //the reward should equal the base fee in link + assertEq(reward.amount, DEFAULT_REPORT_LINK_FEE); + } + + function test_getRewardWithNativeQuoteAndSurcharge() public { + //set the native surcharge + setNativeSurcharge(FEE_SCALAR / 2, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory reward = getReward(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //the reward should equal the base fee in link regardless of the surcharge + assertEq(reward.amount, DEFAULT_REPORT_LINK_FEE); + } + + function test_getRewardWithLinkDiscount() public { + //set the link discount + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(link), FEE_SCALAR / 2, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory reward = getReward(getV3Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER); + + //the reward should equal the discounted base fee + assertEq(reward.amount, DEFAULT_REPORT_LINK_FEE / 2); + } + + function test_getLinkFeeIsRoundedUp() public { + //set the link discount + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(link), FEE_SCALAR / 3, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER); + + //the reward should equal .66% + 1 of the base fee due to a 33% discount rounded up + assertEq(fee.amount, (DEFAULT_REPORT_LINK_FEE * 2) / 3 + 1); + } + + function test_getLinkRewardIsSameAsFee() public { + //set the link discount + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(link), FEE_SCALAR / 3, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER); + Common.Asset memory reward = getReward(getV3Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER); + + //check the reward is in link + assertEq(fee.assetAddress, address(link)); + + //the reward should equal .66% of the base fee due to a 33% discount rounded down + assertEq(reward.amount, fee.amount); + } + + function test_getLinkRewardWithNativeQuoteAndSurchargeWithLinkDiscount() public { + //set the native surcharge + setNativeSurcharge(FEE_SCALAR / 2, ADMIN); + + //set the link discount + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(link), FEE_SCALAR / 3, ADMIN); + + //get the fee required by the feeManager + Common.Asset memory reward = getReward(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //the reward should equal the base fee in link regardless of the surcharge + assertEq(reward.amount, DEFAULT_REPORT_LINK_FEE); + } + + function test_testRevertIfReportHasExpired() public { + //expect a revert + vm.expectRevert(EXPIRED_REPORT_ERROR); + + //get the fee required by the feeManager + getFee( + getV3ReportWithCustomExpiryAndFee( + DEFAULT_FEED_1_V3, + block.timestamp - 1, + DEFAULT_REPORT_LINK_FEE, + DEFAULT_REPORT_NATIVE_FEE + ), + getNativeQuote(), + USER + ); + } + + function test_discountIsReturnedForLink() public { + //set the subscriber discount to 50% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(link), FEE_SCALAR / 2, ADMIN); + + //get the fee applied + uint256 discount = getAppliedDiscount(getV3Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER); + + //fee should be half the default + assertEq(discount, FEE_SCALAR / 2); + } + + function test_DiscountIsReturnedForNative() public { + //set the subscriber discount to 50% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), FEE_SCALAR / 2, ADMIN); + + //get the discount applied + uint256 discount = getAppliedDiscount(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //fee should be half the default + assertEq(discount, FEE_SCALAR / 2); + } + + function test_DiscountIsReturnedForNativeWithSurcharge() public { + //set the subscriber discount to 50% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), FEE_SCALAR / 2, ADMIN); + + //set the surcharge + setNativeSurcharge(FEE_SCALAR / 5, ADMIN); + + //get the discount applied + uint256 discount = getAppliedDiscount(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //fee should be half the default + assertEq(discount, FEE_SCALAR / 2); + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/fee-manager/FeeManager.processFee.t.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/fee-manager/FeeManager.processFee.t.sol new file mode 100644 index 00000000000..0e0ed8977bc --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/fee-manager/FeeManager.processFee.t.sol @@ -0,0 +1,492 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import {Common} from "../../../libraries/Common.sol"; +import "./BaseFeeManager.t.sol"; +import {IRewardManager} from "../../interfaces/IRewardManager.sol"; + +/** + * @title BaseFeeManagerTest + * @author Michael Fletcher + * @notice This contract will test the functionality of the feeManager processFee + */ +contract FeeManagerProcessFeeTest is BaseFeeManagerTest { + function setUp() public override { + super.setUp(); + } + + function test_nonAdminProxyUserCannotProcessFee() public { + //get the default payload + bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3)); + + //should revert as the user is not the owner + vm.expectRevert(UNAUTHORIZED_ERROR); + + //process the fee + ProcessFeeAsUser(payload, USER, address(link), 0, USER); + } + + function test_processFeeAsProxy() public { + //get the default payload + bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3)); + + //approve the link to be transferred from the from the subscriber to the rewardManager + approveLink(address(rewardManager), DEFAULT_REPORT_LINK_FEE, USER); + + //processing the fee will transfer the link from the user to the rewardManager + processFee(payload, USER, address(link), 0); + + //check the link has been transferred + assertEq(getLinkBalance(address(rewardManager)), DEFAULT_REPORT_LINK_FEE); + + //check the user has had the link fee deducted + assertEq(getLinkBalance(USER), DEFAULT_LINK_MINT_QUANTITY - DEFAULT_REPORT_LINK_FEE); + } + + function test_processFeeIfSubscriberIsSelf() public { + //get the default payload + bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3)); + + //expect a revert due to the feeManager being the subscriber + vm.expectRevert(INVALID_ADDRESS_ERROR); + + //process the fee will fail due to assertion + processFee(payload, address(feeManager), address(native), 0); + } + + function test_processFeeWithWithEmptyQuotePayload() public { + //get the default payload + bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3)); + + //expect a revert as the quote is invalid + vm.expectRevert(); + + //processing the fee will transfer the link by default + processFee(payload, USER, address(0), 0); + } + + function test_processFeeWithWithZeroQuotePayload() public { + //get the default payload + bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3)); + + //expect a revert as the quote is invalid + vm.expectRevert(INVALID_QUOTE_ERROR); + + //processing the fee will transfer the link by default + processFee(payload, USER, INVALID_ADDRESS, 0); + } + + function test_processFeeWithWithCorruptQuotePayload() public { + //get the default payload + bytes memory payload = abi.encode( + [DEFAULT_CONFIG_DIGEST, 0, 0], + getV3Report(DEFAULT_FEED_1_V3), + new bytes32[](1), + new bytes32[](1), + bytes32("") + ); + + //expect an evm revert as the quote is corrupt + vm.expectRevert(); + + //processing the fee will not withdraw anything as there is no fee to collect + processFee(payload, USER, address(link), 0); + } + + function test_processFeeDefaultReportsStillVerifiesWithEmptyQuote() public { + //get the default payload + bytes memory payload = getPayload(getV1Report(DEFAULT_FEED_1_V1)); + + //processing the fee will transfer the link from the user to the rewardManager + processFee(payload, USER, address(0), 0); + } + + function test_processFeeWithDefaultReportPayloadAndQuoteStillVerifies() public { + //get the default payload + bytes memory payload = getPayload(getV1Report(DEFAULT_FEED_1_V1)); + + //processing the fee will not withdraw anything as there is no fee to collect + processFee(payload, USER, address(link), 0); + } + + function test_processFeeNative() public { + //simulate a deposit of link for the conversion pool + mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE); + + //get the default payload + bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3)); + + //approve the native to be transferred from the user + approveNative(address(feeManager), DEFAULT_REPORT_NATIVE_FEE, USER); + + //processing the fee will transfer the native from the user to the feeManager + processFee(payload, USER, address(native), 0); + + //check the native has been transferred + assertEq(getNativeBalance(address(feeManager)), DEFAULT_REPORT_NATIVE_FEE); + + //check the link has been transferred to the rewardManager + assertEq(getLinkBalance(address(rewardManager)), DEFAULT_REPORT_LINK_FEE); + + //check the feeManager has had the link deducted, the remaining balance should be 0 + assertEq(getLinkBalance(address(feeManager)), 0); + + //check the subscriber has had the native deducted + assertEq(getNativeBalance(USER), DEFAULT_NATIVE_MINT_QUANTITY - DEFAULT_REPORT_NATIVE_FEE); + } + + function test_processFeeEmitsEventIfNotEnoughLink() public { + //simulate a deposit of half the link required for the fee + mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE / 2); + + //get the default payload + bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3)); + + //approve the native to be transferred from the user + approveNative(address(feeManager), DEFAULT_REPORT_NATIVE_FEE, USER); + + //expect an emit as there's not enough link + vm.expectEmit(); + + IRewardManager.FeePayment[] memory contractFees = new IRewardManager.FeePayment[](1); + contractFees[0] = IRewardManager.FeePayment(DEFAULT_CONFIG_DIGEST, uint192(DEFAULT_REPORT_LINK_FEE)); + + //emit the event that is expected to be emitted + emit InsufficientLink(contractFees); + + //processing the fee will transfer the native from the user to the feeManager + processFee(payload, USER, address(native), 0); + + //check the native has been transferred + assertEq(getNativeBalance(address(feeManager)), DEFAULT_REPORT_NATIVE_FEE); + + //check no link has been transferred to the rewardManager + assertEq(getLinkBalance(address(rewardManager)), 0); + assertEq(getLinkBalance(address(feeManager)), DEFAULT_REPORT_LINK_FEE / 2); + + //check the subscriber has had the native deducted + assertEq(getNativeBalance(USER), DEFAULT_NATIVE_MINT_QUANTITY - DEFAULT_REPORT_NATIVE_FEE); + } + + function test_processFeeWithUnwrappedNative() public { + //simulate a deposit of link for the conversion pool + mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE); + + //get the default payload + bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3)); + + //only the proxy or admin can call processFee, they will pass in the native value on the users behalf + processFee(payload, USER, address(native), DEFAULT_REPORT_NATIVE_FEE); + + //check the native has been transferred and converted to wrapped native + assertEq(getNativeBalance(address(feeManager)), DEFAULT_REPORT_NATIVE_FEE); + assertEq(getNativeUnwrappedBalance(address(feeManager)), 0); + + //check the link has been transferred to the rewardManager + assertEq(getLinkBalance(address(rewardManager)), DEFAULT_REPORT_LINK_FEE); + + //check the feeManager has had the link deducted, the remaining balance should be 0 + assertEq(getLinkBalance(address(feeManager)), 0); + + //check the subscriber has had the native deducted + assertEq(getNativeUnwrappedBalance(USER), DEFAULT_NATIVE_MINT_QUANTITY - DEFAULT_REPORT_NATIVE_FEE); + } + + function test_processFeeWithUnwrappedNativeShortFunds() public { + //simulate a deposit of link for the conversion pool + mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE); + + //get the default payload + bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3)); + + //expect a revert as not enough funds + vm.expectRevert(INVALID_DEPOSIT_ERROR); + + //only the proxy or admin can call processFee, they will pass in the native value on the users behalf + processFee(payload, USER, address(native), DEFAULT_REPORT_NATIVE_FEE - 1); + } + + function test_processFeeWithUnwrappedNativeLinkAddress() public { + //simulate a deposit of link for the conversion pool + mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE); + + //get the default payload + bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3)); + + //expect a revert as not enough funds + vm.expectRevert(INSUFFICIENT_ALLOWANCE_ERROR); + + //the change will be returned and the user will attempted to be billed in LINK + processFee(payload, USER, address(link), DEFAULT_REPORT_NATIVE_FEE - 1); + } + + function test_processFeeWithUnwrappedNativeLinkAddressExcessiveFee() public { + //approve the link to be transferred from the from the subscriber to the rewardManager + approveLink(address(rewardManager), DEFAULT_REPORT_LINK_FEE, PROXY); + + //get the default payload + bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3)); + + //call processFee from the proxy to test whether the funds are returned to the subscriber. In reality, the funds would be returned to the caller of the proxy. + processFee(payload, PROXY, address(link), DEFAULT_REPORT_NATIVE_FEE); + + //check the native unwrapped is no longer in the account + assertEq(getNativeBalance(address(feeManager)), 0); + assertEq(getNativeUnwrappedBalance(address(feeManager)), 0); + + //check the link has been transferred to the rewardManager + assertEq(getLinkBalance(address(rewardManager)), DEFAULT_REPORT_LINK_FEE); + + //check the feeManager has had the link deducted, the remaining balance should be 0 + assertEq(getLinkBalance(address(feeManager)), 0); + + //native should not be deducted + assertEq(getNativeUnwrappedBalance(PROXY), DEFAULT_NATIVE_MINT_QUANTITY); + } + + function test_processFeeWithUnwrappedNativeWithExcessiveFee() public { + //simulate a deposit of link for the conversion pool + mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE); + + //get the default payload + bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3)); + + //call processFee from the proxy to test whether the funds are returned to the subscriber. In reality, the funds would be returned to the caller of the proxy. + processFee(payload, PROXY, address(native), DEFAULT_REPORT_NATIVE_FEE * 2); + + //check the native has been transferred and converted to wrapped native + assertEq(getNativeBalance(address(feeManager)), DEFAULT_REPORT_NATIVE_FEE); + assertEq(getNativeUnwrappedBalance(address(feeManager)), 0); + + //check the link has been transferred to the rewardManager + assertEq(getLinkBalance(address(rewardManager)), DEFAULT_REPORT_LINK_FEE); + + //check the feeManager has had the link deducted, the remaining balance should be 0 + assertEq(getLinkBalance(address(feeManager)), 0); + + //check the subscriber has had the native deducted + assertEq(getNativeUnwrappedBalance(PROXY), DEFAULT_NATIVE_MINT_QUANTITY - DEFAULT_REPORT_NATIVE_FEE); + } + + function test_processFeeUsesCorrectDigest() public { + //get the default payload + bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3)); + + //approve the link to be transferred from the from the subscriber to the rewardManager + approveLink(address(rewardManager), DEFAULT_REPORT_LINK_FEE, USER); + + //processing the fee will transfer the link from the user to the rewardManager + processFee(payload, USER, address(link), 0); + + //check the link has been transferred + assertEq(getLinkBalance(address(rewardManager)), DEFAULT_REPORT_LINK_FEE); + + //check the user has had the link fee deducted + assertEq(getLinkBalance(USER), DEFAULT_LINK_MINT_QUANTITY - DEFAULT_REPORT_LINK_FEE); + + //check funds have been paid to the reward manager + assertEq(rewardManager.s_totalRewardRecipientFees(DEFAULT_CONFIG_DIGEST), DEFAULT_REPORT_LINK_FEE); + } + + function test_V1PayloadVerifies() public { + //replicate a default payload + bytes memory payload = abi.encode( + [DEFAULT_CONFIG_DIGEST, 0, 0], + getV2Report(DEFAULT_FEED_1_V1), + new bytes32[](1), + new bytes32[](1), + bytes32("") + ); + + //processing the fee will transfer the link from the user to the rewardManager + processFee(payload, USER, address(0), 0); + } + + function test_V2PayloadVerifies() public { + //get the default payload + bytes memory payload = getPayload(getV2Report(DEFAULT_FEED_1_V2)); + + //approve the link to be transferred from the from the subscriber to the rewardManager + approveLink(address(rewardManager), DEFAULT_REPORT_LINK_FEE, USER); + + //processing the fee will transfer the link from the user to the rewardManager + processFee(payload, USER, address(link), 0); + + //check the link has been transferred + assertEq(getLinkBalance(address(rewardManager)), DEFAULT_REPORT_LINK_FEE); + + //check the user has had the link fee deducted + assertEq(getLinkBalance(USER), DEFAULT_LINK_MINT_QUANTITY - DEFAULT_REPORT_LINK_FEE); + } + + function test_V2PayloadWithoutQuoteFails() public { + //get the default payload + bytes memory payload = getPayload(getV2Report(DEFAULT_FEED_1_V2)); + + //expect a revert as the quote is invalid + vm.expectRevert(); + + //processing the fee will transfer the link from the user to the rewardManager + processFee(payload, USER, address(0), 0); + } + + function test_V2PayloadWithoutZeroFee() public { + //get the default payload + bytes memory payload = getPayload(getV2Report(DEFAULT_FEED_1_V2)); + + //expect a revert as the quote is invalid + vm.expectRevert(); + + //processing the fee will transfer the link from the user to the rewardManager + processFee(payload, USER, address(link), 0); + } + + function test_processFeeWithInvalidReportVersionFailsToDecode() public { + bytes memory data = abi.encode(0x0000100000000000000000000000000000000000000000000000000000000000); + + //get the default payload + bytes memory payload = getPayload(data); + + //serialization will fail as there is no report to decode + vm.expectRevert(); + + //processing the fee will not withdraw anything as there is no fee to collect + processFee(payload, USER, address(link), 0); + } + + function test_processFeeWithZeroNativeNonZeroLinkWithNativeQuote() public { + //get the default payload + bytes memory payload = getPayload( + getV3ReportWithCustomExpiryAndFee(DEFAULT_FEED_1_V3, block.timestamp, DEFAULT_REPORT_LINK_FEE, 0) + ); + + //call processFee should not revert as the fee is 0 + processFee(payload, PROXY, address(native), 0); + } + + function test_processFeeWithZeroNativeNonZeroLinkWithLinkQuote() public { + //get the default payload + bytes memory payload = getPayload( + getV3ReportWithCustomExpiryAndFee(DEFAULT_FEED_1_V3, block.timestamp, DEFAULT_REPORT_LINK_FEE, 0) + ); + + //approve the link to be transferred from the from the subscriber to the rewardManager + approveLink(address(rewardManager), DEFAULT_REPORT_LINK_FEE, USER); + + //processing the fee will transfer the link to the rewardManager from the user + processFee(payload, USER, address(link), 0); + + //check the link has been transferred + assertEq(getLinkBalance(address(rewardManager)), DEFAULT_REPORT_LINK_FEE); + + //check the user has had the link fee deducted + assertEq(getLinkBalance(USER), DEFAULT_LINK_MINT_QUANTITY - DEFAULT_REPORT_LINK_FEE); + } + + function test_processFeeWithZeroLinkNonZeroNativeWithNativeQuote() public { + //simulate a deposit of link for the conversion pool + mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE); + + //get the default payload + bytes memory payload = getPayload( + getV3ReportWithCustomExpiryAndFee(DEFAULT_FEED_1_V3, block.timestamp, 0, DEFAULT_REPORT_NATIVE_FEE) + ); + + //approve the native to be transferred from the user + approveNative(address(feeManager), DEFAULT_REPORT_NATIVE_FEE, USER); + + //processing the fee will transfer the native from the user to the feeManager + processFee(payload, USER, address(native), 0); + + //check the native has been transferred + assertEq(getNativeBalance(address(feeManager)), DEFAULT_REPORT_NATIVE_FEE); + + //check no link has been transferred to the rewardManager + assertEq(getLinkBalance(address(rewardManager)), 0); + + //check the feeManager has had no link deducted + assertEq(getLinkBalance(address(feeManager)), DEFAULT_REPORT_LINK_FEE); + + //check the subscriber has had the native deducted + assertEq(getNativeBalance(USER), DEFAULT_NATIVE_MINT_QUANTITY - DEFAULT_REPORT_NATIVE_FEE); + } + + function test_processFeeWithZeroLinkNonZeroNativeWithLinkQuote() public { + //get the default payload + bytes memory payload = getPayload( + getV3ReportWithCustomExpiryAndFee(DEFAULT_FEED_1_V3, block.timestamp, 0, DEFAULT_REPORT_NATIVE_FEE) + ); + + //call processFee should not revert as the fee is 0 + processFee(payload, USER, address(link), 0); + } + + function test_processFeeWithZeroNativeNonZeroLinkReturnsChange() public { + //get the default payload + bytes memory payload = getPayload( + getV3ReportWithCustomExpiryAndFee(DEFAULT_FEED_1_V3, block.timestamp, 0, DEFAULT_REPORT_NATIVE_FEE) + ); + + //call processFee should not revert as the fee is 0 + processFee(payload, USER, address(link), DEFAULT_REPORT_NATIVE_FEE); + + //check the change has been returned + assertEq(USER.balance, DEFAULT_NATIVE_MINT_QUANTITY); + } + + function test_V1PayloadVerifiesAndReturnsChange() public { + //emulate a V1 payload with no quote + bytes memory payload = getPayload(getV1Report(DEFAULT_FEED_1_V1)); + + processFee(payload, USER, address(0), DEFAULT_REPORT_NATIVE_FEE); + + //Fee manager should not contain any native + assertEq(address(feeManager).balance, 0); + assertEq(getNativeBalance(address(feeManager)), 0); + + //check the unused native passed in is returned + assertEq(USER.balance, DEFAULT_NATIVE_MINT_QUANTITY); + } + + function test_processFeeWithDiscountEmitsEvent() public { + //simulate a deposit of link for the conversion pool + mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE); + + //set the subscriber discount to 50% + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), FEE_SCALAR / 2, ADMIN); + + //approve the native to be transferred from the user + approveNative(address(feeManager), DEFAULT_REPORT_NATIVE_FEE / 2, USER); + + //get the default payload + bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3)); + + Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + Common.Asset memory reward = getReward(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + uint256 appliedDiscount = getAppliedDiscount(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + vm.expectEmit(); + + emit DiscountApplied(DEFAULT_CONFIG_DIGEST, USER, fee, reward, appliedDiscount); + + //call processFee should not revert as the fee is 0 + processFee(payload, USER, address(native), 0); + } + + function test_processFeeWithNoDiscountDoesNotEmitEvent() public { + //simulate a deposit of link for the conversion pool + mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE); + + //approve the native to be transferred from the user + approveNative(address(feeManager), DEFAULT_REPORT_NATIVE_FEE, USER); + + //get the default payload + bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3)); + + //call processFee should not revert as the fee is 0 + processFee(payload, USER, address(native), 0); + + //no logs should have been emitted + assertEq(vm.getRecordedLogs().length, 0); + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/fee-manager/FeeManager.processFeeBulk.t.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/fee-manager/FeeManager.processFeeBulk.t.sol new file mode 100644 index 00000000000..fa77b98d3cf --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/fee-manager/FeeManager.processFeeBulk.t.sol @@ -0,0 +1,193 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import "./BaseFeeManager.t.sol"; +import {IRewardManager} from "../../interfaces/IRewardManager.sol"; + +/** + * @title BaseFeeManagerTest + * @author Michael Fletcher + * @notice This contract will test the functionality of the feeManager processFee + */ +contract FeeManagerProcessFeeTest is BaseFeeManagerTest { + uint256 internal constant NUMBER_OF_REPORTS = 5; + + function setUp() public override { + super.setUp(); + } + + function test_processMultipleLinkReports() public { + bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3)); + + bytes[] memory payloads = new bytes[](NUMBER_OF_REPORTS); + for (uint256 i = 0; i < NUMBER_OF_REPORTS; ++i) { + payloads[i] = payload; + } + + approveLink(address(rewardManager), DEFAULT_REPORT_LINK_FEE * NUMBER_OF_REPORTS, USER); + + processFee(payloads, USER, address(link), DEFAULT_NATIVE_MINT_QUANTITY); + + assertEq(getLinkBalance(address(rewardManager)), DEFAULT_REPORT_LINK_FEE * NUMBER_OF_REPORTS); + assertEq(getLinkBalance(address(feeManager)), 0); + assertEq(getLinkBalance(USER), DEFAULT_LINK_MINT_QUANTITY - DEFAULT_REPORT_LINK_FEE * NUMBER_OF_REPORTS); + + //the subscriber (user) should receive funds back and not the proxy, although when live the proxy will forward the funds sent and not cover it seen here + assertEq(USER.balance, DEFAULT_NATIVE_MINT_QUANTITY); + assertEq(PROXY.balance, DEFAULT_NATIVE_MINT_QUANTITY); + } + + function test_processMultipleWrappedNativeReports() public { + mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE * NUMBER_OF_REPORTS + 1); + + bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3)); + + bytes[] memory payloads = new bytes[](NUMBER_OF_REPORTS); + for (uint256 i; i < NUMBER_OF_REPORTS; ++i) { + payloads[i] = payload; + } + + approveNative(address(feeManager), DEFAULT_REPORT_NATIVE_FEE * NUMBER_OF_REPORTS, USER); + + processFee(payloads, USER, address(native), 0); + + assertEq(getNativeBalance(address(feeManager)), DEFAULT_REPORT_NATIVE_FEE * NUMBER_OF_REPORTS); + assertEq(getLinkBalance(address(rewardManager)), DEFAULT_REPORT_LINK_FEE * NUMBER_OF_REPORTS); + assertEq(getLinkBalance(address(feeManager)), 1); + assertEq(getNativeBalance(USER), DEFAULT_NATIVE_MINT_QUANTITY - DEFAULT_REPORT_NATIVE_FEE * NUMBER_OF_REPORTS); + } + + function test_processMultipleUnwrappedNativeReports() public { + mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE * NUMBER_OF_REPORTS + 1); + + bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3)); + + bytes[] memory payloads = new bytes[](NUMBER_OF_REPORTS); + for (uint256 i; i < NUMBER_OF_REPORTS; ++i) { + payloads[i] = payload; + } + + processFee(payloads, USER, address(native), DEFAULT_REPORT_NATIVE_FEE * NUMBER_OF_REPORTS * 2); + + assertEq(getNativeBalance(address(feeManager)), DEFAULT_REPORT_NATIVE_FEE * NUMBER_OF_REPORTS); + assertEq(getLinkBalance(address(rewardManager)), DEFAULT_REPORT_LINK_FEE * NUMBER_OF_REPORTS); + assertEq(getLinkBalance(address(feeManager)), 1); + + assertEq(PROXY.balance, DEFAULT_NATIVE_MINT_QUANTITY); + assertEq(USER.balance, DEFAULT_NATIVE_MINT_QUANTITY - DEFAULT_REPORT_NATIVE_FEE * NUMBER_OF_REPORTS); + } + + function test_processV1V2V3Reports() public { + mintLink(address(feeManager), 1); + + bytes memory payloadV1 = abi.encode( + [DEFAULT_CONFIG_DIGEST, 0, 0], + getV1Report(DEFAULT_FEED_1_V1), + new bytes32[](1), + new bytes32[](1), + bytes32("") + ); + + bytes memory linkPayloadV2 = getPayload(getV2Report(DEFAULT_FEED_1_V2)); + bytes memory linkPayloadV3 = getPayload(getV3Report(DEFAULT_FEED_1_V3)); + + bytes[] memory payloads = new bytes[](5); + payloads[0] = payloadV1; + payloads[1] = linkPayloadV2; + payloads[2] = linkPayloadV2; + payloads[3] = linkPayloadV3; + payloads[4] = linkPayloadV3; + + approveLink(address(rewardManager), DEFAULT_REPORT_LINK_FEE * 4, USER); + + processFee(payloads, USER, address(link), 0); + + assertEq(getNativeBalance(address(feeManager)), 0); + assertEq(getLinkBalance(address(rewardManager)), DEFAULT_REPORT_LINK_FEE * 4); + assertEq(getLinkBalance(address(feeManager)), 1); + + assertEq(getLinkBalance(USER), DEFAULT_LINK_MINT_QUANTITY - DEFAULT_REPORT_LINK_FEE * 4); + assertEq(getNativeBalance(USER), DEFAULT_NATIVE_MINT_QUANTITY - 0); + } + + function test_processV1V2V3ReportsWithUnwrapped() public { + mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE * 4 + 1); + + bytes memory payloadV1 = abi.encode( + [DEFAULT_CONFIG_DIGEST, 0, 0], + getV1Report(DEFAULT_FEED_1_V1), + new bytes32[](1), + new bytes32[](1), + bytes32("") + ); + + bytes memory nativePayloadV2 = getPayload(getV2Report(DEFAULT_FEED_1_V2)); + bytes memory nativePayloadV3 = getPayload(getV3Report(DEFAULT_FEED_1_V3)); + + bytes[] memory payloads = new bytes[](5); + payloads[0] = payloadV1; + payloads[1] = nativePayloadV2; + payloads[2] = nativePayloadV2; + payloads[3] = nativePayloadV3; + payloads[4] = nativePayloadV3; + + processFee(payloads, USER, address(native), DEFAULT_REPORT_NATIVE_FEE * 4); + + assertEq(getNativeBalance(address(feeManager)), DEFAULT_REPORT_NATIVE_FEE * 4); + assertEq(getLinkBalance(address(rewardManager)), DEFAULT_REPORT_LINK_FEE * 4); + assertEq(getLinkBalance(address(feeManager)), 1); + + assertEq(USER.balance, DEFAULT_NATIVE_MINT_QUANTITY - DEFAULT_REPORT_NATIVE_FEE * 4); + assertEq(PROXY.balance, DEFAULT_NATIVE_MINT_QUANTITY); + } + + function test_processMultipleV1Reports() public { + bytes memory payload = abi.encode( + [DEFAULT_CONFIG_DIGEST, 0, 0], + getV1Report(DEFAULT_FEED_1_V1), + new bytes32[](1), + new bytes32[](1), + bytes32("") + ); + + bytes[] memory payloads = new bytes[](NUMBER_OF_REPORTS); + for (uint256 i = 0; i < NUMBER_OF_REPORTS; ++i) { + payloads[i] = payload; + } + + processFee(payloads, USER, address(native), DEFAULT_REPORT_NATIVE_FEE * 5); + + assertEq(USER.balance, DEFAULT_NATIVE_MINT_QUANTITY); + assertEq(PROXY.balance, DEFAULT_NATIVE_MINT_QUANTITY); + } + + function test_eventIsEmittedIfNotEnoughLink() public { + bytes memory nativePayload = getPayload(getV3Report(DEFAULT_FEED_1_V3)); + + bytes[] memory payloads = new bytes[](5); + payloads[0] = nativePayload; + payloads[1] = nativePayload; + payloads[2] = nativePayload; + payloads[3] = nativePayload; + payloads[4] = nativePayload; + + approveNative(address(feeManager), DEFAULT_REPORT_NATIVE_FEE * 5, USER); + + IRewardManager.FeePayment[] memory payments = new IRewardManager.FeePayment[](5); + payments[0] = IRewardManager.FeePayment(DEFAULT_CONFIG_DIGEST, uint192(DEFAULT_REPORT_LINK_FEE)); + payments[1] = IRewardManager.FeePayment(DEFAULT_CONFIG_DIGEST, uint192(DEFAULT_REPORT_LINK_FEE)); + payments[2] = IRewardManager.FeePayment(DEFAULT_CONFIG_DIGEST, uint192(DEFAULT_REPORT_LINK_FEE)); + payments[3] = IRewardManager.FeePayment(DEFAULT_CONFIG_DIGEST, uint192(DEFAULT_REPORT_LINK_FEE)); + payments[4] = IRewardManager.FeePayment(DEFAULT_CONFIG_DIGEST, uint192(DEFAULT_REPORT_LINK_FEE)); + + vm.expectEmit(); + + emit InsufficientLink(payments); + + processFee(payloads, USER, address(native), 0); + + assertEq(getNativeBalance(address(feeManager)), DEFAULT_REPORT_NATIVE_FEE * 5); + assertEq(getNativeBalance(USER), DEFAULT_NATIVE_MINT_QUANTITY - DEFAULT_REPORT_NATIVE_FEE * 5); + assertEq(getLinkBalance(USER), DEFAULT_LINK_MINT_QUANTITY); + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/gas/Gas_VerifierTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/gas/Gas_VerifierTest.t.sol new file mode 100644 index 00000000000..ee8ba4c3e34 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/gas/Gas_VerifierTest.t.sol @@ -0,0 +1,230 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import {BaseTest, BaseTestWithConfiguredVerifierAndFeeManager} from "../verifier/BaseVerifierTest.t.sol"; +import {SimpleWriteAccessController} from "../../../../shared/access/SimpleWriteAccessController.sol"; +import {Common} from "../../../libraries/Common.sol"; +import {IRewardManager} from "../../interfaces/IRewardManager.sol"; + +contract Verifier_setConfig is BaseTest { + address[] internal s_signerAddrs; + + function setUp() public override { + BaseTest.setUp(); + Signer[] memory signers = _getSigners(MAX_ORACLES); + s_signerAddrs = _getSignerAddresses(signers); + s_verifierProxy.initializeVerifier(address(s_verifier)); + } + + function testSetConfigSuccess_gas() public { + s_verifier.setConfig( + FEED_ID, + s_signerAddrs, + s_offchaintransmitters, + FAULT_TOLERANCE, + bytes(""), + VERIFIER_VERSION, + bytes(""), + new Common.AddressAndWeight[](0) + ); + } +} + +contract Verifier_verifyWithFee is BaseTestWithConfiguredVerifierAndFeeManager { + uint256 internal constant DEFAULT_LINK_MINT_QUANTITY = 100 ether; + uint256 internal constant DEFAULT_NATIVE_MINT_QUANTITY = 100 ether; + + function setUp() public virtual override { + super.setUp(); + + //mint some link and eth to warm the storage + link.mint(address(rewardManager), DEFAULT_LINK_MINT_QUANTITY); + native.mint(address(feeManager), DEFAULT_NATIVE_MINT_QUANTITY); + + //warm the rewardManager + link.mint(address(this), DEFAULT_NATIVE_MINT_QUANTITY); + _approveLink(address(rewardManager), DEFAULT_REPORT_LINK_FEE, address(this)); + (, , bytes32 latestConfigDigest) = s_verifier.latestConfigDetails(FEED_ID); + + //mint some tokens to the user + link.mint(USER, DEFAULT_LINK_MINT_QUANTITY); + native.mint(USER, DEFAULT_NATIVE_MINT_QUANTITY); + vm.deal(USER, DEFAULT_NATIVE_MINT_QUANTITY); + + //mint some link tokens to the feeManager pool + link.mint(address(feeManager), DEFAULT_REPORT_LINK_FEE); + + //approve funds prior to test + _approveLink(address(rewardManager), DEFAULT_REPORT_LINK_FEE, USER); + _approveNative(address(feeManager), DEFAULT_REPORT_NATIVE_FEE, USER); + + IRewardManager.FeePayment[] memory payments = new IRewardManager.FeePayment[](1); + payments[0] = IRewardManager.FeePayment(latestConfigDigest, uint192(DEFAULT_REPORT_LINK_FEE)); + + changePrank(address(feeManager)); + rewardManager.onFeePaid(payments, address(this)); + + changePrank(USER); + } + + function testVerifyProxyWithLinkFeeSuccess_gas() public { + bytes memory signedLinkPayload = _generateV3EncodedBlob( + _generateV3Report(), + _generateReportContext(v3ConfigDigest), + _getSigners(FAULT_TOLERANCE + 1) + ); + + s_verifierProxy.verify(signedLinkPayload, abi.encode(link)); + } + + function testVerifyProxyWithNativeFeeSuccess_gas() public { + bytes memory signedNativePayload = _generateV3EncodedBlob( + _generateV3Report(), + _generateReportContext(v3ConfigDigest), + _getSigners(FAULT_TOLERANCE + 1) + ); + + s_verifierProxy.verify(signedNativePayload, abi.encode(native)); + } +} + +contract Verifier_bulkVerifyWithFee is BaseTestWithConfiguredVerifierAndFeeManager { + uint256 internal constant DEFAULT_LINK_MINT_QUANTITY = 100 ether; + uint256 internal constant DEFAULT_NATIVE_MINT_QUANTITY = 100 ether; + uint256 internal constant NUMBER_OF_REPORTS_TO_VERIFY = 5; + + function setUp() public virtual override { + super.setUp(); + + //mint some link and eth to warm the storage + link.mint(address(rewardManager), DEFAULT_LINK_MINT_QUANTITY); + native.mint(address(feeManager), DEFAULT_NATIVE_MINT_QUANTITY); + + //warm the rewardManager + link.mint(address(this), DEFAULT_NATIVE_MINT_QUANTITY); + _approveLink(address(rewardManager), DEFAULT_REPORT_LINK_FEE, address(this)); + (, , bytes32 latestConfigDigest) = s_verifier.latestConfigDetails(FEED_ID); + + //mint some tokens to the user + link.mint(USER, DEFAULT_LINK_MINT_QUANTITY); + native.mint(USER, DEFAULT_NATIVE_MINT_QUANTITY); + vm.deal(USER, DEFAULT_NATIVE_MINT_QUANTITY); + + //mint some link tokens to the feeManager pool + link.mint(address(feeManager), DEFAULT_REPORT_LINK_FEE * NUMBER_OF_REPORTS_TO_VERIFY); + + //approve funds prior to test + _approveLink(address(rewardManager), DEFAULT_REPORT_LINK_FEE * NUMBER_OF_REPORTS_TO_VERIFY, USER); + _approveNative(address(feeManager), DEFAULT_REPORT_NATIVE_FEE * NUMBER_OF_REPORTS_TO_VERIFY, USER); + + IRewardManager.FeePayment[] memory payments = new IRewardManager.FeePayment[](1); + payments[0] = IRewardManager.FeePayment(latestConfigDigest, uint192(DEFAULT_REPORT_LINK_FEE)); + + changePrank(address(feeManager)); + rewardManager.onFeePaid(payments, address(this)); + + changePrank(USER); + } + + function testBulkVerifyProxyWithLinkFeeSuccess_gas() public { + bytes memory signedLinkPayload = _generateV3EncodedBlob( + _generateV3Report(), + _generateReportContext(v3ConfigDigest), + _getSigners(FAULT_TOLERANCE + 1) + ); + + bytes[] memory signedLinkPayloads = new bytes[](NUMBER_OF_REPORTS_TO_VERIFY); + for (uint256 i = 0; i < NUMBER_OF_REPORTS_TO_VERIFY; i++) { + signedLinkPayloads[i] = signedLinkPayload; + } + + s_verifierProxy.verifyBulk(signedLinkPayloads, abi.encode(link)); + } + + function testBulkVerifyProxyWithNativeFeeSuccess_gas() public { + bytes memory signedNativePayload = _generateV3EncodedBlob( + _generateV3Report(), + _generateReportContext(v3ConfigDigest), + _getSigners(FAULT_TOLERANCE + 1) + ); + + bytes[] memory signedNativePayloads = new bytes[](NUMBER_OF_REPORTS_TO_VERIFY); + for (uint256 i = 0; i < NUMBER_OF_REPORTS_TO_VERIFY; i++) { + signedNativePayloads[i] = signedNativePayload; + } + + s_verifierProxy.verifyBulk(signedNativePayloads, abi.encode(native)); + } +} + +contract Verifier_verify is BaseTestWithConfiguredVerifierAndFeeManager { + bytes internal s_signedReport; + bytes32 internal s_configDigest; + + function setUp() public override { + BaseTestWithConfiguredVerifierAndFeeManager.setUp(); + BaseTest.V1Report memory s_testReportOne = _createV1Report( + FEED_ID, + OBSERVATIONS_TIMESTAMP, + MEDIAN, + BID, + ASK, + BLOCKNUMBER_UPPER_BOUND, + blockhash(BLOCKNUMBER_UPPER_BOUND), + BLOCKNUMBER_LOWER_BOUND, + uint32(block.timestamp) + ); + (, , s_configDigest) = s_verifier.latestConfigDetails(FEED_ID); + bytes32[3] memory reportContext; + reportContext[0] = s_configDigest; + reportContext[1] = bytes32(abi.encode(uint32(5), uint8(1))); + s_signedReport = _generateV1EncodedBlob(s_testReportOne, reportContext, _getSigners(FAULT_TOLERANCE + 1)); + } + + function testVerifySuccess_gas() public { + changePrank(address(s_verifierProxy)); + + s_verifier.verify(s_signedReport, msg.sender); + } + + function testVerifyProxySuccess_gas() public { + s_verifierProxy.verify(s_signedReport, abi.encode(native)); + } +} + +contract Verifier_accessControlledVerify is BaseTestWithConfiguredVerifierAndFeeManager { + bytes internal s_signedReport; + bytes32 internal s_configDigest; + SimpleWriteAccessController s_accessController; + + address internal constant CLIENT = address(9000); + address internal constant ACCESS_CONTROLLER_ADDR = address(10000); + + function setUp() public override { + BaseTestWithConfiguredVerifierAndFeeManager.setUp(); + BaseTest.V1Report memory s_testReportOne = _createV1Report( + FEED_ID, + OBSERVATIONS_TIMESTAMP, + MEDIAN, + BID, + ASK, + BLOCKNUMBER_UPPER_BOUND, + blockhash(BLOCKNUMBER_UPPER_BOUND), + BLOCKNUMBER_LOWER_BOUND, + uint32(block.timestamp) + ); + (, , s_configDigest) = s_verifier.latestConfigDetails(FEED_ID); + bytes32[3] memory reportContext; + reportContext[0] = s_configDigest; + reportContext[1] = bytes32(abi.encode(uint32(5), uint8(1))); + s_signedReport = _generateV1EncodedBlob(s_testReportOne, reportContext, _getSigners(FAULT_TOLERANCE + 1)); + s_accessController = new SimpleWriteAccessController(); + s_verifierProxy.setAccessController(s_accessController); + s_accessController.addAccess(CLIENT); + } + + function testVerifyWithAccessControl_gas() public { + changePrank(CLIENT); + s_verifierProxy.verify(s_signedReport, abi.encode(native)); + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/mocks/ErroredVerifier.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/mocks/ErroredVerifier.sol new file mode 100644 index 00000000000..e9dcd589e23 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/mocks/ErroredVerifier.sol @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import {IVerifier} from "../../interfaces/IVerifier.sol"; +import {Common} from "../../../libraries/Common.sol"; + +contract ErroredVerifier is IVerifier { + function supportsInterface(bytes4 interfaceId) public pure override returns (bool) { + return interfaceId == this.verify.selector; + } + + //define each of the errors thrown in the revert below + + error FailedToVerify(); + error FailedToSetConfig(); + error FailedToActivateConfig(); + error FailedToDeactivateConfig(); + error FailedToActivateFeed(); + error FailedToDeactivateFeed(); + error FailedToGetLatestConfigDigestAndEpoch(); + error FailedToGetLatestConfigDetails(); + + function verify( + bytes memory, + /** + * signedReport* + */ + address + ) + external + pure + override + returns ( + /** + * sender* + */ + bytes memory + ) + { + revert FailedToVerify(); + } + + function setConfig( + bytes32, + address[] memory, + bytes32[] memory, + uint8, + bytes memory, + uint64, + bytes memory, + Common.AddressAndWeight[] memory + ) external pure override { + revert FailedToSetConfig(); + } + + function setConfigFromSource( + bytes32, + uint256, + address, + uint32, + address[] memory, + bytes32[] memory, + uint8, + bytes memory, + uint64, + bytes memory, + Common.AddressAndWeight[] memory + ) external pure override { + revert FailedToSetConfig(); + } + + function activateConfig(bytes32, bytes32) external pure { + revert FailedToActivateConfig(); + } + + function deactivateConfig(bytes32, bytes32) external pure { + revert FailedToDeactivateConfig(); + } + + function activateFeed(bytes32) external pure { + revert FailedToActivateFeed(); + } + + function deactivateFeed(bytes32) external pure { + revert FailedToDeactivateFeed(); + } + + function latestConfigDigestAndEpoch(bytes32) external pure override returns (bool, bytes32, uint32) { + revert FailedToGetLatestConfigDigestAndEpoch(); + } + + function latestConfigDetails(bytes32) external pure override returns (uint32, uint32, bytes32) { + revert FailedToGetLatestConfigDetails(); + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/mocks/ExposedVerifier.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/mocks/ExposedVerifier.sol new file mode 100644 index 00000000000..1c004bf3846 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/mocks/ExposedVerifier.sol @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.19; + +// ExposedVerifier exposes certain internal Verifier +// methods/structures so that golang code can access them, and we get +// reliable type checking on their usage +contract ExposedVerifier { + constructor() {} + + function _configDigestFromConfigData( + bytes32 feedId, + uint256 chainId, + address contractAddress, + uint64 configCount, + address[] memory signers, + bytes32[] memory offchainTransmitters, + uint8 f, + bytes memory onchainConfig, + uint64 offchainConfigVersion, + bytes memory offchainConfig + ) internal pure returns (bytes32) { + uint256 h = uint256( + keccak256( + abi.encode( + feedId, + chainId, + contractAddress, + configCount, + signers, + offchainTransmitters, + f, + onchainConfig, + offchainConfigVersion, + offchainConfig + ) + ) + ); + uint256 prefixMask = type(uint256).max << (256 - 16); // 0xFFFF00..00 + uint256 prefix = 0x0006 << (256 - 16); // 0x000600..00 + return bytes32((prefix & prefixMask) | (h & ~prefixMask)); + } + + function exposedConfigDigestFromConfigData( + bytes32 _feedId, + uint256 _chainId, + address _contractAddress, + uint64 _configCount, + address[] memory _signers, + bytes32[] memory _offchainTransmitters, + uint8 _f, + bytes calldata _onchainConfig, + uint64 _encodedConfigVersion, + bytes memory _encodedConfig + ) public pure returns (bytes32) { + return + _configDigestFromConfigData( + _feedId, + _chainId, + _contractAddress, + _configCount, + _signers, + _offchainTransmitters, + _f, + _onchainConfig, + _encodedConfigVersion, + _encodedConfig + ); + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/mocks/FeeManagerProxy.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/mocks/FeeManagerProxy.sol new file mode 100644 index 00000000000..9abb4c50c29 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/mocks/FeeManagerProxy.sol @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.19; + +import {IFeeManager} from "../../interfaces/IFeeManager.sol"; + +contract FeeManagerProxy { + IFeeManager internal s_feeManager; + + function processFee(bytes calldata payload, bytes calldata parameterPayload) public payable { + s_feeManager.processFee{value: msg.value}(payload, parameterPayload, msg.sender); + } + + function processFeeBulk(bytes[] calldata payloads, bytes calldata parameterPayload) public payable { + s_feeManager.processFeeBulk{value: msg.value}(payloads, parameterPayload, msg.sender); + } + + function setFeeManager(IFeeManager feeManager) public { + s_feeManager = feeManager; + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/reward-manager/BaseRewardManager.t.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/reward-manager/BaseRewardManager.t.sol new file mode 100644 index 00000000000..b002342b411 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/reward-manager/BaseRewardManager.t.sol @@ -0,0 +1,262 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import {Test} from "forge-std/Test.sol"; +import {ERC20Mock} from "../../../../vendor/openzeppelin-solidity/v4.8.3/contracts/mocks/ERC20Mock.sol"; +import {RewardManager} from "../../RewardManager.sol"; +import {Common} from "../../../libraries/Common.sol"; +import {IRewardManager} from "../../interfaces/IRewardManager.sol"; + +/** + * @title BaseRewardManagerTest + * @author Michael Fletcher + * @notice Base class for all reward manager tests + * @dev This contract is intended to be inherited from and not used directly. It contains functionality to setup a primary and secondary pool + */ +contract BaseRewardManagerTest is Test { + //contracts + ERC20Mock internal asset; + ERC20Mock internal unsupported; + RewardManager internal rewardManager; + + //default address for unregistered recipient + address internal constant INVALID_ADDRESS = address(0); + //contract owner + address internal constant ADMIN = address(uint160(uint256(keccak256("ADMIN")))); + //address to represent verifier contract + address internal constant FEE_MANAGER = address(uint160(uint256(keccak256("FEE_MANAGER")))); + //a general user + address internal constant USER = address(uint160(uint256(keccak256("USER")))); + + //default recipients configured in reward manager + address internal constant DEFAULT_RECIPIENT_1 = address(uint160(uint256(keccak256("DEFAULT_RECIPIENT_1")))); + address internal constant DEFAULT_RECIPIENT_2 = address(uint160(uint256(keccak256("DEFAULT_RECIPIENT_2")))); + address internal constant DEFAULT_RECIPIENT_3 = address(uint160(uint256(keccak256("DEFAULT_RECIPIENT_3")))); + address internal constant DEFAULT_RECIPIENT_4 = address(uint160(uint256(keccak256("DEFAULT_RECIPIENT_4")))); + address internal constant DEFAULT_RECIPIENT_5 = address(uint160(uint256(keccak256("DEFAULT_RECIPIENT_5")))); + address internal constant DEFAULT_RECIPIENT_6 = address(uint160(uint256(keccak256("DEFAULT_RECIPIENT_6")))); + address internal constant DEFAULT_RECIPIENT_7 = address(uint160(uint256(keccak256("DEFAULT_RECIPIENT_7")))); + + //additional recipients not in the reward manager + address internal constant DEFAULT_RECIPIENT_8 = address(uint160(uint256(keccak256("DEFAULT_RECIPIENT_8")))); + address internal constant DEFAULT_RECIPIENT_9 = address(uint160(uint256(keccak256("DEFAULT_RECIPIENT_9")))); + + //two pools should be enough to test all edge cases + bytes32 internal constant PRIMARY_POOL_ID = keccak256("primary_pool"); + bytes32 internal constant SECONDARY_POOL_ID = keccak256("secondary_pool"); + bytes32 internal constant INVALID_POOL_ID = keccak256("invalid_pool"); + bytes32 internal constant ZERO_POOL_ID = bytes32(0); + + //convenience arrays of all pool combinations used for testing + bytes32[] internal PRIMARY_POOL_ARRAY = [PRIMARY_POOL_ID]; + bytes32[] internal SECONDARY_POOL_ARRAY = [SECONDARY_POOL_ID]; + bytes32[] internal ALL_POOLS = [PRIMARY_POOL_ID, SECONDARY_POOL_ID]; + + //erc20 config + uint256 internal constant DEFAULT_MINT_QUANTITY = 100 ether; + + //reward scalar (this should match the const in the contract) + uint64 internal constant POOL_SCALAR = 1e18; + uint64 internal constant ONE_PERCENT = POOL_SCALAR / 100; + uint64 internal constant FIFTY_PERCENT = POOL_SCALAR / 2; + uint64 internal constant TEN_PERCENT = POOL_SCALAR / 10; + + //the selector for each error + bytes4 internal immutable UNAUTHORIZED_ERROR_SELECTOR = RewardManager.Unauthorized.selector; + bytes4 internal immutable INVALID_ADDRESS_ERROR_SELECTOR = RewardManager.InvalidAddress.selector; + bytes4 internal immutable INVALID_WEIGHT_ERROR_SELECTOR = RewardManager.InvalidWeights.selector; + bytes4 internal immutable INVALID_POOL_ID_ERROR_SELECTOR = RewardManager.InvalidPoolId.selector; + bytes internal constant ONLY_CALLABLE_BY_OWNER_ERROR = "Only callable by owner"; + bytes4 internal immutable INVALID_POOL_LENGTH_SELECTOR = RewardManager.InvalidPoolLength.selector; + + // Events emitted within the reward manager + event RewardRecipientsUpdated(bytes32 indexed poolId, Common.AddressAndWeight[] newRewardRecipients); + event RewardsClaimed(bytes32 indexed poolId, address indexed recipient, uint192 quantity); + event FeeManagerUpdated(address newProxyAddress); + event FeePaid(IRewardManager.FeePayment[] payments, address payee); + + function setUp() public virtual { + //change to admin user + vm.startPrank(ADMIN); + + //init required contracts + _initializeERC20Contracts(); + _initializeRewardManager(); + } + + function _initializeERC20Contracts() internal { + //create the contracts + asset = new ERC20Mock("ASSET", "AST", ADMIN, 0); + unsupported = new ERC20Mock("UNSUPPORTED", "UNS", ADMIN, 0); + + //mint some tokens to the admin + asset.mint(ADMIN, DEFAULT_MINT_QUANTITY); + unsupported.mint(ADMIN, DEFAULT_MINT_QUANTITY); + + //mint some tokens to the user + asset.mint(FEE_MANAGER, DEFAULT_MINT_QUANTITY); + unsupported.mint(FEE_MANAGER, DEFAULT_MINT_QUANTITY); + } + + function _initializeRewardManager() internal { + //create the contract + rewardManager = new RewardManager(address(asset)); + + rewardManager.setFeeManager(FEE_MANAGER); + } + + function createPrimaryPool() public { + rewardManager.setRewardRecipients(PRIMARY_POOL_ID, getPrimaryRecipients()); + } + + function createSecondaryPool() public { + rewardManager.setRewardRecipients(SECONDARY_POOL_ID, getSecondaryRecipients()); + } + + //override this to test variations of different recipients. changing this function will require existing tests to be updated as constants are hardcoded to be explicit + function getPrimaryRecipients() public virtual returns (Common.AddressAndWeight[] memory) { + //array of recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](4); + + //init each recipient with even weights. 2500 = 25% of pool + recipients[0] = Common.AddressAndWeight(DEFAULT_RECIPIENT_1, POOL_SCALAR / 4); + recipients[1] = Common.AddressAndWeight(DEFAULT_RECIPIENT_2, POOL_SCALAR / 4); + recipients[2] = Common.AddressAndWeight(DEFAULT_RECIPIENT_3, POOL_SCALAR / 4); + recipients[3] = Common.AddressAndWeight(DEFAULT_RECIPIENT_4, POOL_SCALAR / 4); + + return recipients; + } + + function getPrimaryRecipientAddresses() public pure returns (address[] memory) { + //array of recipients + address[] memory recipients = new address[](4); + + recipients[0] = DEFAULT_RECIPIENT_1; + recipients[1] = DEFAULT_RECIPIENT_2; + recipients[2] = DEFAULT_RECIPIENT_3; + recipients[3] = DEFAULT_RECIPIENT_4; + + return recipients; + } + + //override this to test variations of different recipients. + function getSecondaryRecipients() public virtual returns (Common.AddressAndWeight[] memory) { + //array of recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](4); + + //init each recipient with even weights. 2500 = 25% of pool + recipients[0] = Common.AddressAndWeight(DEFAULT_RECIPIENT_1, POOL_SCALAR / 4); + recipients[1] = Common.AddressAndWeight(DEFAULT_RECIPIENT_5, POOL_SCALAR / 4); + recipients[2] = Common.AddressAndWeight(DEFAULT_RECIPIENT_6, POOL_SCALAR / 4); + recipients[3] = Common.AddressAndWeight(DEFAULT_RECIPIENT_7, POOL_SCALAR / 4); + + return recipients; + } + + function getSecondaryRecipientAddresses() public pure returns (address[] memory) { + //array of recipients + address[] memory recipients = new address[](4); + + recipients[0] = DEFAULT_RECIPIENT_1; + recipients[1] = DEFAULT_RECIPIENT_5; + recipients[2] = DEFAULT_RECIPIENT_6; + recipients[3] = DEFAULT_RECIPIENT_7; + + return recipients; + } + + function addFundsToPool(bytes32 poolId, Common.Asset memory amount, address sender) public { + IRewardManager.FeePayment[] memory payments = new IRewardManager.FeePayment[](1); + payments[0] = IRewardManager.FeePayment(poolId, uint192(amount.amount)); + + addFundsToPool(payments, sender); + } + + function addFundsToPool(IRewardManager.FeePayment[] memory payments, address sender) public { + //record the current address and switch to the sender + address originalAddr = msg.sender; + changePrank(sender); + + uint256 totalPayment; + for (uint256 i; i < payments.length; ++i) { + totalPayment += payments[i].amount; + } + + //approve the amount being paid into the pool + ERC20Mock(address(asset)).approve(address(rewardManager), totalPayment); + + //this represents the verifier adding some funds to the pool + rewardManager.onFeePaid(payments, sender); + + //change back to the original address + changePrank(originalAddr); + } + + function getAsset(uint256 quantity) public view returns (Common.Asset memory) { + return Common.Asset(address(asset), quantity); + } + + function getAssetBalance(address addr) public view returns (uint256) { + return asset.balanceOf(addr); + } + + function claimRewards(bytes32[] memory poolIds, address sender) public { + //record the current address and switch to the recipient + address originalAddr = msg.sender; + changePrank(sender); + + //claim the rewards + rewardManager.claimRewards(poolIds); + + //change back to the original address + changePrank(originalAddr); + } + + function payRecipients(bytes32 poolId, address[] memory recipients, address sender) public { + //record the current address and switch to the recipient + address originalAddr = msg.sender; + changePrank(sender); + + //pay the recipients + rewardManager.payRecipients(poolId, recipients); + + //change back to the original address + changePrank(originalAddr); + } + + function setRewardRecipients(bytes32 poolId, Common.AddressAndWeight[] memory recipients, address sender) public { + //record the current address and switch to the recipient + address originalAddr = msg.sender; + changePrank(sender); + + //pay the recipients + rewardManager.setRewardRecipients(poolId, recipients); + + //change back to the original address + changePrank(originalAddr); + } + + function setFeeManager(address feeManager, address sender) public { + //record the current address and switch to the recipient + address originalAddr = msg.sender; + changePrank(sender); + + //update the proxy + rewardManager.setFeeManager(feeManager); + + //change back to the original address + changePrank(originalAddr); + } + + function updateRewardRecipients(bytes32 poolId, Common.AddressAndWeight[] memory recipients, address sender) public { + //record the current address and switch to the recipient + address originalAddr = msg.sender; + changePrank(sender); + + //pay the recipients + rewardManager.updateRewardRecipients(poolId, recipients); + + //change back to the original address + changePrank(originalAddr); + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/reward-manager/RewardManager.claim.t.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/reward-manager/RewardManager.claim.t.sol new file mode 100644 index 00000000000..efbe9fd6b36 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/reward-manager/RewardManager.claim.t.sol @@ -0,0 +1,790 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import {BaseRewardManagerTest} from "./BaseRewardManager.t.sol"; +import {Common} from "../../../libraries/Common.sol"; + +/** + * @title BaseRewardManagerTest + * @author Michael Fletcher + * @notice This contract will test the claim functionality of the RewardManager contract. + */ +contract RewardManagerClaimTest is BaseRewardManagerTest { + uint256 internal constant POOL_DEPOSIT_AMOUNT = 10e18; + + function setUp() public override { + //setup contracts + super.setUp(); + + //create a single pool for these tests + createPrimaryPool(); + + //add funds to the pool to be split among the recipients + addFundsToPool(PRIMARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + } + + function test_claimAllRecipients() public { + //expected recipient amount is 1/4 of the pool deposit + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //claim funds for each recipient within the pool + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[i]; + + //claim the individual rewards for each recipient + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount); + } + } + + function test_claimRewardsWithDuplicatePoolIdsDoesNotPayoutTwice() public { + //add funds to a different pool to ensure they're not claimed + addFundsToPool(SECONDARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + + //expected recipient amount is 1/4 of the pool deposit + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //create an array containing duplicate poolIds + bytes32[] memory poolIds = new bytes32[](2); + poolIds[0] = PRIMARY_POOL_ID; + poolIds[1] = PRIMARY_POOL_ID; + + //claim funds for each recipient within the pool + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[i]; + + //claim the individual rewards for each recipient + claimRewards(poolIds, recipient.addr); + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount); + } + + //the pool should still have the remaining + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT); + } + + function test_claimSingleRecipient() public { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[0]; + + //claim the individual rewards for this recipient + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + + //expected recipient amount is 1/4 of the pool deposit + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //check the recipients balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount); + + //check the rewardManager has the remaining quantity + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT - expectedRecipientAmount); + } + + function test_claimMultipleRecipients() public { + //claim the individual rewards for each recipient + claimRewards(PRIMARY_POOL_ARRAY, getPrimaryRecipients()[0].addr); + claimRewards(PRIMARY_POOL_ARRAY, getPrimaryRecipients()[1].addr); + + //expected recipient amount is 1/4 of the pool deposit + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //check the recipients balance matches the ratio the recipient should have received + assertEq(getAssetBalance(getPrimaryRecipients()[0].addr), expectedRecipientAmount); + assertEq(getAssetBalance(getPrimaryRecipients()[1].addr), expectedRecipientAmount); + + //check the rewardManager has the remaining quantity + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT - (expectedRecipientAmount * 2)); + } + + function test_claimUnregisteredRecipient() public { + //claim the rewards for a recipient who isn't in this pool + claimRewards(PRIMARY_POOL_ARRAY, getSecondaryRecipients()[1].addr); + + //check the recipients didn't receive any fees from this pool + assertEq(getAssetBalance(getSecondaryRecipients()[1].addr), 0); + + //check the rewardManager has the remaining quantity + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT); + } + + function test_claimUnevenAmountRoundsDown() public { + //adding 1 to the pool should leave 1 wei worth of dust, which the contract doesn't handle due to it being economically infeasible + addFundsToPool(PRIMARY_POOL_ID, getAsset(1), FEE_MANAGER); + + //expected recipient amount is 1/4 of the pool deposit + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //claim funds for each recipient within the pool + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[i]; + + //claim the individual rewards for each recipient + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount); + } + + //check the rewardManager has the remaining quantity equals 1 wei + assertEq(getAssetBalance(address(rewardManager)), 1); + } + + function test_claimUnregisteredPoolId() public { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[0]; + + //claim the individual rewards for this recipient + claimRewards(SECONDARY_POOL_ARRAY, recipient.addr); + + //check the recipients balance is still 0 as there's no pool to receive fees from + assertEq(getAssetBalance(recipient.addr), 0); + + //check the rewardManager has the full amount + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT); + } + + function test_singleRecipientClaimMultipleDeposits() public { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[0]; + + //claim the individual rewards for this recipient + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + + //expected recipient amount is 1/4 of the pool deposit + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //check the recipients balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount); + + //check the rewardManager has the remaining quantity, which is 3/4 of the initial deposit + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT - expectedRecipientAmount); + + //add funds to the pool to be split among the recipients + addFundsToPool(PRIMARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + + //claim the individual rewards for this recipient + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + + //check the recipients balance matches the ratio the recipient should have received, which is 1/4 of each deposit + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount * 2); + + //check the rewardManager has the remaining quantity, which is now 3/4 of both deposits + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT * 2 - (expectedRecipientAmount * 2)); + } + + function test_recipientsClaimMultipleDeposits() public { + //expected recipient amount is 1/4 of the pool deposit + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //claim funds for each recipient within the pool + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[i]; + + //claim the individual rewards for each recipient + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount); + } + + //the reward manager balance should be 0 as all of the funds have been claimed + assertEq(getAssetBalance(address(rewardManager)), 0); + + //add funds to the pool to be split among the recipients + addFundsToPool(PRIMARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + + //claim funds for each recipient within the pool + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[i]; + + //claim the individual rewards for each recipient + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + + //expected recipient amount is 1/4 of the pool deposit + expectedRecipientAmount = (POOL_DEPOSIT_AMOUNT / 4) * 2; + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount); + } + + //the reward manager balance should again be 0 as all of the funds have been claimed + assertEq(getAssetBalance(address(rewardManager)), 0); + } + + function test_eventIsEmittedUponClaim() public { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[0]; + + //expect an emit + vm.expectEmit(); + + //emit the event that is expected to be emitted + emit RewardsClaimed(PRIMARY_POOL_ID, recipient.addr, uint192(POOL_DEPOSIT_AMOUNT / 4)); + + //claim the individual rewards for each recipient + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + } + + function test_eventIsNotEmittedUponUnsuccessfulClaim() public { + //record logs to check no events were emitted + vm.recordLogs(); + + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[0]; + + //claim the individual rewards for each recipient + claimRewards(SECONDARY_POOL_ARRAY, recipient.addr); + + //no logs should have been emitted + assertEq(vm.getRecordedLogs().length, 0); + } +} + +contract RewardManagerRecipientClaimMultiplePoolsTest is BaseRewardManagerTest { + uint256 internal constant POOL_DEPOSIT_AMOUNT = 10e18; + + function setUp() public override { + //setup contracts + super.setUp(); + + //create a two pools + createPrimaryPool(); + createSecondaryPool(); + + //add funds to each of the pools to be split among the recipients + addFundsToPool(PRIMARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + addFundsToPool(SECONDARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + } + + function test_claimAllRecipientsSinglePool() public { + //expected recipient amount is 1/4 of the pool deposit + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //claim funds for each recipient within the pool + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[i]; + + //claim the individual rewards for each recipient + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount); + } + + //check the pool balance is still equal to DEPOSIT_AMOUNT as the test only claims for one of the pools + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT); + } + + function test_claimMultipleRecipientsSinglePool() public { + //claim the individual rewards for each recipient + claimRewards(SECONDARY_POOL_ARRAY, getSecondaryRecipients()[0].addr); + claimRewards(SECONDARY_POOL_ARRAY, getSecondaryRecipients()[1].addr); + + //expected recipient amount is 1/4 of the pool deposit + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //check the recipients balance matches the ratio the recipient should have received + assertEq(getAssetBalance(getSecondaryRecipients()[0].addr), expectedRecipientAmount); + assertEq(getAssetBalance(getSecondaryRecipients()[1].addr), expectedRecipientAmount); + + //check the rewardManager has the remaining quantity + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT * 2 - (expectedRecipientAmount * 2)); + } + + function test_claimMultipleRecipientsMultiplePools() public { + //claim the individual rewards for each recipient + claimRewards(PRIMARY_POOL_ARRAY, getPrimaryRecipients()[0].addr); + claimRewards(PRIMARY_POOL_ARRAY, getPrimaryRecipients()[1].addr); + claimRewards(SECONDARY_POOL_ARRAY, getSecondaryRecipients()[0].addr); + claimRewards(SECONDARY_POOL_ARRAY, getSecondaryRecipients()[1].addr); + + //expected recipient amount is 1/4 of the pool deposit + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //check the recipients balance matches the ratio the recipient should have received. The first recipient is shared across both pools so should receive 1/4 of each pool + assertEq(getAssetBalance(getPrimaryRecipients()[0].addr), expectedRecipientAmount * 2); + assertEq(getAssetBalance(getPrimaryRecipients()[1].addr), expectedRecipientAmount); + assertEq(getAssetBalance(getSecondaryRecipients()[1].addr), expectedRecipientAmount); + + //check the rewardManager has the remaining quantity + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT); + } + + function test_claimAllRecipientsMultiplePools() public { + //expected recipient amount is 1/4 of the pool deposit + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //claim funds for each recipient within the pool + for (uint256 i = 1; i < getPrimaryRecipients().length; i++) { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[i]; + + //claim the individual rewards for each recipient + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount); + } + + //claim funds for each recipient within the pool + for (uint256 i = 1; i < getSecondaryRecipients().length; i++) { + //get the recipient that is claiming + Common.AddressAndWeight memory secondaryRecipient = getSecondaryRecipients()[i]; + + //claim the individual rewards for each recipient + claimRewards(SECONDARY_POOL_ARRAY, secondaryRecipient.addr); + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(secondaryRecipient.addr), expectedRecipientAmount); + } + + //special case to handle the first recipient of each pool as they're the same address + Common.AddressAndWeight memory commonRecipient = getPrimaryRecipients()[0]; + + //claim the individual rewards for each pool + claimRewards(PRIMARY_POOL_ARRAY, commonRecipient.addr); + claimRewards(SECONDARY_POOL_ARRAY, commonRecipient.addr); + + //check the balance matches the ratio the recipient should have received, which is 1/4 of each deposit for each pool + assertEq(getAssetBalance(commonRecipient.addr), expectedRecipientAmount * 2); + } + + function test_claimSingleUniqueRecipient() public { + //the first recipient of the secondary pool is in both pools, so take the second recipient which is unique + Common.AddressAndWeight memory recipient = getSecondaryRecipients()[1]; + + //claim the individual rewards for this recipient + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + claimRewards(SECONDARY_POOL_ARRAY, recipient.addr); + + //the recipient should have received 1/4 of the deposit amount + uint256 recipientExpectedAmount = POOL_DEPOSIT_AMOUNT / 4; + + //the recipient should have received 1/4 of the deposit amount + assertEq(getAssetBalance(recipient.addr), recipientExpectedAmount); + + //check the rewardManager has the remaining quantity + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT * 2 - recipientExpectedAmount); + } + + function test_claimSingleRecipientMultiplePools() public { + //the first recipient of the secondary pool is in both pools + Common.AddressAndWeight memory recipient = getSecondaryRecipients()[0]; + + //claim the individual rewards for this recipient + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + claimRewards(SECONDARY_POOL_ARRAY, recipient.addr); + + //the recipient should have received 1/4 of the deposit amount for each pool + uint256 recipientExpectedAmount = (POOL_DEPOSIT_AMOUNT / 4) * 2; + + //this recipient belongs in both pools so should have received 1/4 of each + assertEq(getAssetBalance(recipient.addr), recipientExpectedAmount); + + //check the rewardManager has the remaining quantity + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT * 2 - recipientExpectedAmount); + } + + function test_claimUnregisteredRecipient() public { + //claim the individual rewards for this recipient + claimRewards(PRIMARY_POOL_ARRAY, getSecondaryRecipients()[1].addr); + claimRewards(SECONDARY_POOL_ARRAY, getPrimaryRecipients()[1].addr); + + //check the recipients didn't receive any fees from this pool + assertEq(getAssetBalance(getSecondaryRecipients()[1].addr), 0); + assertEq(getAssetBalance(getPrimaryRecipients()[1].addr), 0); + + //check the rewardManager has the remaining quantity + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT * 2); + } + + function test_claimUnevenAmountRoundsDown() public { + //adding an uneven amount of dust to each pool, this should round down to the nearest whole number with 4 remaining in the contract + addFundsToPool(PRIMARY_POOL_ID, getAsset(3), FEE_MANAGER); + addFundsToPool(SECONDARY_POOL_ID, getAsset(1), FEE_MANAGER); + + //the recipient should have received 1/4 of the deposit amount for each pool + uint256 recipientExpectedAmount = POOL_DEPOSIT_AMOUNT / 4; + + //claim funds for each recipient within the pool + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[i]; + + //claim the individual rewards for each recipient + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), recipientExpectedAmount); + } + + //special case to handle the first recipient of each pool as they're the same address + claimRewards(SECONDARY_POOL_ARRAY, getSecondaryRecipients()[0].addr); + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(getSecondaryRecipients()[0].addr), recipientExpectedAmount * 2); + + //claim funds for each recipient of the secondary pool except the first + for (uint256 i = 1; i < getSecondaryRecipients().length; i++) { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getSecondaryRecipients()[i]; + + //claim the individual rewards for each recipient + claimRewards(SECONDARY_POOL_ARRAY, recipient.addr); + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), recipientExpectedAmount); + } + + //contract should have 4 remaining + assertEq(getAssetBalance(address(rewardManager)), 4); + } + + function test_singleRecipientClaimMultipleDeposits() public { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getSecondaryRecipients()[0]; + + //claim the individual rewards for this recipient + claimRewards(SECONDARY_POOL_ARRAY, recipient.addr); + + //the recipient should have received 1/4 of the deposit amount + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //check the recipients balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount); + + //check the rewardManager has the remaining quantity, which is 3/4 of the initial deposit plus the deposit from the second pool + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT * 2 - expectedRecipientAmount); + + //add funds to the pool to be split among the recipients + addFundsToPool(SECONDARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + + //claim the individual rewards for this recipient + claimRewards(SECONDARY_POOL_ARRAY, recipient.addr); + + //the recipient should have received 1/4 of the next deposit amount + expectedRecipientAmount += POOL_DEPOSIT_AMOUNT / 4; + + //check the recipients balance matches the ratio the recipient should have received, which is 1/4 of each deposit + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount); + + //check the rewardManager has the remaining quantity, which is now 3/4 of both deposits + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT * 3 - expectedRecipientAmount); + } + + function test_recipientsClaimMultipleDeposits() public { + //the recipient should have received 1/4 of the deposit amount + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //claim funds for each recipient within the pool + for (uint256 i; i < getSecondaryRecipients().length; i++) { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getSecondaryRecipients()[i]; + + //claim the individual rewards for each recipient + claimRewards(SECONDARY_POOL_ARRAY, recipient.addr); + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount); + } + + //the reward manager balance should contain only the funds of the secondary pool + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT); + + //add funds to the pool to be split among the recipients + addFundsToPool(SECONDARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + + //special case to handle the first recipient of each pool as they're the same address + claimRewards(SECONDARY_POOL_ARRAY, getSecondaryRecipients()[0].addr); + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(getSecondaryRecipients()[0].addr), expectedRecipientAmount * 2); + + //claim funds for each recipient within the pool except the first + for (uint256 i = 1; i < getSecondaryRecipients().length; i++) { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getSecondaryRecipients()[i]; + + //claim the individual rewards for each recipient + claimRewards(SECONDARY_POOL_ARRAY, recipient.addr); + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount * 2); + } + + //the reward manager balance should again be the balance of the secondary pool as the primary pool has been emptied twice + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT); + } + + function test_claimEmptyPoolWhenSecondPoolContainsFunds() public { + //the recipient should have received 1/4 of the deposit amount + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //claim all rewards for each recipient in the primary pool + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[i]; + + //claim the individual rewards for each recipient + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount); + } + + //claim all the rewards again for the first recipient as that address is a member of both pools + claimRewards(PRIMARY_POOL_ARRAY, getSecondaryRecipients()[0].addr); + + //check the balance + assertEq(getAssetBalance(getSecondaryRecipients()[0].addr), expectedRecipientAmount); + } + + function test_getRewardsAvailableToRecipientInBothPools() public { + //get index 0 as this recipient is in both default pools + bytes32[] memory poolIds = rewardManager.getAvailableRewardPoolIds( + getPrimaryRecipients()[0].addr, + 0, + type(uint256).max + ); + + //check the recipient is in both pools + assertEq(poolIds[0], PRIMARY_POOL_ID); + assertEq(poolIds[1], SECONDARY_POOL_ID); + } + + function test_getRewardsAvailableToRecipientInSinglePool() public { + //get index 0 as this recipient is in both default pools + bytes32[] memory poolIds = rewardManager.getAvailableRewardPoolIds( + getPrimaryRecipients()[1].addr, + 0, + type(uint256).max + ); + + //check the recipient is in both pools + assertEq(poolIds[0], PRIMARY_POOL_ID); + assertEq(poolIds[1], ZERO_POOL_ID); + } + + function test_getRewardsAvailableToRecipientInNoPools() public view { + //get index 0 as this recipient is in both default pools + bytes32[] memory poolIds = rewardManager.getAvailableRewardPoolIds(FEE_MANAGER, 0, type(uint256).max); + + //check the recipient is in neither pool + assertEq(poolIds[0], ZERO_POOL_ID); + assertEq(poolIds[1], ZERO_POOL_ID); + } + + function test_getRewardsAvailableToRecipientInBothPoolsWhereAlreadyClaimed() public { + //get index 0 as this recipient is in both default pools + bytes32[] memory poolIds = rewardManager.getAvailableRewardPoolIds( + getPrimaryRecipients()[0].addr, + 0, + type(uint256).max + ); + + //check the recipient is in both pools + assertEq(poolIds[0], PRIMARY_POOL_ID); + assertEq(poolIds[1], SECONDARY_POOL_ID); + + //claim the rewards for each pool + claimRewards(PRIMARY_POOL_ARRAY, getPrimaryRecipients()[0].addr); + claimRewards(SECONDARY_POOL_ARRAY, getSecondaryRecipients()[0].addr); + + //get the available pools again + poolIds = rewardManager.getAvailableRewardPoolIds(getPrimaryRecipients()[0].addr, 0, type(uint256).max); + + //user should not be in any pool + assertEq(poolIds[0], ZERO_POOL_ID); + assertEq(poolIds[1], ZERO_POOL_ID); + } + + function test_getAvailableRewardsCursorCannotBeGreaterThanTotalPools() public { + vm.expectRevert(INVALID_POOL_LENGTH_SELECTOR); + + rewardManager.getAvailableRewardPoolIds(FEE_MANAGER, type(uint256).max, 0); + } + + function test_getAvailableRewardsCursorAndTotalPoolsEqual() public { + bytes32[] memory poolIds = rewardManager.getAvailableRewardPoolIds(getPrimaryRecipients()[0].addr, 2, 2); + + assertEq(poolIds.length, 0); + } + + function test_getAvailableRewardsCursorSingleResult() public { + bytes32[] memory poolIds = rewardManager.getAvailableRewardPoolIds(getPrimaryRecipients()[0].addr, 0, 1); + + assertEq(poolIds[0], PRIMARY_POOL_ID); + } +} + +contract RewardManagerRecipientClaimDifferentWeightsTest is BaseRewardManagerTest { + uint256 internal constant POOL_DEPOSIT_AMOUNT = 10e18; + + function setUp() public override { + //setup contracts + super.setUp(); + + //create a single pool for these tests + createPrimaryPool(); + + //add funds to the pool to be split among the recipients + addFundsToPool(PRIMARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + } + + function getPrimaryRecipients() public virtual override returns (Common.AddressAndWeight[] memory) { + //array of recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](4); + + //init each recipient with uneven weights + recipients[0] = Common.AddressAndWeight(DEFAULT_RECIPIENT_1, TEN_PERCENT); + recipients[1] = Common.AddressAndWeight(DEFAULT_RECIPIENT_2, TEN_PERCENT * 8); + recipients[2] = Common.AddressAndWeight(DEFAULT_RECIPIENT_3, ONE_PERCENT * 6); + recipients[3] = Common.AddressAndWeight(DEFAULT_RECIPIENT_4, ONE_PERCENT * 4); + + return recipients; + } + + function test_allRecipientsClaimingReceiveExpectedAmount() public { + //loop all the recipients and claim their expected amount + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[i]; + + //claim the individual rewards for each recipient + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + + //the recipient should have received a share proportional to their weight + uint256 expectedRecipientAmount = (POOL_DEPOSIT_AMOUNT * recipient.weight) / POOL_SCALAR; + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount); + } + } +} + +contract RewardManagerRecipientClaimUnevenWeightTest is BaseRewardManagerTest { + uint256 internal constant POOL_DEPOSIT_AMOUNT = 10e18; + + function setUp() public override { + //setup contracts + super.setUp(); + + //create a single pool for these tests + createPrimaryPool(); + } + + function getPrimaryRecipients() public virtual override returns (Common.AddressAndWeight[] memory) { + //array of recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](2); + + uint64 oneThird = POOL_SCALAR / 3; + + //init each recipient with even weights. + recipients[0] = Common.AddressAndWeight(DEFAULT_RECIPIENT_1, oneThird); + recipients[1] = Common.AddressAndWeight(DEFAULT_RECIPIENT_2, 2 * oneThird + 1); + + return recipients; + } + + function test_allRecipientsClaimingReceiveExpectedAmountWithSmallDeposit() public { + //add a smaller amount of funds to the pool + uint256 smallDeposit = 1e8; + + //add a smaller amount of funds to the pool + addFundsToPool(PRIMARY_POOL_ID, getAsset(smallDeposit), FEE_MANAGER); + + //loop all the recipients and claim their expected amount + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[i]; + + //claim the individual rewards for each recipient + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + + //the recipient should have received a share proportional to their weight + uint256 expectedRecipientAmount = (smallDeposit * recipient.weight) / POOL_SCALAR; + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount); + } + + //smaller deposits will consequently have less precision and will not be able to be split as evenly, the remaining 1 will be lost due to 333...|... being paid out instead of 333...4| + assertEq(getAssetBalance(address(rewardManager)), 1); + } + + function test_allRecipientsClaimingReceiveExpectedAmount() public { + //add funds to the pool to be split among the recipients + addFundsToPool(PRIMARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + + //loop all the recipients and claim their expected amount + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[i]; + + //claim the individual rewards for each recipient + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + + //the recipient should have received a share proportional to their weight + uint256 expectedRecipientAmount = (POOL_DEPOSIT_AMOUNT * recipient.weight) / POOL_SCALAR; + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount); + } + + //their should be 0 wei left over indicating a successful split + assertEq(getAssetBalance(address(rewardManager)), 0); + } +} + +contract RewardManagerNoRecipientSet is BaseRewardManagerTest { + uint256 internal constant POOL_DEPOSIT_AMOUNT = 10e18; + + function setUp() public override { + //setup contracts + super.setUp(); + + //add funds to the pool to be split among the recipients once registered + addFundsToPool(PRIMARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + } + + function test_claimAllRecipientsAfterRecipientsSet() public { + //expected recipient amount is 1/4 of the pool deposit + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //try and claim funds for each recipient within the pool + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[i]; + + //there should be no rewards claimed as the recipient is not registered + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + + //check the recipient received nothing + assertEq(getAssetBalance(recipient.addr), 0); + } + + //Set the recipients after the rewards have been paid into the pool + setRewardRecipients(PRIMARY_POOL_ID, getPrimaryRecipients(), ADMIN); + + //claim funds for each recipient within the pool + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //get the recipient that is claiming + Common.AddressAndWeight memory recipient = getPrimaryRecipients()[i]; + + //there should be no rewards claimed as the recipient is registered + claimRewards(PRIMARY_POOL_ARRAY, recipient.addr); + + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipient.addr), expectedRecipientAmount); + } + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/reward-manager/RewardManager.general.t.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/reward-manager/RewardManager.general.t.sol new file mode 100644 index 00000000000..b2e0cf99bb9 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/reward-manager/RewardManager.general.t.sol @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import {BaseRewardManagerTest} from "./BaseRewardManager.t.sol"; +import {RewardManager} from "../../RewardManager.sol"; +import {ERC20Mock} from "../../../../vendor/openzeppelin-solidity/v4.8.3/contracts/mocks/ERC20Mock.sol"; +import {IRewardManager} from "../../interfaces/IRewardManager.sol"; + +/** + * @title BaseRewardManagerTest + * @author Michael Fletcher + * @notice This contract will test the core functionality of the RewardManager contract + */ +contract RewardManagerSetupTest is BaseRewardManagerTest { + uint256 internal constant POOL_DEPOSIT_AMOUNT = 10e18; + + function setUp() public override { + //setup contracts + super.setUp(); + } + + function test_rejectsZeroLinkAddressOnConstruction() public { + //should revert if the contract is a zero address + vm.expectRevert(INVALID_ADDRESS_ERROR_SELECTOR); + + //create a rewardManager with a zero link address + new RewardManager(address(0)); + } + + function test_eventEmittedUponFeeManagerUpdate() public { + //expect the event to be emitted + vm.expectEmit(); + + //emit the event that is expected to be emitted + emit FeeManagerUpdated(FEE_MANAGER); + + //set the verifier proxy + setFeeManager(FEE_MANAGER, ADMIN); + } + + function test_eventEmittedUponFeePaid() public { + //create pool and add funds + createPrimaryPool(); + + //change to the feeManager who is the one who will be paying the fees + changePrank(FEE_MANAGER); + + //approve the amount being paid into the pool + ERC20Mock(getAsset(POOL_DEPOSIT_AMOUNT).assetAddress).approve(address(rewardManager), POOL_DEPOSIT_AMOUNT); + + IRewardManager.FeePayment[] memory payments = new IRewardManager.FeePayment[](1); + payments[0] = IRewardManager.FeePayment(PRIMARY_POOL_ID, uint192(POOL_DEPOSIT_AMOUNT)); + + //event is emitted when funds are added + vm.expectEmit(); + emit FeePaid(payments, FEE_MANAGER); + + //this represents the verifier adding some funds to the pool + rewardManager.onFeePaid(payments, FEE_MANAGER); + } + + function test_setFeeManagerZeroAddress() public { + //should revert if the contract is a zero address + vm.expectRevert(INVALID_ADDRESS_ERROR_SELECTOR); + + //set the verifier proxy + setFeeManager(address(0), ADMIN); + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/reward-manager/RewardManager.payRecipients.t.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/reward-manager/RewardManager.payRecipients.t.sol new file mode 100644 index 00000000000..89fac663ba3 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/reward-manager/RewardManager.payRecipients.t.sol @@ -0,0 +1,194 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import {BaseRewardManagerTest} from "./BaseRewardManager.t.sol"; +import {IRewardManager} from "../../interfaces/IRewardManager.sol"; + +/** + * @title BaseRewardManagerTest + * @author Michael Fletcher + * @notice This contract will test the payRecipients functionality of the RewardManager contract + */ +contract RewardManagerPayRecipientsTest is BaseRewardManagerTest { + uint256 internal constant POOL_DEPOSIT_AMOUNT = 10e18; + + function setUp() public override { + //setup contracts + super.setUp(); + + //create a single pool for these tests + createPrimaryPool(); + + //add funds to the pool to be split among the recipients + addFundsToPool(PRIMARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + } + + function test_payAllRecipients() public { + //pay all the recipients in the pool + payRecipients(PRIMARY_POOL_ID, getPrimaryRecipientAddresses(), ADMIN); + + //each recipient should receive 1/4 of the pool + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //check each recipient received the correct amount + for (uint256 i = 0; i < getPrimaryRecipientAddresses().length; i++) { + assertEq(getAssetBalance(getPrimaryRecipientAddresses()[i]), expectedRecipientAmount); + } + } + + function test_paySingleRecipient() public { + //get the first individual recipient + address recipient = getPrimaryRecipientAddresses()[0]; + + //get a single recipient as an array + address[] memory recipients = new address[](1); + recipients[0] = recipient; + + //pay a single recipient + payRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + + //the recipient should have received 1/4 of the deposit amount + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + assertEq(getAssetBalance(recipient), expectedRecipientAmount); + } + + function test_payRecipientWithInvalidPool() public { + //get the first individual recipient + address recipient = getPrimaryRecipientAddresses()[0]; + + //get a single recipient as an array + address[] memory recipients = new address[](1); + recipients[0] = recipient; + + //pay a single recipient + payRecipients(SECONDARY_POOL_ID, recipients, ADMIN); + + //the recipient should have received nothing + assertEq(getAssetBalance(recipient), 0); + } + + function test_payRecipientsEmptyRecipientList() public { + //get a single recipient + address[] memory recipients = new address[](0); + + //pay a single recipient + payRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + + //rewardManager should have the full balance + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT); + } + + function test_payAllRecipientsWithAdditionalUnregisteredRecipient() public { + //load all the recipients and add an additional one who is not in the pool + address[] memory recipients = new address[](getPrimaryRecipientAddresses().length + 1); + for (uint256 i = 0; i < getPrimaryRecipientAddresses().length; i++) { + recipients[i] = getPrimaryRecipientAddresses()[i]; + } + recipients[recipients.length - 1] = DEFAULT_RECIPIENT_5; + + //pay the recipients + payRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + + //each recipient should receive 1/4 of the pool except the last + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //check each recipient received the correct amount + for (uint256 i = 0; i < getPrimaryRecipientAddresses().length; i++) { + assertEq(getAssetBalance(getPrimaryRecipientAddresses()[i]), expectedRecipientAmount); + } + + //the unregistered recipient should receive nothing + assertEq(getAssetBalance(DEFAULT_RECIPIENT_5), 0); + } + + function test_payAllRecipientsWithAdditionalInvalidRecipient() public { + //load all the recipients and add an additional one which is invalid, that should receive nothing + address[] memory recipients = new address[](getPrimaryRecipientAddresses().length + 1); + for (uint256 i = 0; i < getPrimaryRecipientAddresses().length; i++) { + recipients[i] = getPrimaryRecipientAddresses()[i]; + } + recipients[recipients.length - 1] = INVALID_ADDRESS; + + //pay the recipients + payRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + + //each recipient should receive 1/4 of the pool except the last + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //check each recipient received the correct amount + for (uint256 i = 0; i < getPrimaryRecipientAddresses().length; i++) { + assertEq(getAssetBalance(getPrimaryRecipientAddresses()[i]), expectedRecipientAmount); + } + } + + function test_paySubsetOfRecipientsInPool() public { + //load a subset of the recipients into an array + address[] memory recipients = new address[](getPrimaryRecipientAddresses().length - 1); + for (uint256 i = 0; i < recipients.length; i++) { + recipients[i] = getPrimaryRecipientAddresses()[i]; + } + + //pay the subset of recipients + payRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + + //each recipient should receive 1/4 of the pool except the last + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //check each subset of recipients received the correct amount + for (uint256 i = 0; i < recipients.length - 1; i++) { + assertEq(getAssetBalance(recipients[i]), expectedRecipientAmount); + } + + //check the pool has the remaining balance + assertEq( + getAssetBalance(address(rewardManager)), + POOL_DEPOSIT_AMOUNT - expectedRecipientAmount * recipients.length + ); + } + + function test_payAllRecipientsFromNonAdminUser() public { + //should revert if the caller isn't an admin or recipient within the pool + vm.expectRevert(UNAUTHORIZED_ERROR_SELECTOR); + + //pay all the recipients in the pool + payRecipients(PRIMARY_POOL_ID, getPrimaryRecipientAddresses(), FEE_MANAGER); + } + + function test_payAllRecipientsFromRecipientInPool() public { + //pay all the recipients in the pool + payRecipients(PRIMARY_POOL_ID, getPrimaryRecipientAddresses(), DEFAULT_RECIPIENT_1); + + //each recipient should receive 1/4 of the pool + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //check each recipient received the correct amount + for (uint256 i = 0; i < getPrimaryRecipientAddresses().length; i++) { + assertEq(getAssetBalance(getPrimaryRecipientAddresses()[i]), expectedRecipientAmount); + } + } + + function test_payRecipientsWithInvalidPoolId() public { + //pay all the recipients in the pool + payRecipients(INVALID_POOL_ID, getPrimaryRecipientAddresses(), ADMIN); + + //pool should still contain the full balance + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT); + } + + function test_addFundsToPoolAsOwner() public { + //add funds to the pool + addFundsToPool(PRIMARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + } + + function test_addFundsToPoolAsNonOwnerOrFeeManager() public { + //should revert if the caller isn't an admin or recipient within the pool + vm.expectRevert(UNAUTHORIZED_ERROR_SELECTOR); + + IRewardManager.FeePayment[] memory payments = new IRewardManager.FeePayment[](1); + payments[0] = IRewardManager.FeePayment(PRIMARY_POOL_ID, uint192(POOL_DEPOSIT_AMOUNT)); + + //add funds to the pool + rewardManager.onFeePaid(payments, USER); + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/reward-manager/RewardManager.setRecipients.t.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/reward-manager/RewardManager.setRecipients.t.sol new file mode 100644 index 00000000000..d3e6990bd9f --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/reward-manager/RewardManager.setRecipients.t.sol @@ -0,0 +1,148 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import {BaseRewardManagerTest} from "./BaseRewardManager.t.sol"; +import {Common} from "../../../libraries/Common.sol"; + +/** + * @title BaseRewardManagerTest + * @author Michael Fletcher + * @notice This contract will test the setRecipient functionality of the RewardManager contract + */ +contract RewardManagerSetRecipientsTest is BaseRewardManagerTest { + function setUp() public override { + //setup contracts + super.setUp(); + } + + function test_setRewardRecipients() public { + //set the recipients + setRewardRecipients(PRIMARY_POOL_ID, getPrimaryRecipients(), ADMIN); + } + + function test_setRewardRecipientsIsEmpty() public { + //array of recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](4); + + //should revert if the recipients array is empty + vm.expectRevert(INVALID_ADDRESS_ERROR_SELECTOR); + + //set the recipients + setRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + } + + function test_setRewardRecipientWithZeroWeight() public { + //array of recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](5); + + //init each recipient with even weights + recipients[0] = Common.AddressAndWeight(DEFAULT_RECIPIENT_1, ONE_PERCENT * 25); + recipients[1] = Common.AddressAndWeight(DEFAULT_RECIPIENT_2, ONE_PERCENT * 25); + recipients[2] = Common.AddressAndWeight(DEFAULT_RECIPIENT_3, ONE_PERCENT * 25); + recipients[3] = Common.AddressAndWeight(DEFAULT_RECIPIENT_4, ONE_PERCENT * 25); + recipients[4] = Common.AddressAndWeight(DEFAULT_RECIPIENT_5, 0); + + //set the recipients + setRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + } + + function test_setRewardRecipientWithZeroAddress() public { + //array of recipients + Common.AddressAndWeight[] memory recipients = getPrimaryRecipients(); + + //override the first recipient with a zero address + recipients[0].addr = address(0); + + //should revert if the recipients array is empty + vm.expectRevert(INVALID_ADDRESS_ERROR_SELECTOR); + + //set the recipients + setRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + } + + function test_setRewardRecipientWeights() public { + //array of recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](4); + + //init each recipient with even weights + recipients[0] = Common.AddressAndWeight(DEFAULT_RECIPIENT_1, 25); + recipients[1] = Common.AddressAndWeight(DEFAULT_RECIPIENT_2, 25); + recipients[2] = Common.AddressAndWeight(DEFAULT_RECIPIENT_3, 25); + recipients[3] = Common.AddressAndWeight(DEFAULT_RECIPIENT_4, 25); + + //should revert if the recipients array is empty + vm.expectRevert(INVALID_WEIGHT_ERROR_SELECTOR); + + //set the recipients with a recipient with a weight of 100% + setRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + } + + function test_setSingleRewardRecipient() public { + //array of recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](1); + + //init each recipient with even weights + recipients[0] = Common.AddressAndWeight(DEFAULT_RECIPIENT_1, POOL_SCALAR); + + //set the recipients with a recipient with a weight of 100% + setRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + } + + function test_setRewardRecipientTwice() public { + //set the recipients + setRewardRecipients(PRIMARY_POOL_ID, getPrimaryRecipients(), ADMIN); + + //should revert if recipients for this pool have already been set + vm.expectRevert(INVALID_POOL_ID_ERROR_SELECTOR); + + //set the recipients again + setRewardRecipients(PRIMARY_POOL_ID, getPrimaryRecipients(), ADMIN); + } + + function test_setRewardRecipientFromNonOwnerOrFeeManagerAddress() public { + //should revert if the sender is not the owner or proxy + vm.expectRevert(UNAUTHORIZED_ERROR_SELECTOR); + + //set the recipients + setRewardRecipients(PRIMARY_POOL_ID, getPrimaryRecipients(), USER); + } + + function test_setRewardRecipientFromManagerAddress() public { + //update the proxy address + setFeeManager(FEE_MANAGER, ADMIN); + + //set the recipients + setRewardRecipients(PRIMARY_POOL_ID, getPrimaryRecipients(), FEE_MANAGER); + } + + function test_eventIsEmittedUponSetRecipients() public { + //expect an emit + vm.expectEmit(); + + //emit the event that is expected to be emitted + emit RewardRecipientsUpdated(PRIMARY_POOL_ID, getPrimaryRecipients()); + + //set the recipients + setRewardRecipients(PRIMARY_POOL_ID, getPrimaryRecipients(), ADMIN); + } + + function test_setRecipientContainsDuplicateRecipients() public { + //create a new array to hold the existing recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](getPrimaryRecipients().length * 2); + + //add all the existing recipients + for (uint256 i; i < getPrimaryRecipients().length; i++) { + recipients[i] = getPrimaryRecipients()[i]; + } + //add all the existing recipients again + for (uint256 i; i < getPrimaryRecipients().length; i++) { + recipients[i + getPrimaryRecipients().length] = getPrimaryRecipients()[i]; + } + + //should revert as the list contains a duplicate + vm.expectRevert(INVALID_ADDRESS_ERROR_SELECTOR); + + //set the recipients + setRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/reward-manager/RewardManager.updateRewardRecipients.t.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/reward-manager/RewardManager.updateRewardRecipients.t.sol new file mode 100644 index 00000000000..0d3a2b69b39 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/reward-manager/RewardManager.updateRewardRecipients.t.sol @@ -0,0 +1,450 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import {BaseRewardManagerTest} from "./BaseRewardManager.t.sol"; +import {Common} from "../../../libraries/Common.sol"; + +/** + * @title BaseRewardManagerTest + * @author Michael Fletcher + * @notice This contract will test the updateRecipient functionality of the RewardManager contract + */ +contract RewardManagerUpdateRewardRecipientsTest is BaseRewardManagerTest { + uint256 internal constant POOL_DEPOSIT_AMOUNT = 10e18; + + function setUp() public override { + //setup contracts + super.setUp(); + + //create a single pool for these tests + createPrimaryPool(); + + //add funds to the pool to be split among the recipients + addFundsToPool(PRIMARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + } + + function test_onlyAdminCanUpdateRecipients() public { + //should revert if the caller is not the admin + vm.expectRevert(ONLY_CALLABLE_BY_OWNER_ERROR); + + //updating a recipient should force the funds to be paid out + updateRewardRecipients(PRIMARY_POOL_ID, getPrimaryRecipients(), FEE_MANAGER); + } + + function test_updateAllRecipientsWithSameAddressAndWeight() public { + //expected recipient amount is 1/4 of the pool deposit + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //updating a recipient should force the funds to be paid out + updateRewardRecipients(PRIMARY_POOL_ID, getPrimaryRecipients(), ADMIN); + + //check each recipient received the correct amount + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(getPrimaryRecipients()[i].addr), expectedRecipientAmount); + } + } + + function test_updatePartialRecipientsWithSameAddressAndWeight() public { + //expected recipient amount is 1/4 of the pool deposit + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //get a subset of the recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](2); + recipients[0] = Common.AddressAndWeight(DEFAULT_RECIPIENT_1, ONE_PERCENT * 25); + recipients[1] = Common.AddressAndWeight(DEFAULT_RECIPIENT_2, ONE_PERCENT * 25); + + //updating a recipient should force the funds to be paid out + updateRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + + //check each recipient received the correct amount + for (uint256 i; i < recipients.length; i++) { + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipients[i].addr), expectedRecipientAmount); + } + + //the reward manager should still have half remaining funds + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT / 2); + } + + function test_updateRecipientWithNewZeroAddress() public { + //create a new array to hold the existing recipients plus a new zero address + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](getPrimaryRecipients().length + 1); + + //add all the existing recipients + for (uint256 i; i < getPrimaryRecipients().length; i++) { + recipients[i] = getPrimaryRecipients()[i]; + } + //add a new address to the primary recipients + recipients[recipients.length - 1] = Common.AddressAndWeight(address(0), 0); + + //should revert if the recipient is a zero address + vm.expectRevert(INVALID_ADDRESS_ERROR_SELECTOR); + + //update the recipients with invalid address + updateRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + } + + function test_updateRecipientsContainsDuplicateRecipients() public { + //create a new array to hold the existing recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](getPrimaryRecipients().length * 2); + + //add all the existing recipients + for (uint256 i; i < getPrimaryRecipients().length; i++) { + recipients[i] = getPrimaryRecipients()[i]; + } + //add all the existing recipients again + for (uint256 i; i < getPrimaryRecipients().length; i++) { + recipients[i + getPrimaryRecipients().length] = getPrimaryRecipients()[i]; + } + + //should revert as the list contains a duplicate + vm.expectRevert(INVALID_ADDRESS_ERROR_SELECTOR); + + //update the recipients with the duplicate addresses + updateRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + } + + function test_updateRecipientsToDifferentSet() public { + //create a list of containing recipients from the primary configured set, and new recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](getPrimaryRecipients().length + 4); + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //copy the recipient and set the weight to 0 which implies the recipient is being replaced + recipients[i] = Common.AddressAndWeight(getPrimaryRecipients()[i].addr, 0); + } + + //add the new recipients individually + recipients[4] = Common.AddressAndWeight(DEFAULT_RECIPIENT_5, ONE_PERCENT * 25); + recipients[5] = Common.AddressAndWeight(DEFAULT_RECIPIENT_6, ONE_PERCENT * 25); + recipients[6] = Common.AddressAndWeight(DEFAULT_RECIPIENT_7, ONE_PERCENT * 25); + recipients[7] = Common.AddressAndWeight(DEFAULT_RECIPIENT_8, ONE_PERCENT * 25); + + //updating a recipient should force the funds to be paid out for the primary recipients + updateRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + } + + function test_updateRecipientsToDifferentPartialSet() public { + //create a list of containing recipients from the primary configured set, and new recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](getPrimaryRecipients().length + 2); + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //copy the recipient and set the weight to 0 which implies the recipient is being replaced + recipients[i] = Common.AddressAndWeight(getPrimaryRecipients()[i].addr, 0); + } + + //add the new recipients individually + recipients[4] = Common.AddressAndWeight(DEFAULT_RECIPIENT_5, FIFTY_PERCENT); + recipients[5] = Common.AddressAndWeight(DEFAULT_RECIPIENT_6, FIFTY_PERCENT); + + //updating a recipient should force the funds to be paid out for the primary recipients + updateRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + } + + function test_updateRecipientsToDifferentLargerSet() public { + //create a list of containing recipients from the primary configured set, and new recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](getPrimaryRecipients().length + 5); + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //copy the recipient and set the weight to 0 which implies the recipient is being replaced + recipients[i] = Common.AddressAndWeight(getPrimaryRecipients()[i].addr, 0); + } + + //add the new recipients individually + recipients[4] = Common.AddressAndWeight(DEFAULT_RECIPIENT_5, TEN_PERCENT * 2); + recipients[5] = Common.AddressAndWeight(DEFAULT_RECIPIENT_6, TEN_PERCENT * 2); + recipients[6] = Common.AddressAndWeight(DEFAULT_RECIPIENT_7, TEN_PERCENT * 2); + recipients[7] = Common.AddressAndWeight(DEFAULT_RECIPIENT_8, TEN_PERCENT * 2); + recipients[8] = Common.AddressAndWeight(DEFAULT_RECIPIENT_9, TEN_PERCENT * 2); + + //updating a recipient should force the funds to be paid out for the primary recipients + updateRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + } + + function test_updateRecipientsUpdateAndRemoveExistingForLargerSet() public { + //create a list of containing recipients from the primary configured set, and new recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](9); + + //update the existing recipients + recipients[0] = Common.AddressAndWeight(getPrimaryRecipients()[0].addr, 0); + recipients[1] = Common.AddressAndWeight(getPrimaryRecipients()[1].addr, 0); + recipients[2] = Common.AddressAndWeight(getPrimaryRecipients()[2].addr, TEN_PERCENT * 3); + recipients[3] = Common.AddressAndWeight(getPrimaryRecipients()[3].addr, TEN_PERCENT * 3); + + //add the new recipients individually + recipients[4] = Common.AddressAndWeight(DEFAULT_RECIPIENT_5, TEN_PERCENT); + recipients[5] = Common.AddressAndWeight(DEFAULT_RECIPIENT_6, TEN_PERCENT); + recipients[6] = Common.AddressAndWeight(DEFAULT_RECIPIENT_7, TEN_PERCENT); + recipients[7] = Common.AddressAndWeight(DEFAULT_RECIPIENT_8, TEN_PERCENT); + recipients[8] = Common.AddressAndWeight(DEFAULT_RECIPIENT_9, TEN_PERCENT); + + //should revert as the weight does not equal 100% + vm.expectRevert(INVALID_WEIGHT_ERROR_SELECTOR); + + //updating a recipient should force the funds to be paid out for the primary recipients + updateRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + } + + function test_updateRecipientsUpdateAndRemoveExistingForSmallerSet() public { + //create a list of containing recipients from the primary configured set, and new recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](5); + + //update the existing recipients + recipients[0] = Common.AddressAndWeight(getPrimaryRecipients()[0].addr, 0); + recipients[1] = Common.AddressAndWeight(getPrimaryRecipients()[1].addr, 0); + recipients[2] = Common.AddressAndWeight(getPrimaryRecipients()[2].addr, TEN_PERCENT * 3); + recipients[3] = Common.AddressAndWeight(getPrimaryRecipients()[3].addr, TEN_PERCENT * 2); + + //add the new recipients individually + recipients[4] = Common.AddressAndWeight(DEFAULT_RECIPIENT_5, TEN_PERCENT * 5); + + //updating a recipient should force the funds to be paid out for the primary recipients + updateRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + } + + function test_updateRecipientsToDifferentSetWithInvalidWeights() public { + //create a list of containing recipients from the primary configured set, and new recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](getPrimaryRecipients().length + 2); + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //copy the recipient and set the weight to 0 which implies the recipient is being replaced + recipients[i] = Common.AddressAndWeight(getPrimaryRecipients()[i].addr, 0); + } + + //add the new recipients individually + recipients[4] = Common.AddressAndWeight(DEFAULT_RECIPIENT_5, TEN_PERCENT * 5); + recipients[5] = Common.AddressAndWeight(DEFAULT_RECIPIENT_6, TEN_PERCENT); + + //should revert as the weight will not equal 100% + vm.expectRevert(INVALID_WEIGHT_ERROR_SELECTOR); + + //updating a recipient should force the funds to be paid out for the primary recipients + updateRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + } + + function test_updatePartialRecipientsToSubset() public { + //create a list of containing recipients from the primary configured set, and new recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](4); + recipients[0] = Common.AddressAndWeight(DEFAULT_RECIPIENT_1, 0); + recipients[1] = Common.AddressAndWeight(DEFAULT_RECIPIENT_2, 0); + recipients[2] = Common.AddressAndWeight(DEFAULT_RECIPIENT_3, TEN_PERCENT * 5); + recipients[3] = Common.AddressAndWeight(DEFAULT_RECIPIENT_4, TEN_PERCENT * 5); + + //updating a recipient should force the funds to be paid out for the primary recipients + updateRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + } + + function test_updatePartialRecipientsWithUnderWeightSet() public { + //create a list of containing recipients from the primary configured set, and new recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](4); + recipients[0] = Common.AddressAndWeight(DEFAULT_RECIPIENT_1, TEN_PERCENT); + recipients[1] = Common.AddressAndWeight(DEFAULT_RECIPIENT_2, TEN_PERCENT); + recipients[2] = Common.AddressAndWeight(DEFAULT_RECIPIENT_3, TEN_PERCENT); + recipients[3] = Common.AddressAndWeight(DEFAULT_RECIPIENT_4, TEN_PERCENT); + + //should revert as the new weights exceed the previous weights being replaced + vm.expectRevert(INVALID_WEIGHT_ERROR_SELECTOR); + + //updating a recipient should force the funds to be paid out for the primary recipients + updateRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + } + + function test_updatePartialRecipientsWithExcessiveWeight() public { + //create a list of containing recipients from the primary configured set, and new recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](4); + recipients[0] = Common.AddressAndWeight(DEFAULT_RECIPIENT_1, TEN_PERCENT); + recipients[1] = Common.AddressAndWeight(DEFAULT_RECIPIENT_2, TEN_PERCENT); + recipients[2] = Common.AddressAndWeight(DEFAULT_RECIPIENT_3, TEN_PERCENT); + recipients[3] = Common.AddressAndWeight(DEFAULT_RECIPIENT_4, POOL_SCALAR); + + //should revert as the new weights exceed the previous weights being replaced + vm.expectRevert(INVALID_WEIGHT_ERROR_SELECTOR); + + //updating a recipient should force the funds to be paid out for the primary recipients + updateRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + } + + function test_updateRecipientWeights() public { + //expected recipient amount is 1/4 of the pool deposit for original recipients + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //create a list of containing recipients from the primary configured set with their new weights + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](4); + recipients[0] = Common.AddressAndWeight(DEFAULT_RECIPIENT_1, TEN_PERCENT); + recipients[1] = Common.AddressAndWeight(DEFAULT_RECIPIENT_2, TEN_PERCENT); + recipients[2] = Common.AddressAndWeight(DEFAULT_RECIPIENT_3, TEN_PERCENT * 3); + recipients[3] = Common.AddressAndWeight(DEFAULT_RECIPIENT_4, TEN_PERCENT * 5); + + //updating a recipient should force the funds to be paid out for the primary recipients + updateRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + + //check each recipient received the correct amount + for (uint256 i; i < recipients.length; i++) { + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipients[i].addr), expectedRecipientAmount); + } + + //the reward manager should have no funds remaining + assertEq(getAssetBalance(address(rewardManager)), 0); + + //add more funds to the pool to check new distribution + addFundsToPool(PRIMARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + + //loop each user and claim the rewards + for (uint256 i; i < recipients.length; i++) { + //claim the rewards for this recipient + claimRewards(PRIMARY_POOL_ARRAY, recipients[i].addr); + } + + //manually check the balance of each recipient + assertEq( + getAssetBalance(DEFAULT_RECIPIENT_1), + (POOL_DEPOSIT_AMOUNT * TEN_PERCENT) / POOL_SCALAR + expectedRecipientAmount + ); + assertEq( + getAssetBalance(DEFAULT_RECIPIENT_2), + (POOL_DEPOSIT_AMOUNT * TEN_PERCENT) / POOL_SCALAR + expectedRecipientAmount + ); + assertEq( + getAssetBalance(DEFAULT_RECIPIENT_3), + (POOL_DEPOSIT_AMOUNT * TEN_PERCENT * 3) / POOL_SCALAR + expectedRecipientAmount + ); + assertEq( + getAssetBalance(DEFAULT_RECIPIENT_4), + (POOL_DEPOSIT_AMOUNT * TEN_PERCENT * 5) / POOL_SCALAR + expectedRecipientAmount + ); + } + + function test_partialUpdateRecipientWeights() public { + //expected recipient amount is 1/4 of the pool deposit for original recipients + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //create a list of containing recipients from the primary configured set with their new weights + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](2); + recipients[0] = Common.AddressAndWeight(DEFAULT_RECIPIENT_1, TEN_PERCENT); + recipients[1] = Common.AddressAndWeight(DEFAULT_RECIPIENT_2, TEN_PERCENT * 4); + + //updating a recipient should force the funds to be paid out for the primary recipients + updateRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + + //check each recipient received the correct amount + for (uint256 i; i < recipients.length; i++) { + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipients[i].addr), expectedRecipientAmount); + } + + //the reward manager should have half the funds remaining + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT / 2); + + //add more funds to the pool to check new distribution + addFundsToPool(PRIMARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + + //loop each user and claim the rewards + for (uint256 i; i < recipients.length; i++) { + //claim the rewards for this recipient + claimRewards(PRIMARY_POOL_ARRAY, recipients[i].addr); + } + + //manually check the balance of each recipient + assertEq( + getAssetBalance(DEFAULT_RECIPIENT_1), + (POOL_DEPOSIT_AMOUNT * TEN_PERCENT) / POOL_SCALAR + expectedRecipientAmount + ); + assertEq( + getAssetBalance(DEFAULT_RECIPIENT_2), + (POOL_DEPOSIT_AMOUNT * TEN_PERCENT * 4) / POOL_SCALAR + expectedRecipientAmount + ); + + //the reward manager should have half the funds remaining + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT); + } + + function test_eventIsEmittedUponUpdateRecipients() public { + //expect an emit + vm.expectEmit(); + + //emit the event that is expected to be emitted + emit RewardRecipientsUpdated(PRIMARY_POOL_ID, getPrimaryRecipients()); + + //expected recipient amount is 1/4 of the pool deposit + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //updating a recipient should force the funds to be paid out + updateRewardRecipients(PRIMARY_POOL_ID, getPrimaryRecipients(), ADMIN); + + //check each recipient received the correct amount + for (uint256 i; i < getPrimaryRecipients().length; i++) { + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(getPrimaryRecipients()[i].addr), expectedRecipientAmount); + } + } +} + +contract RewardManagerUpdateRewardRecipientsMultiplePoolsTest is BaseRewardManagerTest { + uint256 internal constant POOL_DEPOSIT_AMOUNT = 10e18; + + function setUp() public override { + //setup contracts + super.setUp(); + + //create a single pool for these tests + createPrimaryPool(); + createSecondaryPool(); + + //add funds to the pool to be split among the recipients + addFundsToPool(PRIMARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + addFundsToPool(SECONDARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + } + + function getSecondaryRecipients() public override returns (Common.AddressAndWeight[] memory) { + //for testing purposes, the primary and secondary pool to contain the same recipients + return getPrimaryRecipients(); + } + + function test_updatePrimaryRecipientWeights() public { + //expected recipient amount is 1/4 of the pool deposit for original recipients + uint256 expectedRecipientAmount = POOL_DEPOSIT_AMOUNT / 4; + + //create a list of containing recipients from the primary configured set, and new recipients + Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](4); + recipients[0] = Common.AddressAndWeight(DEFAULT_RECIPIENT_1, TEN_PERCENT * 4); + recipients[1] = Common.AddressAndWeight(DEFAULT_RECIPIENT_2, TEN_PERCENT * 4); + recipients[2] = Common.AddressAndWeight(DEFAULT_RECIPIENT_3, TEN_PERCENT); + recipients[3] = Common.AddressAndWeight(DEFAULT_RECIPIENT_4, TEN_PERCENT); + + //updating a recipient should force the funds to be paid out for the primary recipients + updateRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN); + + //check each recipient received the correct amount + for (uint256 i; i < recipients.length; i++) { + //check the balance matches the ratio the recipient should have received + assertEq(getAssetBalance(recipients[i].addr), expectedRecipientAmount); + } + + //the reward manager should still have the funds for the secondary pool + assertEq(getAssetBalance(address(rewardManager)), POOL_DEPOSIT_AMOUNT); + + //add more funds to the pool to check new distribution + addFundsToPool(PRIMARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER); + + //claim the rewards for the updated recipients manually + claimRewards(PRIMARY_POOL_ARRAY, recipients[0].addr); + claimRewards(PRIMARY_POOL_ARRAY, recipients[1].addr); + claimRewards(PRIMARY_POOL_ARRAY, recipients[2].addr); + claimRewards(PRIMARY_POOL_ARRAY, recipients[3].addr); + + //check the balance matches the ratio the recipient who were updated should have received + assertEq( + getAssetBalance(recipients[0].addr), + (POOL_DEPOSIT_AMOUNT * TEN_PERCENT * 4) / POOL_SCALAR + expectedRecipientAmount + ); + assertEq( + getAssetBalance(recipients[1].addr), + (POOL_DEPOSIT_AMOUNT * TEN_PERCENT * 4) / POOL_SCALAR + expectedRecipientAmount + ); + assertEq( + getAssetBalance(recipients[2].addr), + (POOL_DEPOSIT_AMOUNT * TEN_PERCENT) / POOL_SCALAR + expectedRecipientAmount + ); + assertEq( + getAssetBalance(recipients[3].addr), + (POOL_DEPOSIT_AMOUNT * TEN_PERCENT) / POOL_SCALAR + expectedRecipientAmount + ); + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/BaseVerifierTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/BaseVerifierTest.t.sol new file mode 100644 index 00000000000..4d65414676e --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/BaseVerifierTest.t.sol @@ -0,0 +1,502 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import {Test} from "forge-std/Test.sol"; +import {VerifierProxy} from "../../VerifierProxy.sol"; +import {IERC165} from "../../../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; +import {IVerifier} from "../../interfaces/IVerifier.sol"; +import {ErroredVerifier} from "../mocks/ErroredVerifier.sol"; +import {Verifier} from "../../Verifier.sol"; +import {Strings} from "@openzeppelin/contracts/utils/Strings.sol"; +import {AccessControllerInterface} from "../../../../shared/interfaces/AccessControllerInterface.sol"; +import {FeeManager} from "../../FeeManager.sol"; +import {Common} from "../../../libraries/Common.sol"; +import {ERC20Mock} from "../../../../vendor/openzeppelin-solidity/v4.8.3/contracts/mocks/ERC20Mock.sol"; +import {WERC20Mock} from "../../../../shared/mocks/WERC20Mock.sol"; +import {RewardManager} from "../../RewardManager.sol"; + +contract BaseTest is Test { + uint256 internal constant MAX_ORACLES = 31; + address internal constant ADMIN = address(1); + address internal constant USER = address(2); + address internal constant MOCK_VERIFIER_ADDRESS = address(100); + address internal constant MOCK_VERIFIER_ADDRESS_TWO = address(200); + address internal constant ACCESS_CONTROLLER_ADDRESS = address(300); + + bytes32 internal constant V_MASK = 0x0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff; + bytes32 internal constant V1_BITMASK = 0x0001000000000000000000000000000000000000000000000000000000000000; + bytes32 internal constant V2_BITMASK = 0x0002000000000000000000000000000000000000000000000000000000000000; + bytes32 internal constant V3_BITMASK = 0x0003000000000000000000000000000000000000000000000000000000000000; + + //version 0 feeds + bytes32 internal constant FEED_ID = (keccak256("ETH-USD") & V_MASK) | V1_BITMASK; + bytes32 internal constant FEED_ID_2 = (keccak256("LINK-USD") & V_MASK) | V1_BITMASK; + bytes32 internal constant FEED_ID_3 = (keccak256("BTC-USD") & V_MASK) | V1_BITMASK; + + //version 3 feeds + bytes32 internal constant FEED_ID_V3 = (keccak256("ETH-USD") & V_MASK) | V3_BITMASK; + + bytes32 internal constant INVALID_FEED = keccak256("INVALID"); + uint32 internal constant OBSERVATIONS_TIMESTAMP = 1000; + uint64 internal constant BLOCKNUMBER_LOWER_BOUND = 1000; + uint64 internal constant BLOCKNUMBER_UPPER_BOUND = BLOCKNUMBER_LOWER_BOUND + 5; + int192 internal constant MEDIAN = 1 ether; + int192 internal constant BID = 500000000 gwei; + int192 internal constant ASK = 2 ether; + + bytes32 internal constant EMPTY_BYTES = bytes32(""); + + uint8 internal constant FAULT_TOLERANCE = 10; + uint64 internal constant VERIFIER_VERSION = 1; + + string internal constant SERVER_URL = "https://mercury.server/client/"; + uint8 internal constant MAX_COMMITMENT_DELAY = 5; + + VerifierProxy internal s_verifierProxy; + Verifier internal s_verifier; + Verifier internal s_verifier_2; + ErroredVerifier internal s_erroredVerifier; + + struct Signer { + uint256 mockPrivateKey; + address signerAddress; + } + + struct V1Report { + // The feed ID the report has data for + bytes32 feedId; + // The time the median value was observed on + uint32 observationsTimestamp; + // The median value agreed in an OCR round + int192 median; + // The best bid value agreed in an OCR round + int192 bid; + // The best ask value agreed in an OCR round + int192 ask; + // The upper bound of the block range the median value was observed within + uint64 blocknumberUpperBound; + // The blockhash for the upper bound of block range (ensures correct blockchain) + bytes32 upperBlockhash; + // The lower bound of the block range the median value was observed within + uint64 blocknumberLowerBound; + // The current block timestamp + uint64 currentBlockTimestamp; + } + + Signer[MAX_ORACLES] internal s_signers; + bytes32[] internal s_offchaintransmitters; + bool private s_baseTestInitialized; + + function setUp() public virtual { + // BaseTest.setUp is often called multiple times from tests' setUp due to inheritance. + if (s_baseTestInitialized) return; + s_baseTestInitialized = true; + + vm.startPrank(ADMIN); + vm.mockCall( + MOCK_VERIFIER_ADDRESS, + abi.encodeWithSelector(IERC165.supportsInterface.selector, IVerifier.verify.selector), + abi.encode(true) + ); + s_verifierProxy = new VerifierProxy(AccessControllerInterface(address(0))); + + s_verifier = new Verifier(address(s_verifierProxy)); + s_verifier_2 = new Verifier(address(s_verifierProxy)); + s_erroredVerifier = new ErroredVerifier(); + + for (uint256 i; i < MAX_ORACLES; i++) { + uint256 mockPK = i + 1; + s_signers[i].mockPrivateKey = mockPK; + s_signers[i].signerAddress = vm.addr(mockPK); + } + } + + function _getSigners(uint256 numSigners) internal view returns (Signer[] memory) { + Signer[] memory signers = new Signer[](numSigners); + for (uint256 i; i < numSigners; i++) { + signers[i] = s_signers[i]; + } + return signers; + } + + function _getSignerAddresses(Signer[] memory signers) internal view returns (address[] memory) { + address[] memory signerAddrs = new address[](signers.length); + for (uint256 i = 0; i < signerAddrs.length; i++) { + signerAddrs[i] = s_signers[i].signerAddress; + } + return signerAddrs; + } + + function _generateSignerSignatures( + bytes memory report, + bytes32[3] memory reportContext, + Signer[] memory signers + ) internal pure returns (bytes32[] memory rawRs, bytes32[] memory rawSs, bytes32 rawVs) { + bytes32[] memory rs = new bytes32[](signers.length); + bytes32[] memory ss = new bytes32[](signers.length); + bytes memory vs = new bytes(signers.length); + + bytes32 hash = keccak256(abi.encodePacked(keccak256(report), reportContext)); + + for (uint256 i = 0; i < signers.length; i++) { + (uint8 v, bytes32 r, bytes32 s) = vm.sign(signers[i].mockPrivateKey, hash); + rs[i] = r; + ss[i] = s; + vs[i] = bytes1(v - 27); + } + return (rs, ss, bytes32(vs)); + } + + function _encodeReport(V1Report memory report) internal pure returns (bytes memory) { + return + abi.encode( + report.feedId, + report.observationsTimestamp, + report.median, + report.bid, + report.ask, + report.blocknumberUpperBound, + report.upperBlockhash, + report.blocknumberLowerBound, + report.currentBlockTimestamp + ); + } + + function _generateV1EncodedBlob( + V1Report memory report, + bytes32[3] memory reportContext, + Signer[] memory signers + ) internal pure returns (bytes memory) { + bytes memory reportBytes = _encodeReport(report); + (bytes32[] memory rs, bytes32[] memory ss, bytes32 rawVs) = _generateSignerSignatures( + reportBytes, + reportContext, + signers + ); + return abi.encode(reportContext, reportBytes, rs, ss, rawVs); + } + + function _configDigestFromConfigData( + bytes32 feedId, + uint256 chainId, + address verifierAddr, + uint64 configCount, + address[] memory signers, + bytes32[] memory offchainTransmitters, + uint8 f, + bytes memory onchainConfig, + uint64 offchainConfigVersion, + bytes memory offchainConfig + ) internal pure returns (bytes32) { + uint256 h = uint256( + keccak256( + abi.encode( + feedId, + chainId, + verifierAddr, + configCount, + signers, + offchainTransmitters, + f, + onchainConfig, + offchainConfigVersion, + offchainConfig + ) + ) + ); + uint256 prefixMask = type(uint256).max << (256 - 16); // 0xFFFF00..00 + uint256 prefix = 0x0006 << (256 - 16); // 0x000600..00 + return bytes32((prefix & prefixMask) | (h & ~prefixMask)); + } + + function _createV1Report( + bytes32 feedId, + uint32 observationsTimestamp, + int192 median, + int192 bid, + int192 ask, + uint64 blocknumberUpperBound, + bytes32 upperBlockhash, + uint64 blocknumberLowerBound, + uint32 currentBlockTimestamp + ) internal pure returns (V1Report memory) { + return + V1Report({ + feedId: feedId, + observationsTimestamp: observationsTimestamp, + median: median, + bid: bid, + ask: ask, + blocknumberUpperBound: blocknumberUpperBound, + upperBlockhash: upperBlockhash, + blocknumberLowerBound: blocknumberLowerBound, + currentBlockTimestamp: currentBlockTimestamp + }); + } + + function _ccipReadURL(bytes32 feedId, uint256 commitmentBlock) internal pure returns (string memory url) { + return + string( + abi.encodePacked( + SERVER_URL, + "?feedIDHex=", + Strings.toHexString(uint256(feedId)), + "&L2Blocknumber=", + Strings.toString(commitmentBlock) + ) + ); + } +} + +contract BaseTestWithConfiguredVerifierAndFeeManager is BaseTest { + FeeManager internal feeManager; + RewardManager internal rewardManager; + ERC20Mock internal link; + WERC20Mock internal native; + + uint256 internal constant DEFAULT_REPORT_LINK_FEE = 1e10; + uint256 internal constant DEFAULT_REPORT_NATIVE_FEE = 1e12; + + bytes32 internal v1ConfigDigest; + bytes32 internal v3ConfigDigest; + + struct V3Report { + // The feed ID the report has data for + bytes32 feedId; + // The time the median value was observed on + uint32 observationsTimestamp; + // The timestamp the report is valid from + uint32 validFromTimestamp; + // The link fee + uint192 linkFee; + // The native fee + uint192 nativeFee; + // The expiry of the report + uint32 expiresAt; + // The median value agreed in an OCR round + int192 benchmarkPrice; + // The best bid value agreed in an OCR round + int192 bid; + // The best ask value agreed in an OCR round + int192 ask; + } + + function setUp() public virtual override { + BaseTest.setUp(); + Signer[] memory signers = _getSigners(MAX_ORACLES); + + s_verifierProxy.initializeVerifier(address(s_verifier)); + s_verifier.setConfig( + FEED_ID, + _getSignerAddresses(signers), + s_offchaintransmitters, + FAULT_TOLERANCE, + bytes(""), + VERIFIER_VERSION, + bytes(""), + new Common.AddressAndWeight[](0) + ); + (, , v1ConfigDigest) = s_verifier.latestConfigDetails(FEED_ID); + + s_verifier.setConfig( + FEED_ID_V3, + _getSignerAddresses(signers), + s_offchaintransmitters, + FAULT_TOLERANCE, + bytes(""), + VERIFIER_VERSION, + bytes(""), + new Common.AddressAndWeight[](0) + ); + (, , v3ConfigDigest) = s_verifier.latestConfigDetails(FEED_ID_V3); + + link = new ERC20Mock("LINK", "LINK", ADMIN, 0); + native = new WERC20Mock(); + + rewardManager = new RewardManager(address(link)); + feeManager = new FeeManager(address(link), address(native), address(s_verifierProxy), address(rewardManager)); + + s_verifierProxy.setFeeManager(feeManager); + rewardManager.setFeeManager(address(feeManager)); + } + + function _encodeReport(V3Report memory report) internal pure returns (bytes memory) { + return + abi.encode( + report.feedId, + report.observationsTimestamp, + report.validFromTimestamp, + report.nativeFee, + report.linkFee, + report.expiresAt, + report.benchmarkPrice, + report.bid, + report.ask + ); + } + + function _generateV3EncodedBlob( + V3Report memory report, + bytes32[3] memory reportContext, + Signer[] memory signers + ) internal pure returns (bytes memory) { + bytes memory reportBytes = _encodeReport(report); + (bytes32[] memory rs, bytes32[] memory ss, bytes32 rawVs) = _generateSignerSignatures( + reportBytes, + reportContext, + signers + ); + return abi.encode(reportContext, reportBytes, rs, ss, rawVs); + } + + function _generateV1Report() internal view returns (V1Report memory) { + return + _createV1Report( + FEED_ID, + OBSERVATIONS_TIMESTAMP, + MEDIAN, + BID, + ASK, + BLOCKNUMBER_UPPER_BOUND, + bytes32(blockhash(BLOCKNUMBER_UPPER_BOUND)), + BLOCKNUMBER_LOWER_BOUND, + uint32(block.timestamp) + ); + } + + function _generateV3Report() internal view returns (V3Report memory) { + return + V3Report({ + feedId: FEED_ID_V3, + observationsTimestamp: OBSERVATIONS_TIMESTAMP, + validFromTimestamp: uint32(block.timestamp), + nativeFee: uint192(DEFAULT_REPORT_NATIVE_FEE), + linkFee: uint192(DEFAULT_REPORT_LINK_FEE), + expiresAt: uint32(block.timestamp), + benchmarkPrice: MEDIAN, + bid: BID, + ask: ASK + }); + } + + function _generateReportContext(bytes32 configDigest) internal pure returns (bytes32[3] memory) { + bytes32[3] memory reportContext; + reportContext[0] = configDigest; + reportContext[1] = bytes32(abi.encode(uint32(5), uint8(1))); + return reportContext; + } + + function _approveLink(address spender, uint256 quantity, address sender) internal { + address originalAddr = msg.sender; + changePrank(sender); + + link.approve(spender, quantity); + changePrank(originalAddr); + } + + function _approveNative(address spender, uint256 quantity, address sender) internal { + address originalAddr = msg.sender; + changePrank(sender); + + native.approve(spender, quantity); + changePrank(originalAddr); + } + + function _verify(bytes memory payload, address feeAddress, uint256 wrappedNativeValue, address sender) internal { + address originalAddr = msg.sender; + changePrank(sender); + + s_verifierProxy.verify{value: wrappedNativeValue}(payload, abi.encode(feeAddress)); + + changePrank(originalAddr); + } + + function _verifyBulk( + bytes[] memory payload, + address feeAddress, + uint256 wrappedNativeValue, + address sender + ) internal { + address originalAddr = msg.sender; + changePrank(sender); + + s_verifierProxy.verifyBulk{value: wrappedNativeValue}(payload, abi.encode(feeAddress)); + + changePrank(originalAddr); + } +} + +contract BaseTestWithMultipleConfiguredDigests is BaseTestWithConfiguredVerifierAndFeeManager { + bytes32 internal s_configDigestOne; + bytes32 internal s_configDigestTwo; + bytes32 internal s_configDigestThree; + bytes32 internal s_configDigestFour; + bytes32 internal s_configDigestFive; + + uint32 internal s_numConfigsSet; + + uint8 internal constant FAULT_TOLERANCE_TWO = 2; + uint8 internal constant FAULT_TOLERANCE_THREE = 1; + + function setUp() public virtual override { + BaseTestWithConfiguredVerifierAndFeeManager.setUp(); + Signer[] memory signers = _getSigners(MAX_ORACLES); + + (, , s_configDigestOne) = s_verifier.latestConfigDetails(FEED_ID); + + // Verifier 1, Feed 1, Config 2 + Signer[] memory secondSetOfSigners = _getSigners(8); + s_verifier.setConfig( + FEED_ID, + _getSignerAddresses(secondSetOfSigners), + s_offchaintransmitters, + FAULT_TOLERANCE_TWO, + bytes(""), + 2, + bytes(""), + new Common.AddressAndWeight[](0) + ); + (, , s_configDigestTwo) = s_verifier.latestConfigDetails(FEED_ID); + + // Verifier 1, Feed 1, Config 3 + Signer[] memory thirdSetOfSigners = _getSigners(5); + s_verifier.setConfig( + FEED_ID, + _getSignerAddresses(thirdSetOfSigners), + s_offchaintransmitters, + FAULT_TOLERANCE_THREE, + bytes(""), + 3, + bytes(""), + new Common.AddressAndWeight[](0) + ); + (s_numConfigsSet, , s_configDigestThree) = s_verifier.latestConfigDetails(FEED_ID); + + // Verifier 1, Feed 2, Config 1 + s_verifier.setConfig( + FEED_ID_2, + _getSignerAddresses(signers), + s_offchaintransmitters, + FAULT_TOLERANCE, + bytes(""), + 4, + bytes(""), + new Common.AddressAndWeight[](0) + ); + (, , s_configDigestFour) = s_verifier.latestConfigDetails(FEED_ID_2); + + // Verifier 2, Feed 3, Config 1 + s_verifierProxy.initializeVerifier(address(s_verifier_2)); + s_verifier_2.setConfig( + FEED_ID_3, + _getSignerAddresses(signers), + s_offchaintransmitters, + FAULT_TOLERANCE, + bytes(""), + VERIFIER_VERSION, + bytes(""), + new Common.AddressAndWeight[](0) + ); + (, , s_configDigestFive) = s_verifier_2.latestConfigDetails(FEED_ID_3); + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierActivateConfigTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierActivateConfigTest.t.sol new file mode 100644 index 00000000000..99daabe206b --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierActivateConfigTest.t.sol @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import {BaseTestWithConfiguredVerifierAndFeeManager, BaseTestWithMultipleConfiguredDigests} from "./BaseVerifierTest.t.sol"; +import {Verifier} from "../../../v0.3.0/Verifier.sol"; + +contract VerifierActivateConfigTest is BaseTestWithConfiguredVerifierAndFeeManager { + function test_revertsIfNotOwner() public { + vm.expectRevert("Only callable by owner"); + + changePrank(address(s_verifierProxy)); + s_verifier.activateConfig(FEED_ID, bytes32("mock")); + } + + function test_revertsIfDigestIsEmpty() public { + vm.expectRevert(abi.encodeWithSelector(Verifier.DigestEmpty.selector)); + s_verifier.activateConfig(FEED_ID, bytes32("")); + } + + function test_revertsIfDigestNotSet() public { + vm.expectRevert(abi.encodeWithSelector(Verifier.DigestNotSet.selector, FEED_ID, bytes32("non-existent-digest"))); + s_verifier.activateConfig(FEED_ID, bytes32("non-existent-digest")); + } +} + +contract VerifierActivateConfigWithDeactivatedConfigTest is BaseTestWithMultipleConfiguredDigests { + bytes32[3] internal s_reportContext; + + event ConfigActivated(bytes32 configDigest); + + V1Report internal s_testReportOne; + + function setUp() public override { + BaseTestWithMultipleConfiguredDigests.setUp(); + s_reportContext[0] = s_configDigestTwo; + s_reportContext[1] = bytes32(abi.encode(uint32(5), uint8(1))); + s_testReportOne = _createV1Report( + FEED_ID, + uint32(block.timestamp), + MEDIAN, + BID, + ASK, + uint64(block.number), + blockhash(block.number + 3), + uint64(block.number + 3), + uint32(block.timestamp) + ); + + s_verifier.deactivateConfig(FEED_ID, s_configDigestTwo); + } + + function test_allowsVerification() public { + s_verifier.activateConfig(FEED_ID, s_configDigestTwo); + changePrank(address(s_verifierProxy)); + + bytes memory signedReport = _generateV1EncodedBlob( + s_testReportOne, + s_reportContext, + _getSigners(FAULT_TOLERANCE_TWO + 1) + ); + s_verifier.verify(signedReport, msg.sender); + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierDeactivateFeedTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierDeactivateFeedTest.t.sol new file mode 100644 index 00000000000..fb52c1c93e7 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierDeactivateFeedTest.t.sol @@ -0,0 +1,108 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import {BaseTestWithConfiguredVerifierAndFeeManager, BaseTestWithMultipleConfiguredDigests} from "./BaseVerifierTest.t.sol"; +import {Verifier} from "../../../v0.3.0/Verifier.sol"; + +contract VerifierActivateFeedTest is BaseTestWithConfiguredVerifierAndFeeManager { + function test_revertsIfNotOwnerActivateFeed() public { + changePrank(address(s_verifierProxy)); + vm.expectRevert("Only callable by owner"); + s_verifier.activateFeed(FEED_ID); + } + + function test_revertsIfNotOwnerDeactivateFeed() public { + changePrank(address(s_verifierProxy)); + vm.expectRevert("Only callable by owner"); + s_verifier.deactivateFeed(FEED_ID); + } + + function test_revertsIfNoFeedExistsActivate() public { + vm.expectRevert(abi.encodeWithSelector(Verifier.InvalidFeed.selector, INVALID_FEED)); + s_verifier.activateFeed(INVALID_FEED); + } + + function test_revertsIfNoFeedExistsDeactivate() public { + vm.expectRevert(abi.encodeWithSelector(Verifier.InvalidFeed.selector, INVALID_FEED)); + s_verifier.deactivateFeed(INVALID_FEED); + } +} + +contract VerifierDeactivateFeedWithVerifyTest is BaseTestWithMultipleConfiguredDigests { + bytes32[3] internal s_reportContext; + + event ConfigActivated(bytes32 configDigest); + + V1Report internal s_testReportOne; + + function setUp() public override { + BaseTestWithMultipleConfiguredDigests.setUp(); + s_reportContext[0] = s_configDigestOne; + s_reportContext[1] = bytes32(abi.encode(uint32(5), uint8(1))); + s_testReportOne = _createV1Report( + FEED_ID, + uint32(block.timestamp), + MEDIAN, + BID, + ASK, + uint64(block.number), + blockhash(block.number + 3), + uint64(block.number + 3), + uint32(block.timestamp) + ); + + s_verifier.deactivateFeed(FEED_ID); + } + + function test_currentReportAllowsVerification() public { + s_verifier.activateFeed(FEED_ID); + changePrank(address(s_verifierProxy)); + + bytes memory signedReport = _generateV1EncodedBlob( + s_testReportOne, + s_reportContext, + _getSigners(FAULT_TOLERANCE + 1) + ); + s_verifier.verify(signedReport, msg.sender); + } + + function test_previousReportAllowsVerification() public { + s_verifier.activateFeed(FEED_ID); + changePrank(address(s_verifierProxy)); + + s_reportContext[0] = s_configDigestTwo; + bytes memory signedReport = _generateV1EncodedBlob( + s_testReportOne, + s_reportContext, + _getSigners(FAULT_TOLERANCE_TWO + 1) + ); + s_verifier.verify(signedReport, msg.sender); + } + + function test_currentReportFailsVerification() public { + changePrank(address(s_verifierProxy)); + + bytes memory signedReport = _generateV1EncodedBlob( + s_testReportOne, + s_reportContext, + _getSigners(FAULT_TOLERANCE + 1) + ); + + vm.expectRevert(abi.encodeWithSelector(Verifier.InactiveFeed.selector, FEED_ID)); + s_verifier.verify(signedReport, msg.sender); + } + + function test_previousReportFailsVerification() public { + changePrank(address(s_verifierProxy)); + + s_reportContext[0] = s_configDigestTwo; + bytes memory signedReport = _generateV1EncodedBlob( + s_testReportOne, + s_reportContext, + _getSigners(FAULT_TOLERANCE_TWO + 1) + ); + + vm.expectRevert(abi.encodeWithSelector(Verifier.InactiveFeed.selector, FEED_ID)); + s_verifier.verify(signedReport, msg.sender); + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierProxyConstructorTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierProxyConstructorTest.t.sol new file mode 100644 index 00000000000..82efd8907be --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierProxyConstructorTest.t.sol @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import {BaseTest} from "./BaseVerifierTest.t.sol"; +import {VerifierProxy} from "../../../v0.3.0/VerifierProxy.sol"; +import {AccessControllerInterface} from "../../../../shared/interfaces/AccessControllerInterface.sol"; + +contract VerifierProxyConstructorTest is BaseTest { + function test_correctlySetsTheOwner() public { + VerifierProxy proxy = new VerifierProxy(AccessControllerInterface(address(0))); + assertEq(proxy.owner(), ADMIN); + } + + function test_correctlySetsTheCorrectAccessControllerInterface() public { + address accessControllerAddr = address(1234); + VerifierProxy proxy = new VerifierProxy(AccessControllerInterface(accessControllerAddr)); + assertEq(address(proxy.s_accessController()), accessControllerAddr); + } + + function test_correctlySetsVersion() public view { + string memory version = s_verifierProxy.typeAndVersion(); + assertEq(version, "VerifierProxy 2.0.0"); + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierProxyInitializeVerifierTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierProxyInitializeVerifierTest.t.sol new file mode 100644 index 00000000000..5537d273be9 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierProxyInitializeVerifierTest.t.sol @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import {BaseTest} from "./BaseVerifierTest.t.sol"; +import {VerifierProxy} from "../../../v0.3.0/VerifierProxy.sol"; + +contract VerifierProxyInitializeVerifierTest is BaseTest { + bytes32 latestDigest; + + function setUp() public override { + BaseTest.setUp(); + } + + function test_revertsIfNotOwner() public { + changePrank(USER); + vm.expectRevert("Only callable by owner"); + s_verifierProxy.initializeVerifier(address(s_verifier)); + } + + function test_revertsIfZeroAddress() public { + vm.expectRevert(abi.encodeWithSelector(VerifierProxy.ZeroAddress.selector)); + s_verifierProxy.initializeVerifier(address(0)); + } + + function test_revertsIfVerifierAlreadyInitialized() public { + s_verifierProxy.initializeVerifier(address(s_verifier)); + vm.expectRevert(abi.encodeWithSelector(VerifierProxy.VerifierAlreadyInitialized.selector, address(s_verifier))); + s_verifierProxy.initializeVerifier(address(s_verifier)); + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierProxySetAccessControllerTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierProxySetAccessControllerTest.t.sol new file mode 100644 index 00000000000..03bd6d97ee5 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierProxySetAccessControllerTest.t.sol @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import {BaseTest} from "./BaseVerifierTest.t.sol"; +import {AccessControllerInterface} from "../../../../shared/interfaces/AccessControllerInterface.sol"; + +contract VerifierProxySetAccessControllerTest is BaseTest { + event AccessControllerSet(address oldAccessController, address newAccessController); + + function test_revertsIfCalledByNonOwner() public { + vm.expectRevert("Only callable by owner"); + + changePrank(USER); + s_verifierProxy.setAccessController(AccessControllerInterface(ACCESS_CONTROLLER_ADDRESS)); + } + + function test_successfullySetsNewAccessController() public { + s_verifierProxy.setAccessController(AccessControllerInterface(ACCESS_CONTROLLER_ADDRESS)); + AccessControllerInterface ac = s_verifierProxy.s_accessController(); + assertEq(address(ac), ACCESS_CONTROLLER_ADDRESS); + } + + function test_successfullySetsNewAccessControllerIsEmpty() public { + s_verifierProxy.setAccessController(AccessControllerInterface(address(0))); + AccessControllerInterface ac = s_verifierProxy.s_accessController(); + assertEq(address(ac), address(0)); + } + + function test_emitsTheCorrectEvent() public { + vm.expectEmit(true, false, false, false); + emit AccessControllerSet(address(0), ACCESS_CONTROLLER_ADDRESS); + s_verifierProxy.setAccessController(AccessControllerInterface(ACCESS_CONTROLLER_ADDRESS)); + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierProxySetVerifierTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierProxySetVerifierTest.t.sol new file mode 100644 index 00000000000..78e5ff0766f --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierProxySetVerifierTest.t.sol @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import {BaseTestWithConfiguredVerifierAndFeeManager} from "./BaseVerifierTest.t.sol"; +import {IVerifier} from "../../interfaces/IVerifier.sol"; +import {VerifierProxy} from "../../../v0.3.0/VerifierProxy.sol"; +import {IERC165} from "../../../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; +import {Common} from "../../../libraries/Common.sol"; + +contract VerifierProxyInitializeVerifierTest is BaseTestWithConfiguredVerifierAndFeeManager { + function test_revertsIfNotCorrectVerifier() public { + vm.expectRevert(abi.encodeWithSelector(VerifierProxy.AccessForbidden.selector)); + s_verifierProxy.setVerifier(bytes32("prev-config"), bytes32("new-config"), new Common.AddressAndWeight[](0)); + } + + function test_revertsIfDigestAlreadySet() public { + (, , bytes32 takenDigest) = s_verifier.latestConfigDetails(FEED_ID); + + address maliciousVerifier = address(666); + bytes32 maliciousDigest = bytes32("malicious-digest"); + vm.mockCall( + maliciousVerifier, + abi.encodeWithSelector(IERC165.supportsInterface.selector, IVerifier.verify.selector), + abi.encode(true) + ); + s_verifierProxy.initializeVerifier(maliciousVerifier); + vm.expectRevert( + abi.encodeWithSelector(VerifierProxy.ConfigDigestAlreadySet.selector, takenDigest, address(s_verifier)) + ); + changePrank(address(maliciousVerifier)); + s_verifierProxy.setVerifier(maliciousDigest, takenDigest, new Common.AddressAndWeight[](0)); + } + + function test_updatesVerifierIfVerifier() public { + (, , bytes32 prevDigest) = s_verifier.latestConfigDetails(FEED_ID); + changePrank(address(s_verifier)); + s_verifierProxy.setVerifier(prevDigest, bytes32("new-config"), new Common.AddressAndWeight[](0)); + assertEq(s_verifierProxy.getVerifier(bytes32("new-config")), address(s_verifier)); + assertEq(s_verifierProxy.getVerifier(prevDigest), address(s_verifier)); + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierProxyTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierProxyTest.t.sol new file mode 100644 index 00000000000..ea7e02d7409 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierProxyTest.t.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import {BaseTestWithConfiguredVerifierAndFeeManager} from "./BaseVerifierTest.t.sol"; +import {VerifierProxy} from "../../VerifierProxy.sol"; +import {FeeManager} from "../../FeeManager.sol"; + +contract VerifierProxyInitializeVerifierTest is BaseTestWithConfiguredVerifierAndFeeManager { + function test_setFeeManagerZeroAddress() public { + vm.expectRevert(abi.encodeWithSelector(VerifierProxy.ZeroAddress.selector)); + s_verifierProxy.setFeeManager(FeeManager(address(0))); + } + + function test_setFeeManagerWhichDoesntHonourInterface() public { + vm.expectRevert(abi.encodeWithSelector(VerifierProxy.FeeManagerInvalid.selector)); + s_verifierProxy.setFeeManager(FeeManager(address(s_verifier))); + } + + function test_setFeeManagerWhichDoesntHonourIERC165Interface() public { + vm.expectRevert(); + s_verifierProxy.setFeeManager(FeeManager(address(1))); + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierProxyUnsetVerifierTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierProxyUnsetVerifierTest.t.sol new file mode 100644 index 00000000000..a51c67e336c --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierProxyUnsetVerifierTest.t.sol @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import {BaseTest, BaseTestWithConfiguredVerifierAndFeeManager} from "./BaseVerifierTest.t.sol"; +import {VerifierProxy} from "../../../v0.3.0/VerifierProxy.sol"; + +contract VerifierProxyUnsetVerifierTest is BaseTest { + function test_revertsIfNotAdmin() public { + vm.expectRevert("Only callable by owner"); + + changePrank(USER); + s_verifierProxy.unsetVerifier(bytes32("")); + } + + function test_revertsIfDigestDoesNotExist() public { + vm.expectRevert(abi.encodeWithSelector(VerifierProxy.VerifierNotFound.selector, bytes32(""))); + s_verifierProxy.unsetVerifier(bytes32("")); + } +} + +contract VerifierProxyUnsetVerifierWithPreviouslySetVerifierTest is BaseTestWithConfiguredVerifierAndFeeManager { + bytes32 internal s_configDigest; + + event VerifierUnset(bytes32 configDigest, address verifierAddr); + + function setUp() public override { + BaseTestWithConfiguredVerifierAndFeeManager.setUp(); + (, , s_configDigest) = s_verifier.latestConfigDetails(FEED_ID); + } + + function test_correctlyUnsetsVerifier() public { + s_verifierProxy.unsetVerifier(s_configDigest); + address verifierAddr = s_verifierProxy.getVerifier(s_configDigest); + assertEq(verifierAddr, address(0)); + } + + function test_emitsAnEventAfterUnsettingVerifier() public { + vm.expectEmit(true, false, false, false); + emit VerifierUnset(s_configDigest, address(s_verifier)); + s_verifierProxy.unsetVerifier(s_configDigest); + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierSetConfigFromSourceTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierSetConfigFromSourceTest.t.sol new file mode 100644 index 00000000000..9ee9b5272a7 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierSetConfigFromSourceTest.t.sol @@ -0,0 +1,134 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import {BaseTest, BaseTestWithMultipleConfiguredDigests} from "./BaseVerifierTest.t.sol"; +import {Common} from "../../../libraries/Common.sol"; + +contract VerifierSetConfigFromSourceTest is BaseTest { + function setUp() public virtual override { + BaseTest.setUp(); + } + + function test_revertsIfCalledByNonOwner() public { + vm.expectRevert("Only callable by owner"); + Signer[] memory signers = _getSigners(MAX_ORACLES); + + changePrank(USER); + s_verifier.setConfigFromSource( + FEED_ID, + 12345, + address(12345), + 0, + _getSignerAddresses(signers), + s_offchaintransmitters, + FAULT_TOLERANCE, + bytes(""), + VERIFIER_VERSION, + bytes(""), + new Common.AddressAndWeight[](0) + ); + } +} + +contract VerifierSetConfigFromSourceMultipleDigestsTest is BaseTestWithMultipleConfiguredDigests { + function test_correctlyUpdatesTheDigestInTheProxy() public { + Signer[] memory newSigners = _getSigners(15); + + s_verifier.setConfigFromSource( + FEED_ID, + 12345, + address(12345), + 0, + _getSignerAddresses(newSigners), + s_offchaintransmitters, + 4, + bytes(""), + VERIFIER_VERSION, + bytes(""), + new Common.AddressAndWeight[](0) + ); + + (, , bytes32 configDigest) = s_verifier.latestConfigDetails(FEED_ID); + address verifierAddr = s_verifierProxy.getVerifier(configDigest); + assertEq(verifierAddr, address(s_verifier)); + } + + function test_correctlyUpdatesDigestsOnMultipleVerifiersInTheProxy() public { + Signer[] memory newSigners = _getSigners(15); + + s_verifier.setConfigFromSource( + FEED_ID_2, + 12345, + address(12345), + 0, + _getSignerAddresses(newSigners), + s_offchaintransmitters, + 4, + bytes(""), + VERIFIER_VERSION, + bytes(""), + new Common.AddressAndWeight[](0) + ); + + (, , bytes32 configDigest) = s_verifier.latestConfigDetails(FEED_ID_2); + address verifierAddr = s_verifierProxy.getVerifier(configDigest); + assertEq(verifierAddr, address(s_verifier)); + + s_verifier_2.setConfigFromSource( + FEED_ID_3, + 12345, + address(12345), + 0, + _getSignerAddresses(newSigners), + s_offchaintransmitters, + 4, + bytes(""), + VERIFIER_VERSION, + bytes(""), + new Common.AddressAndWeight[](0) + ); + + (, , bytes32 configDigest2) = s_verifier_2.latestConfigDetails(FEED_ID_3); + address verifierAddr2 = s_verifierProxy.getVerifier(configDigest2); + assertEq(verifierAddr2, address(s_verifier_2)); + } + + function test_correctlySetsConfigWhenDigestsAreRemoved() public { + s_verifier.deactivateConfig(FEED_ID, s_configDigestTwo); + + Signer[] memory newSigners = _getSigners(15); + + s_verifier.setConfigFromSource( + FEED_ID, + 12345, + address(s_verifier), + 0, + _getSignerAddresses(newSigners), + s_offchaintransmitters, + 4, + bytes(""), + VERIFIER_VERSION, + bytes(""), + new Common.AddressAndWeight[](0) + ); + + bytes32 expectedConfigDigest = _configDigestFromConfigData( + FEED_ID, + 12345, + address(s_verifier), + s_numConfigsSet + 1, + _getSignerAddresses(newSigners), + s_offchaintransmitters, + 4, + bytes(""), + VERIFIER_VERSION, + bytes("") + ); + + (uint32 configCount, uint32 blockNumber, bytes32 configDigest) = s_verifier.latestConfigDetails(FEED_ID); + + assertEq(configCount, s_numConfigsSet + 1); + assertEq(blockNumber, block.number); + assertEq(configDigest, expectedConfigDigest); + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierSetConfigTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierSetConfigTest.t.sol new file mode 100644 index 00000000000..972ead81230 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierSetConfigTest.t.sol @@ -0,0 +1,243 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import {BaseTest, BaseTestWithMultipleConfiguredDigests} from "./BaseVerifierTest.t.sol"; +import {Verifier} from "../../../v0.3.0/Verifier.sol"; +import {Common} from "../../../libraries/Common.sol"; + +contract VerifierSetConfigTest is BaseTest { + function setUp() public virtual override { + BaseTest.setUp(); + } + + function test_revertsIfCalledByNonOwner() public { + vm.expectRevert("Only callable by owner"); + Signer[] memory signers = _getSigners(MAX_ORACLES); + + changePrank(USER); + s_verifier.setConfig( + FEED_ID, + _getSignerAddresses(signers), + s_offchaintransmitters, + FAULT_TOLERANCE, + bytes(""), + VERIFIER_VERSION, + bytes(""), + new Common.AddressAndWeight[](0) + ); + } + + function test_revertsIfSetWithTooManySigners() public { + address[] memory signers = new address[](MAX_ORACLES + 1); + vm.expectRevert(abi.encodeWithSelector(Verifier.ExcessSigners.selector, signers.length, MAX_ORACLES)); + s_verifier.setConfig( + FEED_ID, + signers, + s_offchaintransmitters, + FAULT_TOLERANCE, + bytes(""), + VERIFIER_VERSION, + bytes(""), + new Common.AddressAndWeight[](0) + ); + } + + function test_revertsIfFaultToleranceIsZero() public { + vm.expectRevert(abi.encodeWithSelector(Verifier.FaultToleranceMustBePositive.selector)); + Signer[] memory signers = _getSigners(MAX_ORACLES); + s_verifier.setConfig( + FEED_ID, + _getSignerAddresses(signers), + s_offchaintransmitters, + 0, + bytes(""), + VERIFIER_VERSION, + bytes(""), + new Common.AddressAndWeight[](0) + ); + } + + function test_revertsIfNotEnoughSigners() public { + address[] memory signers = new address[](2); + signers[0] = address(1000); + signers[1] = address(1001); + + vm.expectRevert( + abi.encodeWithSelector(Verifier.InsufficientSigners.selector, signers.length, FAULT_TOLERANCE * 3 + 1) + ); + s_verifier.setConfig( + FEED_ID, + signers, + s_offchaintransmitters, + FAULT_TOLERANCE, + bytes(""), + VERIFIER_VERSION, + bytes(""), + new Common.AddressAndWeight[](0) + ); + } + + function test_revertsIfDuplicateSigners() public { + Signer[] memory signers = _getSigners(MAX_ORACLES); + address[] memory signerAddrs = _getSignerAddresses(signers); + signerAddrs[0] = signerAddrs[1]; + vm.expectRevert(abi.encodeWithSelector(Verifier.NonUniqueSignatures.selector)); + s_verifier.setConfig( + FEED_ID, + signerAddrs, + s_offchaintransmitters, + FAULT_TOLERANCE, + bytes(""), + VERIFIER_VERSION, + bytes(""), + new Common.AddressAndWeight[](0) + ); + } + + function test_revertsIfSignerContainsZeroAddress() public { + Signer[] memory signers = _getSigners(MAX_ORACLES); + address[] memory signerAddrs = _getSignerAddresses(signers); + signerAddrs[0] = address(0); + vm.expectRevert(abi.encodeWithSelector(Verifier.ZeroAddress.selector)); + s_verifier.setConfig( + FEED_ID, + signerAddrs, + s_offchaintransmitters, + FAULT_TOLERANCE, + bytes(""), + VERIFIER_VERSION, + bytes(""), + new Common.AddressAndWeight[](0) + ); + } + + function test_correctlyUpdatesTheConfig() public { + Signer[] memory signers = _getSigners(MAX_ORACLES); + + s_verifierProxy.initializeVerifier(address(s_verifier)); + s_verifier.setConfig( + FEED_ID, + _getSignerAddresses(signers), + s_offchaintransmitters, + FAULT_TOLERANCE, + bytes(""), + VERIFIER_VERSION, + bytes(""), + new Common.AddressAndWeight[](0) + ); + + bytes32 expectedConfigDigest = _configDigestFromConfigData( + FEED_ID, + block.chainid, + address(s_verifier), + 1, + _getSignerAddresses(signers), + s_offchaintransmitters, + FAULT_TOLERANCE, + bytes(""), + VERIFIER_VERSION, + bytes("") + ); + + (uint32 configCount, uint32 blockNumber, bytes32 configDigest) = s_verifier.latestConfigDetails(FEED_ID); + assertEq(configCount, 1); + assertEq(blockNumber, block.number); + assertEq(configDigest, expectedConfigDigest); + + (bool scanLogs, bytes32 configDigestTwo, uint32 epoch) = s_verifier.latestConfigDigestAndEpoch(FEED_ID); + assertEq(scanLogs, false); + assertEq(configDigestTwo, expectedConfigDigest); + assertEq(epoch, 0); + } +} + +contract VerifierSetConfigWhenThereAreMultipleDigestsTest is BaseTestWithMultipleConfiguredDigests { + function test_correctlyUpdatesTheDigestInTheProxy() public { + Signer[] memory newSigners = _getSigners(15); + + s_verifier.setConfig( + FEED_ID, + _getSignerAddresses(newSigners), + s_offchaintransmitters, + 4, + bytes(""), + VERIFIER_VERSION, + bytes(""), + new Common.AddressAndWeight[](0) + ); + + (, , bytes32 configDigest) = s_verifier.latestConfigDetails(FEED_ID); + address verifierAddr = s_verifierProxy.getVerifier(configDigest); + assertEq(verifierAddr, address(s_verifier)); + } + + function test_correctlyUpdatesDigestsOnMultipleVerifiersInTheProxy() public { + Signer[] memory newSigners = _getSigners(15); + + s_verifier.setConfig( + FEED_ID_2, + _getSignerAddresses(newSigners), + s_offchaintransmitters, + 4, + bytes(""), + VERIFIER_VERSION, + bytes(""), + new Common.AddressAndWeight[](0) + ); + + (, , bytes32 configDigest) = s_verifier.latestConfigDetails(FEED_ID_2); + address verifierAddr = s_verifierProxy.getVerifier(configDigest); + assertEq(verifierAddr, address(s_verifier)); + + s_verifier_2.setConfig( + FEED_ID_3, + _getSignerAddresses(newSigners), + s_offchaintransmitters, + 4, + bytes(""), + VERIFIER_VERSION, + bytes(""), + new Common.AddressAndWeight[](0) + ); + + (, , bytes32 configDigest2) = s_verifier_2.latestConfigDetails(FEED_ID_3); + address verifierAddr2 = s_verifierProxy.getVerifier(configDigest2); + assertEq(verifierAddr2, address(s_verifier_2)); + } + + function test_correctlySetsConfigWhenDigestsAreRemoved() public { + s_verifier.deactivateConfig(FEED_ID, s_configDigestTwo); + + Signer[] memory newSigners = _getSigners(15); + + s_verifier.setConfig( + FEED_ID, + _getSignerAddresses(newSigners), + s_offchaintransmitters, + 4, + bytes(""), + VERIFIER_VERSION, + bytes(""), + new Common.AddressAndWeight[](0) + ); + + bytes32 expectedConfigDigest = _configDigestFromConfigData( + FEED_ID, + block.chainid, + address(s_verifier), + s_numConfigsSet + 1, + _getSignerAddresses(newSigners), + s_offchaintransmitters, + 4, + bytes(""), + VERIFIER_VERSION, + bytes("") + ); + + (uint32 configCount, uint32 blockNumber, bytes32 configDigest) = s_verifier.latestConfigDetails(FEED_ID); + + assertEq(configCount, s_numConfigsSet + 1); + assertEq(blockNumber, block.number); + assertEq(configDigest, expectedConfigDigest); + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierTest.t.sol new file mode 100644 index 00000000000..81f65f0c6eb --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierTest.t.sol @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import {BaseTest} from "./BaseVerifierTest.t.sol"; +import {Verifier} from "../../../v0.3.0/Verifier.sol"; + +contract VerifierConstructorTest is BaseTest { + function test_revertsIfInitializedWithEmptyVerifierProxy() public { + vm.expectRevert(abi.encodeWithSelector(Verifier.ZeroAddress.selector)); + new Verifier(address(0)); + } + + function test_setsTheCorrectProperties() public { + Verifier v = new Verifier(address(s_verifierProxy)); + assertEq(v.owner(), ADMIN); + + (bool scanLogs, bytes32 configDigest, uint32 epoch) = v.latestConfigDigestAndEpoch(FEED_ID); + assertEq(scanLogs, false); + assertEq(configDigest, EMPTY_BYTES); + assertEq(epoch, 0); + + (uint32 configCount, uint32 blockNumber, bytes32 configDigestTwo) = v.latestConfigDetails(FEED_ID); + assertEq(configCount, 0); + assertEq(blockNumber, 0); + assertEq(configDigestTwo, EMPTY_BYTES); + + string memory typeAndVersion = s_verifier.typeAndVersion(); + assertEq(typeAndVersion, "Verifier 1.2.0"); + } +} + +contract VerifierSupportsInterfaceTest is BaseTest { + function test_falseIfIsNotCorrectInterface() public view { + bool isInterface = s_verifier.supportsInterface(bytes4("abcd")); + assertEq(isInterface, false); + } + + function test_trueIfIsCorrectInterface() public view { + bool isInterface = s_verifier.supportsInterface(Verifier.verify.selector); + assertEq(isInterface, true); + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierTestBillingReport.t.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierTestBillingReport.t.sol new file mode 100644 index 00000000000..ad67a239ba8 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierTestBillingReport.t.sol @@ -0,0 +1,218 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import {BaseTestWithConfiguredVerifierAndFeeManager} from "./BaseVerifierTest.t.sol"; + +contract VerifierTestWithConfiguredVerifierAndFeeManager is BaseTestWithConfiguredVerifierAndFeeManager { + uint256 internal constant DEFAULT_LINK_MINT_QUANTITY = 100 ether; + uint256 internal constant DEFAULT_NATIVE_MINT_QUANTITY = 100 ether; + + function setUp() public virtual override { + super.setUp(); + + //mint some tokens to the user + link.mint(USER, DEFAULT_LINK_MINT_QUANTITY); + native.mint(USER, DEFAULT_NATIVE_MINT_QUANTITY); + vm.deal(USER, DEFAULT_NATIVE_MINT_QUANTITY); + + //mint some link tokens to the feeManager pool + link.mint(address(feeManager), DEFAULT_REPORT_LINK_FEE); + } +} + +contract VerifierTestBillingReport is VerifierTestWithConfiguredVerifierAndFeeManager { + function test_verifyWithLink() public { + bytes memory signedReport = _generateV3EncodedBlob( + _generateV3Report(), + _generateReportContext(v3ConfigDigest), + _getSigners(FAULT_TOLERANCE + 1) + ); + + _approveLink(address(rewardManager), DEFAULT_REPORT_LINK_FEE, USER); + + _verify(signedReport, address(link), 0, USER); + + assertEq(link.balanceOf(USER), DEFAULT_LINK_MINT_QUANTITY - DEFAULT_REPORT_LINK_FEE); + } + + function test_verifyWithNative() public { + bytes memory signedReport = _generateV3EncodedBlob( + _generateV3Report(), + _generateReportContext(v3ConfigDigest), + _getSigners(FAULT_TOLERANCE + 1) + ); + + _approveNative(address(feeManager), DEFAULT_REPORT_NATIVE_FEE, USER); + + _verify(signedReport, address(native), 0, USER); + + assertEq(native.balanceOf(USER), DEFAULT_NATIVE_MINT_QUANTITY - DEFAULT_REPORT_NATIVE_FEE); + assertEq(link.balanceOf(address(rewardManager)), DEFAULT_REPORT_LINK_FEE); + } + + function test_verifyWithNativeUnwrapped() public { + bytes memory signedReport = _generateV3EncodedBlob( + _generateV3Report(), + _generateReportContext(v3ConfigDigest), + _getSigners(FAULT_TOLERANCE + 1) + ); + + _verify(signedReport, address(native), DEFAULT_REPORT_NATIVE_FEE, USER); + + assertEq(USER.balance, DEFAULT_NATIVE_MINT_QUANTITY - DEFAULT_REPORT_NATIVE_FEE); + assertEq(address(feeManager).balance, 0); + } + + function test_verifyWithNativeUnwrappedReturnsChange() public { + bytes memory signedReport = _generateV3EncodedBlob( + _generateV3Report(), + _generateReportContext(v3ConfigDigest), + _getSigners(FAULT_TOLERANCE + 1) + ); + + _verify(signedReport, address(native), DEFAULT_REPORT_NATIVE_FEE * 2, USER); + + assertEq(USER.balance, DEFAULT_NATIVE_MINT_QUANTITY - DEFAULT_REPORT_NATIVE_FEE); + assertEq(address(feeManager).balance, 0); + } +} + +contract VerifierBulkVerifyBillingReport is VerifierTestWithConfiguredVerifierAndFeeManager { + uint256 internal constant NUMBERS_OF_REPORTS = 5; + + function test_verifyWithBulkLink() public { + bytes memory signedReport = _generateV3EncodedBlob( + _generateV3Report(), + _generateReportContext(v3ConfigDigest), + _getSigners(FAULT_TOLERANCE + 1) + ); + + bytes[] memory signedReports = new bytes[](NUMBERS_OF_REPORTS); + for (uint256 i = 0; i < NUMBERS_OF_REPORTS; i++) { + signedReports[i] = signedReport; + } + + _approveLink(address(rewardManager), DEFAULT_REPORT_LINK_FEE * NUMBERS_OF_REPORTS, USER); + + _verifyBulk(signedReports, address(link), 0, USER); + + assertEq(link.balanceOf(USER), DEFAULT_LINK_MINT_QUANTITY - DEFAULT_REPORT_LINK_FEE * NUMBERS_OF_REPORTS); + assertEq(link.balanceOf(address(rewardManager)), DEFAULT_REPORT_LINK_FEE * NUMBERS_OF_REPORTS); + } + + function test_verifyWithBulkNative() public { + bytes memory signedReport = _generateV3EncodedBlob( + _generateV3Report(), + _generateReportContext(v3ConfigDigest), + _getSigners(FAULT_TOLERANCE + 1) + ); + + bytes[] memory signedReports = new bytes[](NUMBERS_OF_REPORTS); + for (uint256 i = 0; i < NUMBERS_OF_REPORTS; i++) { + signedReports[i] = signedReport; + } + + _approveNative(address(feeManager), DEFAULT_REPORT_NATIVE_FEE * NUMBERS_OF_REPORTS, USER); + + _verifyBulk(signedReports, address(native), 0, USER); + + assertEq(native.balanceOf(USER), DEFAULT_NATIVE_MINT_QUANTITY - DEFAULT_REPORT_NATIVE_FEE * NUMBERS_OF_REPORTS); + } + + function test_verifyWithBulkNativeUnwrapped() public { + bytes memory signedReport = _generateV3EncodedBlob( + _generateV3Report(), + _generateReportContext(v3ConfigDigest), + _getSigners(FAULT_TOLERANCE + 1) + ); + + bytes[] memory signedReports = new bytes[](NUMBERS_OF_REPORTS); + for (uint256 i; i < NUMBERS_OF_REPORTS; i++) { + signedReports[i] = signedReport; + } + + _verifyBulk(signedReports, address(native), DEFAULT_REPORT_NATIVE_FEE * NUMBERS_OF_REPORTS, USER); + + assertEq(USER.balance, DEFAULT_NATIVE_MINT_QUANTITY - DEFAULT_REPORT_NATIVE_FEE * 5); + assertEq(address(feeManager).balance, 0); + } + + function test_verifyWithBulkNativeUnwrappedReturnsChange() public { + bytes memory signedReport = _generateV3EncodedBlob( + _generateV3Report(), + _generateReportContext(v3ConfigDigest), + _getSigners(FAULT_TOLERANCE + 1) + ); + + bytes[] memory signedReports = new bytes[](NUMBERS_OF_REPORTS); + for (uint256 i = 0; i < NUMBERS_OF_REPORTS; i++) { + signedReports[i] = signedReport; + } + + _verifyBulk(signedReports, address(native), DEFAULT_REPORT_NATIVE_FEE * (NUMBERS_OF_REPORTS * 2), USER); + + assertEq(USER.balance, DEFAULT_NATIVE_MINT_QUANTITY - DEFAULT_REPORT_NATIVE_FEE * NUMBERS_OF_REPORTS); + assertEq(address(feeManager).balance, 0); + } + + function test_verifyMultiVersions() public { + bytes memory signedReportV1 = _generateV1EncodedBlob( + _generateV1Report(), + _generateReportContext(v1ConfigDigest), + _getSigners(FAULT_TOLERANCE + 1) + ); + + bytes memory signedReportV3 = _generateV3EncodedBlob( + _generateV3Report(), + _generateReportContext(v3ConfigDigest), + _getSigners(FAULT_TOLERANCE + 1) + ); + + bytes[] memory signedReports = new bytes[](3); + + signedReports[0] = signedReportV1; + signedReports[1] = signedReportV3; + signedReports[2] = signedReportV3; + + _approveLink(address(rewardManager), 2 * DEFAULT_REPORT_LINK_FEE, USER); + + _verifyBulk(signedReports, address(link), 0, USER); + + assertEq(link.balanceOf(USER), DEFAULT_LINK_MINT_QUANTITY - 2 * DEFAULT_REPORT_LINK_FEE); + assertEq(native.balanceOf(USER), DEFAULT_NATIVE_MINT_QUANTITY); + assertEq(link.balanceOf(address(rewardManager)), DEFAULT_REPORT_LINK_FEE * 2); + } + + function test_verifyMultiVersionsReturnsVerifiedReports() public { + bytes memory signedReportV1 = _generateV1EncodedBlob( + _generateV1Report(), + _generateReportContext(v1ConfigDigest), + _getSigners(FAULT_TOLERANCE + 1) + ); + + bytes memory signedReportV3 = _generateV3EncodedBlob( + _generateV3Report(), + _generateReportContext(v3ConfigDigest), + _getSigners(FAULT_TOLERANCE + 1) + ); + + bytes[] memory signedReports = new bytes[](3); + + signedReports[0] = signedReportV1; + signedReports[1] = signedReportV3; + signedReports[2] = signedReportV3; + + _approveLink(address(rewardManager), 2 * DEFAULT_REPORT_LINK_FEE, USER); + + address originalAddr = msg.sender; + changePrank(USER); + + bytes[] memory verifierReports = s_verifierProxy.verifyBulk{value: 0}(signedReports, abi.encode(link)); + + changePrank(originalAddr); + + assertEq(verifierReports[0], _encodeReport(_generateV1Report())); + assertEq(verifierReports[1], _encodeReport(_generateV3Report())); + assertEq(verifierReports[2], _encodeReport(_generateV3Report())); + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierUnsetConfigTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierUnsetConfigTest.t.sol new file mode 100644 index 00000000000..e192a2e9e08 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierUnsetConfigTest.t.sol @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import {BaseTestWithMultipleConfiguredDigests} from "./BaseVerifierTest.t.sol"; +import {Verifier} from "../../../v0.3.0/Verifier.sol"; + +contract VerificationdeactivateConfigWhenThereAreMultipleDigestsTest is BaseTestWithMultipleConfiguredDigests { + function test_revertsIfCalledByNonOwner() public { + vm.expectRevert("Only callable by owner"); + + changePrank(USER); + s_verifier.deactivateConfig(FEED_ID, bytes32("")); + } + + function test_revertsIfRemovingAnEmptyDigest() public { + vm.expectRevert(abi.encodeWithSelector(Verifier.DigestEmpty.selector)); + s_verifier.deactivateConfig(FEED_ID, bytes32("")); + } + + function test_revertsIfRemovingAnNonExistentDigest() public { + vm.expectRevert(abi.encodeWithSelector(Verifier.DigestNotSet.selector, FEED_ID, bytes32("mock-digest"))); + s_verifier.deactivateConfig(FEED_ID, bytes32("mock-digest")); + } + + function test_correctlyRemovesAMiddleDigest() public { + s_verifier.deactivateConfig(FEED_ID, s_configDigestTwo); + (, , bytes32 lastConfigDigest) = s_verifier.latestConfigDetails(FEED_ID); + assertEq(lastConfigDigest, s_configDigestThree); + } + + function test_correctlyRemovesTheFirstDigest() public { + s_verifier.deactivateConfig(FEED_ID, s_configDigestOne); + (, , bytes32 lastConfigDigest) = s_verifier.latestConfigDetails(FEED_ID); + assertEq(lastConfigDigest, s_configDigestThree); + } + + function test_correctlyUnsetsDigestsInSequence() public { + // Delete config digest 2 + s_verifier.deactivateConfig(FEED_ID, s_configDigestTwo); + (, , bytes32 lastConfigDigest) = s_verifier.latestConfigDetails(FEED_ID); + assertEq(lastConfigDigest, s_configDigestThree); + + // Delete config digest 1 + s_verifier.deactivateConfig(FEED_ID, s_configDigestOne); + (, , lastConfigDigest) = s_verifier.latestConfigDetails(FEED_ID); + assertEq(lastConfigDigest, s_configDigestThree); + + // Delete config digest 3 + vm.expectRevert( + abi.encodeWithSelector(Verifier.CannotDeactivateLatestConfig.selector, FEED_ID, s_configDigestThree) + ); + s_verifier.deactivateConfig(FEED_ID, s_configDigestThree); + (, , lastConfigDigest) = s_verifier.latestConfigDetails(FEED_ID); + assertEq(lastConfigDigest, s_configDigestThree); + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierVerifyTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierVerifyTest.t.sol new file mode 100644 index 00000000000..1c14ba974c0 --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierVerifyTest.t.sol @@ -0,0 +1,314 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import {BaseTestWithConfiguredVerifierAndFeeManager} from "./BaseVerifierTest.t.sol"; +import {Verifier} from "../../../v0.3.0/Verifier.sol"; +import {VerifierProxy} from "../../../v0.3.0/VerifierProxy.sol"; +import {AccessControllerInterface} from "../../../../shared/interfaces/AccessControllerInterface.sol"; +import {Common} from "../../../libraries/Common.sol"; + +contract VerifierVerifyTest is BaseTestWithConfiguredVerifierAndFeeManager { + bytes32[3] internal s_reportContext; + + event ReportVerified(bytes32 indexed feedId, address requester); + + V1Report internal s_testReportOne; + + function setUp() public virtual override { + BaseTestWithConfiguredVerifierAndFeeManager.setUp(); + (, , bytes32 configDigest) = s_verifier.latestConfigDetails(FEED_ID); + s_reportContext[0] = configDigest; + s_reportContext[1] = bytes32(abi.encode(uint32(5), uint8(1))); + s_testReportOne = _createV1Report( + FEED_ID, + OBSERVATIONS_TIMESTAMP, + MEDIAN, + BID, + ASK, + BLOCKNUMBER_UPPER_BOUND, + blockhash(BLOCKNUMBER_UPPER_BOUND), + BLOCKNUMBER_LOWER_BOUND, + uint32(block.timestamp) + ); + } + + function assertReportsEqual(bytes memory response, V1Report memory testReport) public pure { + ( + bytes32 feedId, + uint32 timestamp, + int192 median, + int192 bid, + int192 ask, + uint64 blockNumUB, + bytes32 upperBlockhash, + uint64 blockNumLB + ) = abi.decode(response, (bytes32, uint32, int192, int192, int192, uint64, bytes32, uint64)); + assertEq(feedId, testReport.feedId); + assertEq(timestamp, testReport.observationsTimestamp); + assertEq(median, testReport.median); + assertEq(bid, testReport.bid); + assertEq(ask, testReport.ask); + assertEq(blockNumLB, testReport.blocknumberLowerBound); + assertEq(blockNumUB, testReport.blocknumberUpperBound); + assertEq(upperBlockhash, testReport.upperBlockhash); + } +} + +contract VerifierProxyVerifyTest is VerifierVerifyTest { + function test_revertsIfNoVerifierConfigured() public { + s_reportContext[0] = bytes32("corrupt-digest"); + bytes memory signedReport = _generateV1EncodedBlob( + s_testReportOne, + s_reportContext, + _getSigners(FAULT_TOLERANCE + 1) + ); + vm.expectRevert(abi.encodeWithSelector(VerifierProxy.VerifierNotFound.selector, bytes32("corrupt-digest"))); + s_verifierProxy.verify(signedReport, bytes("")); + } + + function test_proxiesToTheCorrectVerifier() public { + bytes memory signedReport = _generateV1EncodedBlob( + s_testReportOne, + s_reportContext, + _getSigners(FAULT_TOLERANCE + 1) + ); + + bytes memory response = s_verifierProxy.verify(signedReport, abi.encode(native)); + assertReportsEqual(response, s_testReportOne); + } +} + +contract VerifierProxyAccessControlledVerificationTest is VerifierVerifyTest { + function setUp() public override { + VerifierVerifyTest.setUp(); + AccessControllerInterface accessController = AccessControllerInterface(ACCESS_CONTROLLER_ADDRESS); + + s_verifierProxy.setAccessController(accessController); + } + + function test_revertsIfNoAccess() public { + vm.mockCall( + ACCESS_CONTROLLER_ADDRESS, + abi.encodeWithSelector(AccessControllerInterface.hasAccess.selector, USER), + abi.encode(false) + ); + bytes memory signedReport = _generateV1EncodedBlob( + s_testReportOne, + s_reportContext, + _getSigners(FAULT_TOLERANCE + 1) + ); + vm.expectRevert(abi.encodeWithSelector(VerifierProxy.AccessForbidden.selector)); + + changePrank(USER); + s_verifierProxy.verify(signedReport, abi.encode(native)); + } + + function test_proxiesToTheVerifierIfHasAccess() public { + vm.mockCall( + ACCESS_CONTROLLER_ADDRESS, + abi.encodeWithSelector(AccessControllerInterface.hasAccess.selector, USER), + abi.encode(true) + ); + + bytes memory signedReport = _generateV1EncodedBlob( + s_testReportOne, + s_reportContext, + _getSigners(FAULT_TOLERANCE + 1) + ); + + changePrank(USER); + bytes memory response = s_verifierProxy.verify(signedReport, bytes("")); + assertReportsEqual(response, s_testReportOne); + } +} + +contract VerifierVerifySingleConfigDigestTest is VerifierVerifyTest { + function test_revertsIfVerifiedByNonProxy() public { + bytes memory signedReport = _generateV1EncodedBlob( + s_testReportOne, + s_reportContext, + _getSigners(FAULT_TOLERANCE + 1) + ); + vm.expectRevert(abi.encodeWithSelector(Verifier.AccessForbidden.selector)); + s_verifier.verify(signedReport, msg.sender); + } + + function test_revertsIfVerifiedWithIncorrectAddresses() public { + Signer[] memory signers = _getSigners(FAULT_TOLERANCE + 1); + signers[10].mockPrivateKey = 1234; + bytes memory signedReport = _generateV1EncodedBlob(s_testReportOne, s_reportContext, signers); + changePrank(address(s_verifierProxy)); + vm.expectRevert(abi.encodeWithSelector(Verifier.BadVerification.selector)); + s_verifier.verify(signedReport, msg.sender); + } + + function test_revertsIfMismatchedSignatureLength() public { + bytes32[] memory rs = new bytes32[](FAULT_TOLERANCE + 1); + bytes32[] memory ss = new bytes32[](FAULT_TOLERANCE + 3); + bytes32 rawVs = bytes32(""); + bytes memory signedReport = abi.encode(s_reportContext, abi.encode(s_testReportOne), rs, ss, rawVs); + changePrank(address(s_verifierProxy)); + vm.expectRevert(abi.encodeWithSelector(Verifier.MismatchedSignatures.selector, rs.length, ss.length)); + s_verifier.verify(signedReport, msg.sender); + } + + function test_revertsIfConfigDigestNotSet() public { + bytes32[3] memory reportContext = s_reportContext; + reportContext[0] = bytes32("wrong-context-digest"); + bytes memory signedReport = _generateV1EncodedBlob( + s_testReportOne, + reportContext, + _getSigners(FAULT_TOLERANCE + 1) + ); + vm.expectRevert(abi.encodeWithSelector(Verifier.DigestInactive.selector, FEED_ID, reportContext[0])); + changePrank(address(s_verifierProxy)); + s_verifier.verify(signedReport, msg.sender); + } + + function test_revertsIfReportHasUnconfiguredFeedID() public { + V1Report memory report = _createV1Report( + FEED_ID_2, + OBSERVATIONS_TIMESTAMP, + MEDIAN, + BID, + ASK, + BLOCKNUMBER_UPPER_BOUND, + blockhash(BLOCKNUMBER_UPPER_BOUND), + BLOCKNUMBER_LOWER_BOUND, + uint32(block.timestamp) + ); + bytes memory signedReport = _generateV1EncodedBlob(report, s_reportContext, _getSigners(FAULT_TOLERANCE + 1)); + vm.expectRevert(abi.encodeWithSelector(Verifier.DigestInactive.selector, FEED_ID_2, s_reportContext[0])); + changePrank(address(s_verifierProxy)); + s_verifier.verify(signedReport, msg.sender); + } + + function test_revertsIfWrongNumberOfSigners() public { + bytes memory signedReport = _generateV1EncodedBlob(s_testReportOne, s_reportContext, _getSigners(10)); + vm.expectRevert(abi.encodeWithSelector(Verifier.IncorrectSignatureCount.selector, 10, FAULT_TOLERANCE + 1)); + changePrank(address(s_verifierProxy)); + s_verifier.verify(signedReport, msg.sender); + } + + function test_revertsIfDuplicateSignersHaveSigned() public { + Signer[] memory signers = _getSigners(FAULT_TOLERANCE + 1); + // Duplicate signer at index 1 + signers[0] = signers[1]; + bytes memory signedReport = _generateV1EncodedBlob(s_testReportOne, s_reportContext, signers); + vm.expectRevert(abi.encodeWithSelector(Verifier.BadVerification.selector)); + changePrank(address(s_verifierProxy)); + s_verifier.verify(signedReport, msg.sender); + } + + function test_returnsThePriceAndBlockNumIfReportVerified() public { + bytes memory signedReport = _generateV1EncodedBlob( + s_testReportOne, + s_reportContext, + _getSigners(FAULT_TOLERANCE + 1) + ); + changePrank(address(s_verifierProxy)); + bytes memory response = s_verifier.verify(signedReport, msg.sender); + + assertReportsEqual(response, s_testReportOne); + } + + function test_setsTheCorrectEpoch() public { + s_reportContext[1] = bytes32(uint256(5 << 8)); + bytes memory signedReport = _generateV1EncodedBlob( + s_testReportOne, + s_reportContext, + _getSigners(FAULT_TOLERANCE + 1) + ); + changePrank(address(s_verifierProxy)); + s_verifier.verify(signedReport, msg.sender); + + (, , uint32 latestEpoch) = s_verifier.latestConfigDigestAndEpoch(FEED_ID); + assertEq(latestEpoch, 5); + } + + function test_emitsAnEventIfReportVerified() public { + bytes memory signedReport = _generateV1EncodedBlob( + s_testReportOne, + s_reportContext, + _getSigners(FAULT_TOLERANCE + 1) + ); + vm.expectEmit(true, true, true, true, address(s_verifier)); + emit ReportVerified(s_testReportOne.feedId, msg.sender); + changePrank(address(s_verifierProxy)); + s_verifier.verify(signedReport, msg.sender); + } +} + +contract VerifierVerifyMultipleConfigDigestTest is VerifierVerifyTest { + bytes32 internal s_oldConfigDigest; + bytes32 internal s_newConfigDigest; + + uint8 internal constant FAULT_TOLERANCE_TWO = 5; + + function setUp() public override { + VerifierVerifyTest.setUp(); + (, , s_oldConfigDigest) = s_verifier.latestConfigDetails(FEED_ID); + s_verifier.setConfig( + FEED_ID, + _getSignerAddresses(_getSigners(20)), + s_offchaintransmitters, + FAULT_TOLERANCE_TWO, + bytes(""), + VERIFIER_VERSION, + bytes(""), + new Common.AddressAndWeight[](0) + ); + (, , s_newConfigDigest) = s_verifier.latestConfigDetails(FEED_ID); + } + + function test_revertsIfVerifyingWithAnUnsetDigest() public { + s_verifier.deactivateConfig(FEED_ID, (s_oldConfigDigest)); + + bytes memory signedReport = _generateV1EncodedBlob( + s_testReportOne, + s_reportContext, + _getSigners(FAULT_TOLERANCE + 1) + ); + changePrank(address(s_verifierProxy)); + vm.expectRevert(abi.encodeWithSelector(Verifier.DigestInactive.selector, FEED_ID, s_reportContext[0])); + s_verifier.verify(signedReport, msg.sender); + } + + function test_canVerifyOlderReportsWithOlderConfigs() public { + bytes memory signedReport = _generateV1EncodedBlob( + s_testReportOne, + s_reportContext, + _getSigners(FAULT_TOLERANCE + 1) + ); + changePrank(address(s_verifierProxy)); + bytes memory response = s_verifier.verify(signedReport, msg.sender); + assertReportsEqual(response, s_testReportOne); + } + + function test_canVerifyNewerReportsWithNewerConfigs() public { + s_reportContext[0] = s_newConfigDigest; + bytes memory signedReport = _generateV1EncodedBlob( + s_testReportOne, + s_reportContext, + _getSigners(FAULT_TOLERANCE_TWO + 1) + ); + changePrank(address(s_verifierProxy)); + bytes memory response = s_verifier.verify(signedReport, msg.sender); + assertReportsEqual(response, s_testReportOne); + } + + function test_revertsIfAReportIsVerifiedWithAnExistingButIncorrectDigest() public { + // Try sending the older digest signed with the new set of signers + s_reportContext[0] = s_oldConfigDigest; + bytes memory signedReport = _generateV1EncodedBlob( + s_testReportOne, + s_reportContext, + _getSigners(FAULT_TOLERANCE_TWO + 1) + ); + vm.expectRevert( + abi.encodeWithSelector(Verifier.IncorrectSignatureCount.selector, FAULT_TOLERANCE_TWO + 1, FAULT_TOLERANCE + 1) + ); + changePrank(address(s_verifierProxy)); + s_verifier.verify(signedReport, msg.sender); + } +} From bfaff3e215eaa7bbd037f55eba3d25336ecdd496 Mon Sep 17 00:00:00 2001 From: Michael Fletcher Date: Tue, 19 Nov 2024 18:30:36 +0000 Subject: [PATCH 2/8] Initial working impl of SBRV migration --- .../src/v0.8/llo-feeds/v0.5.0/FeeManager.sol | 21 +- .../src/v0.8/llo-feeds/v0.5.0/Verifier.sol | 252 +++++------------- .../v0.5.0/interfaces/IFeeManager.sol | 8 + .../llo-feeds/v0.5.0/interfaces/IVerifier.sol | 71 +---- 4 files changed, 106 insertions(+), 246 deletions(-) diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/FeeManager.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/FeeManager.sol index 44f550e3253..36d97644906 100644 --- a/contracts/src/v0.8/llo-feeds/v0.5.0/FeeManager.sol +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/FeeManager.sol @@ -25,6 +25,9 @@ contract FeeManager is IFeeManager, ConfirmedOwner, TypeAndVersionInterface { /// @notice list of subscribers and their discounts subscriberDiscounts[subscriber][feedId][token] mapping(address => mapping(bytes32 => mapping(address => uint256))) public s_subscriberDiscounts; + /// @notice map of global discounts + mapping(address => mapping(address => uint256)) public s_globalDiscounts; + /// @notice keep track of any subsidised link that is owed to the reward manager. mapping(bytes32 => uint256) public s_linkDeficit; @@ -160,7 +163,7 @@ contract FeeManager is IFeeManager, ConfirmedOwner, TypeAndVersionInterface { /// @inheritdoc TypeAndVersionInterface function typeAndVersion() external pure override returns (string memory) { - return "FeeManager 2.0.0"; + return "FeeManager 2.1.0"; } /// @inheritdoc IERC165 @@ -285,6 +288,11 @@ contract FeeManager is IFeeManager, ConfirmedOwner, TypeAndVersionInterface { //get the discount being applied uint256 discount = s_subscriberDiscounts[subscriber][feedId][quoteAddress]; + if (discount == 0) { + //check if a global discount has been applied + discount = s_globalDiscounts[subscriber][quoteAddress]; + } + //the reward is always set in LINK reward.assetAddress = i_linkAddress; reward.amount = Math.ceilDiv(linkQuantity * (PERCENTAGE_SCALAR - discount), PERCENTAGE_SCALAR); @@ -338,6 +346,17 @@ contract FeeManager is IFeeManager, ConfirmedOwner, TypeAndVersionInterface { emit SubscriberDiscountUpdated(subscriber, feedId, token, discount); } + function updateSubscriberGlobalDiscount(address subscriber, address token, uint64 discount) external onlyOwner { + //make sure the discount is not greater than the total discount that can be applied + if (discount > PERCENTAGE_SCALAR) revert InvalidDiscount(); + //make sure the token is either LINK or native + if (token != i_linkAddress && token != i_nativeAddress) revert InvalidAddress(); + + s_globalDiscounts[subscriber][token] = discount; + + emit SubscriberDiscountUpdated(subscriber, bytes32(0), token, discount); + } + /// @inheritdoc IFeeManager function withdraw(address assetAddress, address recipient, uint192 quantity) external onlyOwner { //address 0 is used to withdraw native in the context of withdrawing diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/Verifier.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/Verifier.sol index fe5742108a5..13dd7980631 100644 --- a/contracts/src/v0.8/llo-feeds/v0.5.0/Verifier.sol +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/Verifier.sol @@ -26,7 +26,7 @@ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface { // Default role for an oracle address. This means that the oracle address // is not a signer Unset, - // Role given to an oracle address that is allowed to sign feed data + // Role given to an oracle address that is allowed to sign a report Signer } @@ -47,29 +47,25 @@ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface { } struct VerifierState { - // The number of times a new configuration - /// has been set + // The number of configs for this DON uint32 configCount; - // The block number of the block the last time - /// the configuration was updated. + // The block number of the block the last time the configuration was updated. uint32 latestConfigBlockNumber; - // The latest epoch a report was verified for - uint32 latestEpoch; - // Whether or not the verifier for this feed has been deactivated + // Whether the config is deactivated bool isDeactivated; - /// The latest config digest set - bytes32 latestConfigDigest; - /// The historical record of all previously set configs by feedId - mapping(bytes32 => Config) s_verificationDataConfigs; + // Fault tolerance + uint8 f; + // Map of signer addresses to oracles + mapping(address => Signer) oracles; } /// @notice This event is emitted when a new report is verified. /// It is used to keep a historical record of verified reports. event ReportVerified(bytes32 indexed feedId, address requester); - /// @notice This event is emitted whenever a new configuration is set for a feed. It triggers a new run of the offchain reporting protocol. + /// @notice This event is emitted whenever a new DON configuration is set. event ConfigSet( - bytes32 indexed feedId, + bytes32 indexed configId, uint32 previousConfigBlockNumber, bytes32 configDigest, uint64 configCount, @@ -82,16 +78,10 @@ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface { ); /// @notice This event is emitted whenever a configuration is deactivated - event ConfigDeactivated(bytes32 indexed feedId, bytes32 configDigest); + event ConfigDeactivated(bytes32 indexed configDigest); /// @notice This event is emitted whenever a configuration is activated - event ConfigActivated(bytes32 indexed feedId, bytes32 configDigest); - - /// @notice This event is emitted whenever a feed is activated - event FeedActivated(bytes32 indexed feedId); - - /// @notice This event is emitted whenever a feed is deactivated - event FeedDeactivated(bytes32 indexed feedId); + event ConfigActivated(bytes32 indexed configDigest); /// @notice This error is thrown whenever an address tries /// to exeecute a transaction that it is not authorized to do so @@ -100,25 +90,19 @@ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface { /// @notice This error is thrown whenever a zero address is passed error ZeroAddress(); - /// @notice This error is thrown whenever the feed ID passed in - /// a signed report is empty - error FeedIdEmpty(); - /// @notice This error is thrown whenever the config digest /// is empty error DigestEmpty(); /// @notice This error is thrown whenever the config digest /// passed in has not been set in this verifier - /// @param feedId The feed ID in the signed report /// @param configDigest The config digest that has not been set - error DigestNotSet(bytes32 feedId, bytes32 configDigest); + error DigestNotSet(bytes32 configDigest); /// @notice This error is thrown whenever the config digest /// has been deactivated - /// @param feedId The feed ID in the signed report /// @param configDigest The config digest that is inactive - error DigestInactive(bytes32 feedId, bytes32 configDigest); + error DigestInactive(bytes32 configDigest); /// @notice This error is thrown whenever trying to set a config /// with a fault tolerance of 0 @@ -155,25 +139,11 @@ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface { /// @notice This error is thrown whenever a report fails to verify due to bad or duplicate signatures error BadVerification(); - /// @notice This error is thrown whenever the admin tries to deactivate - /// the latest config digest - /// @param feedId The feed ID in the signed report - /// @param configDigest The latest config digest - error CannotDeactivateLatestConfig(bytes32 feedId, bytes32 configDigest); - - /// @notice This error is thrown whenever the feed ID passed in is deactivated - /// @param feedId The feed ID - error InactiveFeed(bytes32 feedId); - - /// @notice This error is thrown whenever the feed ID passed in is not found - /// @param feedId The feed ID - error InvalidFeed(bytes32 feedId); - /// @notice The address of the verifier proxy address private immutable i_verifierProxyAddr; - /// @notice Verifier states keyed on Feed ID - mapping(bytes32 => VerifierState) internal s_feedVerifierStates; + /// @notice Verifier states keyed on config digest + mapping(bytes32 => VerifierState) internal s_verifierStates; /// @param verifierProxyAddr The address of the VerifierProxy contract constructor(address verifierProxyAddr) ConfirmedOwner(msg.sender) { @@ -195,7 +165,7 @@ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface { /// @inheritdoc TypeAndVersionInterface function typeAndVersion() external pure override returns (string memory) { - return "Verifier 1.2.0"; + return "Verifier 2.0.0"; } /// @inheritdoc IVerifier @@ -212,66 +182,42 @@ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface { bytes32 rawVs ) = abi.decode(signedReport, (bytes32[3], bytes, bytes32[], bytes32[], bytes32)); - // The feed ID is the first 32 bytes of the report data. - bytes32 feedId = bytes32(reportData); - - VerifierState storage feedVerifierState = s_feedVerifierStates[feedId]; - - // If the feed has been deactivated, do not verify the report - if (feedVerifierState.isDeactivated) { - revert InactiveFeed(feedId); - } + VerifierState storage verifierState = s_verifierStates[reportContext[0]]; // reportContext consists of: // reportContext[0]: ConfigDigest // reportContext[1]: 27 byte padding, 4-byte epoch and 1-byte round // reportContext[2]: ExtraHash bytes32 configDigest = reportContext[0]; - Config storage s_config = feedVerifierState.s_verificationDataConfigs[configDigest]; - _validateReport(feedId, configDigest, rs, ss, s_config); - _updateEpoch(reportContext, feedVerifierState); + _validateReport(configDigest, rs, ss, verifierState); bytes32 hashedReport = keccak256(reportData); - _verifySignatures(hashedReport, reportContext, rs, ss, rawVs, s_config); - emit ReportVerified(feedId, sender); + _verifySignatures(hashedReport, reportContext, rs, ss, rawVs, verifierState); + emit ReportVerified(bytes32(reportData), sender); return reportData; } /// @notice Validates parameters of the report - /// @param feedId Feed ID from the report /// @param configDigest Config digest from the report /// @param rs R components from the report /// @param ss S components from the report - /// @param config Config for the given feed ID keyed on the config digest + /// @param config Config for the given digest function _validateReport( - bytes32 feedId, bytes32 configDigest, bytes32[] memory rs, bytes32[] memory ss, - Config storage config + VerifierState storage config ) private view { uint8 expectedNumSignatures = config.f + 1; - if (!config.isActive) revert DigestInactive(feedId, configDigest); + if (!config.isDeactivated) revert DigestInactive(configDigest); if (rs.length != expectedNumSignatures) revert IncorrectSignatureCount(rs.length, expectedNumSignatures); if (rs.length != ss.length) revert MismatchedSignatures(rs.length, ss.length); } - /** - * @notice Conditionally update the epoch for a feed - * @param reportContext Report context containing the epoch and round - * @param feedVerifierState Feed verifier state to conditionally update - */ - function _updateEpoch(bytes32[3] memory reportContext, VerifierState storage feedVerifierState) private { - uint40 epochAndRound = uint40(uint256(reportContext[1])); - uint32 epoch = uint32(epochAndRound >> 8); - if (epoch > feedVerifierState.latestEpoch) { - feedVerifierState.latestEpoch = epoch; - } - } /// @notice Verifies that a report has been signed by the correct /// signers and that enough signers have signed the reports. @@ -280,14 +226,14 @@ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface { /// @param rs ith element is the R components of the ith signature on report. Must have at most MAX_NUM_ORACLES entries /// @param ss ith element is the S components of the ith signature on report. Must have at most MAX_NUM_ORACLES entries /// @param rawVs ith element is the the V component of the ith signature - /// @param s_config The config digest the report was signed for + /// @param config The config digest the report was signed for function _verifySignatures( bytes32 hashedReport, bytes32[3] memory reportContext, bytes32[] memory rs, bytes32[] memory ss, bytes32 rawVs, - Config storage s_config + VerifierState storage config ) private view { bytes32 h = keccak256(abi.encodePacked(hashedReport, reportContext)); // i-th byte counts number of sigs made by i-th signer @@ -298,7 +244,7 @@ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface { uint256 numSigners = rs.length; for (uint256 i; i < numSigners; ++i) { signerAddress = ecrecover(h, uint8(rawVs[i]) + 27, rs[i], ss[i]); - o = s_config.oracles[signerAddress]; + o = config.oracles[signerAddress]; if (o.role != Role.Signer) revert BadVerification(); unchecked { signedCount += 1 << (8 * o.index); @@ -310,36 +256,10 @@ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface { /// @inheritdoc IVerifier function setConfig( - bytes32 feedId, - address[] memory signers, - bytes32[] memory offchainTransmitters, - uint8 f, - bytes memory onchainConfig, - uint64 offchainConfigVersion, - bytes memory offchainConfig, - Common.AddressAndWeight[] memory recipientAddressesAndWeights - ) external override checkConfigValid(signers.length, f) onlyOwner { - _setConfig( - feedId, - block.chainid, - address(this), - 0, // 0 defaults to feedConfig.configCount + 1 - signers, - offchainTransmitters, - f, - onchainConfig, - offchainConfigVersion, - offchainConfig, - recipientAddressesAndWeights - ); - } - - /// @inheritdoc IVerifier - function setConfigFromSource( - bytes32 feedId, + bytes32 configId, uint256 sourceChainId, address sourceAddress, - uint32 newConfigCount, + uint32 configCount, address[] memory signers, bytes32[] memory offchainTransmitters, uint8 f, @@ -349,10 +269,10 @@ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface { Common.AddressAndWeight[] memory recipientAddressesAndWeights ) external override checkConfigValid(signers.length, f) onlyOwner { _setConfig( - feedId, + configId, sourceChainId, sourceAddress, - newConfigCount, + configCount, signers, offchainTransmitters, f, @@ -364,10 +284,10 @@ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface { } /// @notice Sets config based on the given arguments - /// @param feedId Feed ID to set config for + /// @param configId Config ID to set config for /// @param sourceChainId Chain ID of source config /// @param sourceAddress Address of source config Verifier - /// @param newConfigCount Optional param to force the new config count + /// @param configCount The number of times a new configuration has been set /// @param signers addresses with which oracles sign the reports /// @param offchainTransmitters CSA key for the ith Oracle /// @param f number of faulty oracles the system can tolerate @@ -376,10 +296,10 @@ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface { /// @param offchainConfig serialized configuration used by the oracles exclusively and only passed through the contract /// @param recipientAddressesAndWeights the addresses and weights of all the recipients to receive rewards function _setConfig( - bytes32 feedId, + bytes32 configId, uint256 sourceChainId, address sourceAddress, - uint32 newConfigCount, + uint32 configCount, address[] memory signers, bytes32[] memory offchainTransmitters, uint8 f, @@ -388,17 +308,11 @@ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface { bytes memory offchainConfig, Common.AddressAndWeight[] memory recipientAddressesAndWeights ) internal { - VerifierState storage feedVerifierState = s_feedVerifierStates[feedId]; - - // Increment the number of times a config has been set first - if (newConfigCount > 0) feedVerifierState.configCount = newConfigCount; - else feedVerifierState.configCount++; - bytes32 configDigest = _configDigestFromConfigData( - feedId, + configId, sourceChainId, sourceAddress, - feedVerifierState.configCount, + configCount, signers, offchainTransmitters, f, @@ -407,8 +321,12 @@ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface { offchainConfig ); - feedVerifierState.s_verificationDataConfigs[configDigest].f = f; - feedVerifierState.s_verificationDataConfigs[configDigest].isActive = true; + VerifierState storage verifierState = s_verifierStates[configDigest]; + + verifierState.latestConfigBlockNumber = uint32(block.number); + verifierState.configCount = configCount; + verifierState.f = f; + for (uint8 i; i < signers.length; ++i) { address signerAddr = signers[i]; if (signerAddr == address(0)) revert ZeroAddress(); @@ -417,26 +335,26 @@ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface { // Here the contract checks to see if a signer's address has already // been set to ensure that the group of signer addresses that will // sign reports with the config digest are unique. - bool isSignerAlreadySet = feedVerifierState.s_verificationDataConfigs[configDigest].oracles[signerAddr].role != + bool isSignerAlreadySet = verifierState.oracles[signerAddr].role != Role.Unset; if (isSignerAlreadySet) revert NonUniqueSignatures(); - feedVerifierState.s_verificationDataConfigs[configDigest].oracles[signerAddr] = Signer({ + verifierState.oracles[signerAddr] = Signer({ role: Role.Signer, index: i }); } IVerifierProxy(i_verifierProxyAddr).setVerifier( - feedVerifierState.latestConfigDigest, + bytes32(0), configDigest, recipientAddressesAndWeights ); emit ConfigSet( - feedId, - feedVerifierState.latestConfigBlockNumber, + configId, + 0, configDigest, - feedVerifierState.configCount, + configCount, signers, offchainTransmitters, f, @@ -444,14 +362,10 @@ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface { offchainConfigVersion, offchainConfig ); - - feedVerifierState.latestEpoch = 0; - feedVerifierState.latestConfigBlockNumber = uint32(block.number); - feedVerifierState.latestConfigDigest = configDigest; } /// @notice Generates the config digest from config data - /// @param feedId Feed ID to set config for + /// @param configId to set config for /// @param sourceChainId Chain ID of source config /// @param sourceAddress Address of source config Verifier /// @param configCount ordinal number of this config setting among all config settings over the life of this contract @@ -463,7 +377,7 @@ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface { /// @param offchainConfig serialized configuration used by the oracles exclusively and only passed through the contract /// @dev This function is a modified version of the method from OCR2Abstract function _configDigestFromConfigData( - bytes32 feedId, + bytes32 configId, uint256 sourceChainId, address sourceAddress, uint64 configCount, @@ -477,7 +391,7 @@ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface { uint256 h = uint256( keccak256( abi.encode( - feedId, + configId, sourceChainId, sourceAddress, configCount, @@ -492,68 +406,38 @@ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface { ); uint256 prefixMask = type(uint256).max << (256 - 16); // 0xFFFF00..00 // 0x0006 corresponds to ConfigDigestPrefixMercuryV02 in libocr - uint256 prefix = 0x0006 << (256 - 16); // 0x000600..00 + uint256 prefix = 0x0009 << (256 - 16); // 0x000600..00 return bytes32((prefix & prefixMask) | (h & ~prefixMask)); } /// @inheritdoc IVerifier - function activateConfig(bytes32 feedId, bytes32 configDigest) external onlyOwner { - VerifierState storage feedVerifierState = s_feedVerifierStates[feedId]; + function activateConfig(bytes32 configDigest) external onlyOwner { + VerifierState storage verifierState = s_verifierStates[configDigest]; if (configDigest == bytes32("")) revert DigestEmpty(); - if (feedVerifierState.s_verificationDataConfigs[configDigest].f == 0) revert DigestNotSet(feedId, configDigest); - feedVerifierState.s_verificationDataConfigs[configDigest].isActive = true; - emit ConfigActivated(feedId, configDigest); + if (verifierState.f == 0) revert DigestNotSet(configDigest); + verifierState.isDeactivated = false; + emit ConfigActivated(configDigest); } /// @inheritdoc IVerifier - function deactivateConfig(bytes32 feedId, bytes32 configDigest) external onlyOwner { - VerifierState storage feedVerifierState = s_feedVerifierStates[feedId]; + function deactivateConfig(bytes32 configDigest) external onlyOwner { + VerifierState storage verifierState = s_verifierStates[configDigest]; if (configDigest == bytes32("")) revert DigestEmpty(); - if (feedVerifierState.s_verificationDataConfigs[configDigest].f == 0) revert DigestNotSet(feedId, configDigest); - if (configDigest == feedVerifierState.latestConfigDigest) { - revert CannotDeactivateLatestConfig(feedId, configDigest); - } - feedVerifierState.s_verificationDataConfigs[configDigest].isActive = false; - emit ConfigDeactivated(feedId, configDigest); - } - - /// @inheritdoc IVerifier - function activateFeed(bytes32 feedId) external onlyOwner { - VerifierState storage feedVerifierState = s_feedVerifierStates[feedId]; - - if (feedVerifierState.configCount == 0) revert InvalidFeed(feedId); - feedVerifierState.isDeactivated = false; - emit FeedActivated(feedId); - } - - /// @inheritdoc IVerifier - function deactivateFeed(bytes32 feedId) external onlyOwner { - VerifierState storage feedVerifierState = s_feedVerifierStates[feedId]; - - if (feedVerifierState.configCount == 0) revert InvalidFeed(feedId); - feedVerifierState.isDeactivated = true; - emit FeedDeactivated(feedId); - } - - /// @inheritdoc IVerifier - function latestConfigDigestAndEpoch( - bytes32 feedId - ) external view override returns (bool scanLogs, bytes32 configDigest, uint32 epoch) { - VerifierState storage feedVerifierState = s_feedVerifierStates[feedId]; - return (false, feedVerifierState.latestConfigDigest, feedVerifierState.latestEpoch); + if (verifierState.f == 0) revert DigestNotSet(configDigest); + verifierState.isDeactivated = true; + emit ConfigDeactivated(configDigest); } /// @inheritdoc IVerifier function latestConfigDetails( - bytes32 feedId - ) external view override returns (uint32 configCount, uint32 blockNumber, bytes32 configDigest) { - VerifierState storage feedVerifierState = s_feedVerifierStates[feedId]; + bytes32 configDigest + ) external view override returns (uint32 configCount, uint32 blockNumber) { + VerifierState storage verifierState = s_verifierStates[configDigest]; return ( - feedVerifierState.configCount, - feedVerifierState.latestConfigBlockNumber, - feedVerifierState.latestConfigDigest + verifierState.configCount, + verifierState.latestConfigBlockNumber ); } } diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/interfaces/IFeeManager.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/interfaces/IFeeManager.sol index 818a3a09a4c..5ea331ea8fd 100644 --- a/contracts/src/v0.8/llo-feeds/v0.5.0/interfaces/IFeeManager.sol +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/interfaces/IFeeManager.sol @@ -54,6 +54,14 @@ interface IFeeManager is IERC165, IVerifierFeeManager { */ function payLinkDeficit(bytes32 configDigest) external; + /** + * @notice Adds a subscriber to the fee manager + * @param subscriber address of the subscriber + * @param token token to apply the discount to + * @param discount discount to be applied to the fee + */ + function updateSubscriberGlobalDiscount(address subscriber, address token, uint64 discount) external; + /** * @notice The structure to hold a fee and reward to verify a report * @param digest the digest linked to the fee and reward diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/interfaces/IVerifier.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/interfaces/IVerifier.sol index 94b260399ea..152101362ea 100644 --- a/contracts/src/v0.8/llo-feeds/v0.5.0/interfaces/IVerifier.sol +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/interfaces/IVerifier.sol @@ -18,34 +18,12 @@ interface IVerifier is IERC165 { */ function verify(bytes calldata signedReport, address sender) external returns (bytes memory verifierResponse); - /** - * @notice sets offchain reporting protocol configuration incl. participating oracles - * @param feedId Feed ID to set config for - * @param signers addresses with which oracles sign the reports - * @param offchainTransmitters CSA key for the ith Oracle - * @param f number of faulty oracles the system can tolerate - * @param onchainConfig serialized configuration used by the contract (and possibly oracles) - * @param offchainConfigVersion version number for offchainEncoding schema - * @param offchainConfig serialized configuration used by the oracles exclusively and only passed through the contract - * @param recipientAddressesAndWeights the addresses and weights of all the recipients to receive rewards - */ - function setConfig( - bytes32 feedId, - address[] memory signers, - bytes32[] memory offchainTransmitters, - uint8 f, - bytes memory onchainConfig, - uint64 offchainConfigVersion, - bytes memory offchainConfig, - Common.AddressAndWeight[] memory recipientAddressesAndWeights - ) external; - /** * @notice identical to `setConfig` except with args for sourceChainId and sourceAddress - * @param feedId Feed ID to set config for + * @param configId Config ID to set config for * @param sourceChainId Chain ID of source config * @param sourceAddress Address of source config Verifier - * @param newConfigCount Param to force the new config count + * @param configCount The config count for the configuration * @param signers addresses with which oracles sign the reports * @param offchainTransmitters CSA key for the ith Oracle * @param f number of faulty oracles the system can tolerate @@ -54,11 +32,11 @@ interface IVerifier is IERC165 { * @param offchainConfig serialized configuration used by the oracles exclusively and only passed through the contract * @param recipientAddressesAndWeights the addresses and weights of all the recipients to receive rewards */ - function setConfigFromSource( - bytes32 feedId, + function setConfig( + bytes32 configId, uint256 sourceChainId, address sourceAddress, - uint32 newConfigCount, + uint32 configCount, address[] memory signers, bytes32[] memory offchainTransmitters, uint8 f, @@ -70,54 +48,25 @@ interface IVerifier is IERC165 { /** * @notice Activates the configuration for a config digest - * @param feedId Feed ID to activate config for * @param configDigest The config digest to activate * @dev This function can be called by the contract admin to activate a configuration. */ - function activateConfig(bytes32 feedId, bytes32 configDigest) external; + function activateConfig(bytes32 configDigest) external; /** * @notice Deactivates the configuration for a config digest - * @param feedId Feed ID to deactivate config for * @param configDigest The config digest to deactivate * @dev This function can be called by the contract admin to deactivate an incorrect configuration. */ - function deactivateConfig(bytes32 feedId, bytes32 configDigest) external; - - /** - * @notice Activates the given feed - * @param feedId Feed ID to activated - * @dev This function can be called by the contract admin to activate a feed - */ - function activateFeed(bytes32 feedId) external; - - /** - * @notice Deactivates the given feed - * @param feedId Feed ID to deactivated - * @dev This function can be called by the contract admin to deactivate a feed - */ - function deactivateFeed(bytes32 feedId) external; - - /** - * @notice returns the latest config digest and epoch for a feed - * @param feedId Feed ID to fetch data for - * @return scanLogs indicates whether to rely on the configDigest and epoch - * returned or whether to scan logs for the Transmitted event instead. - * @return configDigest - * @return epoch - */ - function latestConfigDigestAndEpoch( - bytes32 feedId - ) external view returns (bool scanLogs, bytes32 configDigest, uint32 epoch); + function deactivateConfig(bytes32 configDigest) external; /** * @notice information about current offchain reporting protocol configuration - * @param feedId Feed ID to fetch data for + * @param configDigest Config Digest to fetch data for * @return configCount ordinal number of current config, out of all configs applied to this contract so far * @return blockNumber block at which this config was set - * @return configDigest domain-separation tag for current config */ function latestConfigDetails( - bytes32 feedId - ) external view returns (uint32 configCount, uint32 blockNumber, bytes32 configDigest); + bytes32 configDigest + ) external view returns (uint32 configCount, uint32 blockNumber); } From e27c382aebb36355e786f3acd9fe5c759450bdc3 Mon Sep 17 00:00:00 2001 From: Michael Fletcher Date: Tue, 19 Nov 2024 21:40:18 +0000 Subject: [PATCH 3/8] Tests + fixes --- .../src/v0.8/llo-feeds/v0.5.0/Verifier.sol | 17 +-- .../v0.5.0/test/gas/Gas_VerifierTest.t.sol | 13 +- .../v0.5.0/test/mocks/ErroredVerifier.sol | 32 +---- .../test/verifier/BaseVerifierTest.t.sol | 108 ++++++++++++-- .../verifier/VerifierActivateConfigTest.t.sol | 14 +- .../verifier/VerifierDeactivateFeedTest.t.sol | 108 -------------- .../VerifierProxyConstructorTest.t.sol | 2 +- .../VerifierProxyInitializeVerifierTest.t.sol | 2 +- .../VerifierProxySetVerifierTest.t.sol | 6 +- .../VerifierProxyUnsetVerifierTest.t.sol | 4 +- .../VerifierSetConfigFromSourceTest.t.sol | 134 ------------------ .../test/verifier/VerifierSetConfigTest.t.sol | 114 ++++++++++++--- .../v0.5.0/test/verifier/VerifierTest.t.sol | 12 +- .../verifier/VerifierUnsetConfigTest.t.sol | 42 +----- .../test/verifier/VerifierVerifyTest.t.sol | 50 +++---- 15 files changed, 262 insertions(+), 396 deletions(-) delete mode 100644 contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierDeactivateFeedTest.t.sol delete mode 100644 contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierSetConfigFromSourceTest.t.sol diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/Verifier.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/Verifier.sol index 13dd7980631..55e1c542291 100644 --- a/contracts/src/v0.8/llo-feeds/v0.5.0/Verifier.sol +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/Verifier.sol @@ -52,7 +52,7 @@ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface { // The block number of the block the last time the configuration was updated. uint32 latestConfigBlockNumber; // Whether the config is deactivated - bool isDeactivated; + bool isActive; // Fault tolerance uint8 f; // Map of signer addresses to oracles @@ -182,14 +182,14 @@ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface { bytes32 rawVs ) = abi.decode(signedReport, (bytes32[3], bytes, bytes32[], bytes32[], bytes32)); - VerifierState storage verifierState = s_verifierStates[reportContext[0]]; - // reportContext consists of: // reportContext[0]: ConfigDigest // reportContext[1]: 27 byte padding, 4-byte epoch and 1-byte round // reportContext[2]: ExtraHash bytes32 configDigest = reportContext[0]; + VerifierState storage verifierState = s_verifierStates[configDigest]; + _validateReport(configDigest, rs, ss, verifierState); bytes32 hashedReport = keccak256(reportData); @@ -213,7 +213,7 @@ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface { ) private view { uint8 expectedNumSignatures = config.f + 1; - if (!config.isDeactivated) revert DigestInactive(configDigest); + if (!config.isActive) revert DigestInactive(configDigest); if (rs.length != expectedNumSignatures) revert IncorrectSignatureCount(rs.length, expectedNumSignatures); if (rs.length != ss.length) revert MismatchedSignatures(rs.length, ss.length); } @@ -326,6 +326,7 @@ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface { verifierState.latestConfigBlockNumber = uint32(block.number); verifierState.configCount = configCount; verifierState.f = f; + verifierState.isActive = true; for (uint8 i; i < signers.length; ++i) { address signerAddr = signers[i]; @@ -405,8 +406,8 @@ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface { ) ); uint256 prefixMask = type(uint256).max << (256 - 16); // 0xFFFF00..00 - // 0x0006 corresponds to ConfigDigestPrefixMercuryV02 in libocr - uint256 prefix = 0x0009 << (256 - 16); // 0x000600..00 + // 0x0009 corresponds to ConfigDigestPrefixMercuryV02 in libocr + uint256 prefix = 0x0009 << (256 - 16); // 0x000900..00 return bytes32((prefix & prefixMask) | (h & ~prefixMask)); } @@ -416,7 +417,7 @@ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface { if (configDigest == bytes32("")) revert DigestEmpty(); if (verifierState.f == 0) revert DigestNotSet(configDigest); - verifierState.isDeactivated = false; + verifierState.isActive = true; emit ConfigActivated(configDigest); } @@ -426,7 +427,7 @@ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface { if (configDigest == bytes32("")) revert DigestEmpty(); if (verifierState.f == 0) revert DigestNotSet(configDigest); - verifierState.isDeactivated = true; + verifierState.isActive = false; emit ConfigDeactivated(configDigest); } diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/gas/Gas_VerifierTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/gas/Gas_VerifierTest.t.sol index ee8ba4c3e34..a9bd067696a 100644 --- a/contracts/src/v0.8/llo-feeds/v0.5.0/test/gas/Gas_VerifierTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/gas/Gas_VerifierTest.t.sol @@ -19,11 +19,14 @@ contract Verifier_setConfig is BaseTest { function testSetConfigSuccess_gas() public { s_verifier.setConfig( FEED_ID, + SOURCE_CHAIN_ID, + SOURCE_ADDRESS, + 1, s_signerAddrs, s_offchaintransmitters, FAULT_TOLERANCE, bytes(""), - VERIFIER_VERSION, + 1, bytes(""), new Common.AddressAndWeight[](0) ); @@ -44,7 +47,7 @@ contract Verifier_verifyWithFee is BaseTestWithConfiguredVerifierAndFeeManager { //warm the rewardManager link.mint(address(this), DEFAULT_NATIVE_MINT_QUANTITY); _approveLink(address(rewardManager), DEFAULT_REPORT_LINK_FEE, address(this)); - (, , bytes32 latestConfigDigest) = s_verifier.latestConfigDetails(FEED_ID); + bytes32 latestConfigDigest = v1ConfigDigest; //mint some tokens to the user link.mint(USER, DEFAULT_LINK_MINT_QUANTITY); @@ -103,7 +106,7 @@ contract Verifier_bulkVerifyWithFee is BaseTestWithConfiguredVerifierAndFeeManag //warm the rewardManager link.mint(address(this), DEFAULT_NATIVE_MINT_QUANTITY); _approveLink(address(rewardManager), DEFAULT_REPORT_LINK_FEE, address(this)); - (, , bytes32 latestConfigDigest) = s_verifier.latestConfigDetails(FEED_ID); + bytes32 latestConfigDigest = v1ConfigDigest; //mint some tokens to the user link.mint(USER, DEFAULT_LINK_MINT_QUANTITY); @@ -174,7 +177,7 @@ contract Verifier_verify is BaseTestWithConfiguredVerifierAndFeeManager { BLOCKNUMBER_LOWER_BOUND, uint32(block.timestamp) ); - (, , s_configDigest) = s_verifier.latestConfigDetails(FEED_ID); + s_configDigest = v1ConfigDigest; bytes32[3] memory reportContext; reportContext[0] = s_configDigest; reportContext[1] = bytes32(abi.encode(uint32(5), uint8(1))); @@ -213,7 +216,7 @@ contract Verifier_accessControlledVerify is BaseTestWithConfiguredVerifierAndFee BLOCKNUMBER_LOWER_BOUND, uint32(block.timestamp) ); - (, , s_configDigest) = s_verifier.latestConfigDetails(FEED_ID); + s_configDigest = v1ConfigDigest; bytes32[3] memory reportContext; reportContext[0] = s_configDigest; reportContext[1] = bytes32(abi.encode(uint32(5), uint8(1))); diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/mocks/ErroredVerifier.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/mocks/ErroredVerifier.sol index e9dcd589e23..da0ad973cb1 100644 --- a/contracts/src/v0.8/llo-feeds/v0.5.0/test/mocks/ErroredVerifier.sol +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/mocks/ErroredVerifier.sol @@ -40,20 +40,8 @@ contract ErroredVerifier is IVerifier { revert FailedToVerify(); } - function setConfig( - bytes32, - address[] memory, - bytes32[] memory, - uint8, - bytes memory, - uint64, - bytes memory, - Common.AddressAndWeight[] memory - ) external pure override { - revert FailedToSetConfig(); - } - function setConfigFromSource( + function setConfig( bytes32, uint256, address, @@ -69,27 +57,15 @@ contract ErroredVerifier is IVerifier { revert FailedToSetConfig(); } - function activateConfig(bytes32, bytes32) external pure { + function activateConfig(bytes32) external pure { revert FailedToActivateConfig(); } - function deactivateConfig(bytes32, bytes32) external pure { + function deactivateConfig(bytes32) external pure { revert FailedToDeactivateConfig(); } - function activateFeed(bytes32) external pure { - revert FailedToActivateFeed(); - } - - function deactivateFeed(bytes32) external pure { - revert FailedToDeactivateFeed(); - } - - function latestConfigDigestAndEpoch(bytes32) external pure override returns (bool, bytes32, uint32) { - revert FailedToGetLatestConfigDigestAndEpoch(); - } - - function latestConfigDetails(bytes32) external pure override returns (uint32, uint32, bytes32) { + function latestConfigDetails(bytes32) external pure override returns (uint32, uint32) { revert FailedToGetLatestConfigDetails(); } } diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/BaseVerifierTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/BaseVerifierTest.t.sol index 4d65414676e..b1aa872be0f 100644 --- a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/BaseVerifierTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/BaseVerifierTest.t.sol @@ -28,6 +28,9 @@ contract BaseTest is Test { bytes32 internal constant V2_BITMASK = 0x0002000000000000000000000000000000000000000000000000000000000000; bytes32 internal constant V3_BITMASK = 0x0003000000000000000000000000000000000000000000000000000000000000; + uint256 internal constant SOURCE_CHAIN_ID = 0x1234; + address internal constant SOURCE_ADDRESS = address(0x1234); + //version 0 feeds bytes32 internal constant FEED_ID = (keccak256("ETH-USD") & V_MASK) | V1_BITMASK; bytes32 internal constant FEED_ID_2 = (keccak256("LINK-USD") & V_MASK) | V1_BITMASK; @@ -205,7 +208,7 @@ contract BaseTest is Test { ) ); uint256 prefixMask = type(uint256).max << (256 - 16); // 0xFFFF00..00 - uint256 prefix = 0x0006 << (256 - 16); // 0x000600..00 + uint256 prefix = 0x0009 << (256 - 16); // 0x000900..00 return bytes32((prefix & prefixMask) | (h & ~prefixMask)); } @@ -288,6 +291,9 @@ contract BaseTestWithConfiguredVerifierAndFeeManager is BaseTest { s_verifierProxy.initializeVerifier(address(s_verifier)); s_verifier.setConfig( FEED_ID, + SOURCE_CHAIN_ID, + SOURCE_ADDRESS, + 1, _getSignerAddresses(signers), s_offchaintransmitters, FAULT_TOLERANCE, @@ -296,10 +302,25 @@ contract BaseTestWithConfiguredVerifierAndFeeManager is BaseTest { bytes(""), new Common.AddressAndWeight[](0) ); - (, , v1ConfigDigest) = s_verifier.latestConfigDetails(FEED_ID); + + v1ConfigDigest = _configDigestFromConfigData( + FEED_ID, + SOURCE_CHAIN_ID, + SOURCE_ADDRESS, + 1, + _getSignerAddresses(signers), + s_offchaintransmitters, + FAULT_TOLERANCE, + bytes(""), + VERIFIER_VERSION, + bytes("") + ); s_verifier.setConfig( FEED_ID_V3, + SOURCE_CHAIN_ID, + SOURCE_ADDRESS, + 1, _getSignerAddresses(signers), s_offchaintransmitters, FAULT_TOLERANCE, @@ -308,7 +329,19 @@ contract BaseTestWithConfiguredVerifierAndFeeManager is BaseTest { bytes(""), new Common.AddressAndWeight[](0) ); - (, , v3ConfigDigest) = s_verifier.latestConfigDetails(FEED_ID_V3); + + v3ConfigDigest = _configDigestFromConfigData( + FEED_ID_V3, + SOURCE_CHAIN_ID, + SOURCE_ADDRESS, + 1, + _getSignerAddresses(signers), + s_offchaintransmitters, + FAULT_TOLERANCE, + bytes(""), + VERIFIER_VERSION, + bytes("") + ); link = new ERC20Mock("LINK", "LINK", ADMIN, 0); native = new WERC20Mock(); @@ -442,12 +475,15 @@ contract BaseTestWithMultipleConfiguredDigests is BaseTestWithConfiguredVerifier BaseTestWithConfiguredVerifierAndFeeManager.setUp(); Signer[] memory signers = _getSigners(MAX_ORACLES); - (, , s_configDigestOne) = s_verifier.latestConfigDetails(FEED_ID); + s_configDigestOne = v1ConfigDigest; // Verifier 1, Feed 1, Config 2 Signer[] memory secondSetOfSigners = _getSigners(8); s_verifier.setConfig( FEED_ID, + SOURCE_CHAIN_ID, + SOURCE_ADDRESS, + 2, _getSignerAddresses(secondSetOfSigners), s_offchaintransmitters, FAULT_TOLERANCE_TWO, @@ -456,12 +492,27 @@ contract BaseTestWithMultipleConfiguredDigests is BaseTestWithConfiguredVerifier bytes(""), new Common.AddressAndWeight[](0) ); - (, , s_configDigestTwo) = s_verifier.latestConfigDetails(FEED_ID); + + s_configDigestTwo = _configDigestFromConfigData( + FEED_ID, + SOURCE_CHAIN_ID, + SOURCE_ADDRESS, + 2, + _getSignerAddresses(secondSetOfSigners), + s_offchaintransmitters, + FAULT_TOLERANCE_TWO, + bytes(""), + 2, + bytes("") + ); // Verifier 1, Feed 1, Config 3 Signer[] memory thirdSetOfSigners = _getSigners(5); s_verifier.setConfig( FEED_ID, + SOURCE_CHAIN_ID, + SOURCE_ADDRESS, + 3, _getSignerAddresses(thirdSetOfSigners), s_offchaintransmitters, FAULT_TOLERANCE_THREE, @@ -470,11 +521,25 @@ contract BaseTestWithMultipleConfiguredDigests is BaseTestWithConfiguredVerifier bytes(""), new Common.AddressAndWeight[](0) ); - (s_numConfigsSet, , s_configDigestThree) = s_verifier.latestConfigDetails(FEED_ID); + s_configDigestThree = _configDigestFromConfigData( + FEED_ID, + SOURCE_CHAIN_ID, + SOURCE_ADDRESS, + 3, + _getSignerAddresses(thirdSetOfSigners), + s_offchaintransmitters, + FAULT_TOLERANCE_THREE, + bytes(""), + 3, + bytes("") + ); // Verifier 1, Feed 2, Config 1 s_verifier.setConfig( FEED_ID_2, + SOURCE_CHAIN_ID, + SOURCE_ADDRESS, + 1, _getSignerAddresses(signers), s_offchaintransmitters, FAULT_TOLERANCE, @@ -483,20 +548,45 @@ contract BaseTestWithMultipleConfiguredDigests is BaseTestWithConfiguredVerifier bytes(""), new Common.AddressAndWeight[](0) ); - (, , s_configDigestFour) = s_verifier.latestConfigDetails(FEED_ID_2); + s_configDigestFour = _configDigestFromConfigData( + FEED_ID_2, + SOURCE_CHAIN_ID, + SOURCE_ADDRESS, + 1, + _getSignerAddresses(signers), + s_offchaintransmitters, + FAULT_TOLERANCE, + bytes(""), + 4, + bytes("") + ); // Verifier 2, Feed 3, Config 1 s_verifierProxy.initializeVerifier(address(s_verifier_2)); s_verifier_2.setConfig( FEED_ID_3, + SOURCE_CHAIN_ID, + SOURCE_ADDRESS, + 1, _getSignerAddresses(signers), s_offchaintransmitters, FAULT_TOLERANCE, bytes(""), - VERIFIER_VERSION, + 5, bytes(""), new Common.AddressAndWeight[](0) ); - (, , s_configDigestFive) = s_verifier_2.latestConfigDetails(FEED_ID_3); + s_configDigestFive = _configDigestFromConfigData( + FEED_ID_3, + SOURCE_CHAIN_ID, + SOURCE_ADDRESS, + 1, + _getSignerAddresses(signers), + s_offchaintransmitters, + FAULT_TOLERANCE, + bytes(""), + 5, + bytes("") + ); } } diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierActivateConfigTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierActivateConfigTest.t.sol index 99daabe206b..b7d0975c143 100644 --- a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierActivateConfigTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierActivateConfigTest.t.sol @@ -2,24 +2,24 @@ pragma solidity 0.8.19; import {BaseTestWithConfiguredVerifierAndFeeManager, BaseTestWithMultipleConfiguredDigests} from "./BaseVerifierTest.t.sol"; -import {Verifier} from "../../../v0.3.0/Verifier.sol"; +import {Verifier} from "../../Verifier.sol"; contract VerifierActivateConfigTest is BaseTestWithConfiguredVerifierAndFeeManager { function test_revertsIfNotOwner() public { vm.expectRevert("Only callable by owner"); changePrank(address(s_verifierProxy)); - s_verifier.activateConfig(FEED_ID, bytes32("mock")); + s_verifier.activateConfig(bytes32("mock")); } function test_revertsIfDigestIsEmpty() public { vm.expectRevert(abi.encodeWithSelector(Verifier.DigestEmpty.selector)); - s_verifier.activateConfig(FEED_ID, bytes32("")); + s_verifier.activateConfig(bytes32("")); } function test_revertsIfDigestNotSet() public { - vm.expectRevert(abi.encodeWithSelector(Verifier.DigestNotSet.selector, FEED_ID, bytes32("non-existent-digest"))); - s_verifier.activateConfig(FEED_ID, bytes32("non-existent-digest")); + vm.expectRevert(abi.encodeWithSelector(Verifier.DigestNotSet.selector, bytes32("non-existent-digest"))); + s_verifier.activateConfig(bytes32("non-existent-digest")); } } @@ -46,11 +46,11 @@ contract VerifierActivateConfigWithDeactivatedConfigTest is BaseTestWithMultiple uint32(block.timestamp) ); - s_verifier.deactivateConfig(FEED_ID, s_configDigestTwo); + s_verifier.deactivateConfig(s_configDigestTwo); } function test_allowsVerification() public { - s_verifier.activateConfig(FEED_ID, s_configDigestTwo); + s_verifier.activateConfig(s_configDigestTwo); changePrank(address(s_verifierProxy)); bytes memory signedReport = _generateV1EncodedBlob( diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierDeactivateFeedTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierDeactivateFeedTest.t.sol deleted file mode 100644 index fb52c1c93e7..00000000000 --- a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierDeactivateFeedTest.t.sol +++ /dev/null @@ -1,108 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity 0.8.19; - -import {BaseTestWithConfiguredVerifierAndFeeManager, BaseTestWithMultipleConfiguredDigests} from "./BaseVerifierTest.t.sol"; -import {Verifier} from "../../../v0.3.0/Verifier.sol"; - -contract VerifierActivateFeedTest is BaseTestWithConfiguredVerifierAndFeeManager { - function test_revertsIfNotOwnerActivateFeed() public { - changePrank(address(s_verifierProxy)); - vm.expectRevert("Only callable by owner"); - s_verifier.activateFeed(FEED_ID); - } - - function test_revertsIfNotOwnerDeactivateFeed() public { - changePrank(address(s_verifierProxy)); - vm.expectRevert("Only callable by owner"); - s_verifier.deactivateFeed(FEED_ID); - } - - function test_revertsIfNoFeedExistsActivate() public { - vm.expectRevert(abi.encodeWithSelector(Verifier.InvalidFeed.selector, INVALID_FEED)); - s_verifier.activateFeed(INVALID_FEED); - } - - function test_revertsIfNoFeedExistsDeactivate() public { - vm.expectRevert(abi.encodeWithSelector(Verifier.InvalidFeed.selector, INVALID_FEED)); - s_verifier.deactivateFeed(INVALID_FEED); - } -} - -contract VerifierDeactivateFeedWithVerifyTest is BaseTestWithMultipleConfiguredDigests { - bytes32[3] internal s_reportContext; - - event ConfigActivated(bytes32 configDigest); - - V1Report internal s_testReportOne; - - function setUp() public override { - BaseTestWithMultipleConfiguredDigests.setUp(); - s_reportContext[0] = s_configDigestOne; - s_reportContext[1] = bytes32(abi.encode(uint32(5), uint8(1))); - s_testReportOne = _createV1Report( - FEED_ID, - uint32(block.timestamp), - MEDIAN, - BID, - ASK, - uint64(block.number), - blockhash(block.number + 3), - uint64(block.number + 3), - uint32(block.timestamp) - ); - - s_verifier.deactivateFeed(FEED_ID); - } - - function test_currentReportAllowsVerification() public { - s_verifier.activateFeed(FEED_ID); - changePrank(address(s_verifierProxy)); - - bytes memory signedReport = _generateV1EncodedBlob( - s_testReportOne, - s_reportContext, - _getSigners(FAULT_TOLERANCE + 1) - ); - s_verifier.verify(signedReport, msg.sender); - } - - function test_previousReportAllowsVerification() public { - s_verifier.activateFeed(FEED_ID); - changePrank(address(s_verifierProxy)); - - s_reportContext[0] = s_configDigestTwo; - bytes memory signedReport = _generateV1EncodedBlob( - s_testReportOne, - s_reportContext, - _getSigners(FAULT_TOLERANCE_TWO + 1) - ); - s_verifier.verify(signedReport, msg.sender); - } - - function test_currentReportFailsVerification() public { - changePrank(address(s_verifierProxy)); - - bytes memory signedReport = _generateV1EncodedBlob( - s_testReportOne, - s_reportContext, - _getSigners(FAULT_TOLERANCE + 1) - ); - - vm.expectRevert(abi.encodeWithSelector(Verifier.InactiveFeed.selector, FEED_ID)); - s_verifier.verify(signedReport, msg.sender); - } - - function test_previousReportFailsVerification() public { - changePrank(address(s_verifierProxy)); - - s_reportContext[0] = s_configDigestTwo; - bytes memory signedReport = _generateV1EncodedBlob( - s_testReportOne, - s_reportContext, - _getSigners(FAULT_TOLERANCE_TWO + 1) - ); - - vm.expectRevert(abi.encodeWithSelector(Verifier.InactiveFeed.selector, FEED_ID)); - s_verifier.verify(signedReport, msg.sender); - } -} diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierProxyConstructorTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierProxyConstructorTest.t.sol index 82efd8907be..811a9b440ee 100644 --- a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierProxyConstructorTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierProxyConstructorTest.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.19; import {BaseTest} from "./BaseVerifierTest.t.sol"; -import {VerifierProxy} from "../../../v0.3.0/VerifierProxy.sol"; +import {VerifierProxy} from "../../VerifierProxy.sol"; import {AccessControllerInterface} from "../../../../shared/interfaces/AccessControllerInterface.sol"; contract VerifierProxyConstructorTest is BaseTest { diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierProxyInitializeVerifierTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierProxyInitializeVerifierTest.t.sol index 5537d273be9..e02b14fe56e 100644 --- a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierProxyInitializeVerifierTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierProxyInitializeVerifierTest.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.19; import {BaseTest} from "./BaseVerifierTest.t.sol"; -import {VerifierProxy} from "../../../v0.3.0/VerifierProxy.sol"; +import {VerifierProxy} from "../../VerifierProxy.sol"; contract VerifierProxyInitializeVerifierTest is BaseTest { bytes32 latestDigest; diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierProxySetVerifierTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierProxySetVerifierTest.t.sol index 78e5ff0766f..45f64bf5533 100644 --- a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierProxySetVerifierTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierProxySetVerifierTest.t.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.19; import {BaseTestWithConfiguredVerifierAndFeeManager} from "./BaseVerifierTest.t.sol"; import {IVerifier} from "../../interfaces/IVerifier.sol"; -import {VerifierProxy} from "../../../v0.3.0/VerifierProxy.sol"; +import {VerifierProxy} from "../../VerifierProxy.sol"; import {IERC165} from "../../../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; import {Common} from "../../../libraries/Common.sol"; @@ -14,7 +14,7 @@ contract VerifierProxyInitializeVerifierTest is BaseTestWithConfiguredVerifierAn } function test_revertsIfDigestAlreadySet() public { - (, , bytes32 takenDigest) = s_verifier.latestConfigDetails(FEED_ID); + bytes32 takenDigest = v1ConfigDigest; address maliciousVerifier = address(666); bytes32 maliciousDigest = bytes32("malicious-digest"); @@ -32,7 +32,7 @@ contract VerifierProxyInitializeVerifierTest is BaseTestWithConfiguredVerifierAn } function test_updatesVerifierIfVerifier() public { - (, , bytes32 prevDigest) = s_verifier.latestConfigDetails(FEED_ID); + bytes32 prevDigest = v1ConfigDigest; changePrank(address(s_verifier)); s_verifierProxy.setVerifier(prevDigest, bytes32("new-config"), new Common.AddressAndWeight[](0)); assertEq(s_verifierProxy.getVerifier(bytes32("new-config")), address(s_verifier)); diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierProxyUnsetVerifierTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierProxyUnsetVerifierTest.t.sol index a51c67e336c..74da281a3cd 100644 --- a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierProxyUnsetVerifierTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierProxyUnsetVerifierTest.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.19; import {BaseTest, BaseTestWithConfiguredVerifierAndFeeManager} from "./BaseVerifierTest.t.sol"; -import {VerifierProxy} from "../../../v0.3.0/VerifierProxy.sol"; +import {VerifierProxy} from "../../VerifierProxy.sol"; contract VerifierProxyUnsetVerifierTest is BaseTest { function test_revertsIfNotAdmin() public { @@ -25,7 +25,7 @@ contract VerifierProxyUnsetVerifierWithPreviouslySetVerifierTest is BaseTestWith function setUp() public override { BaseTestWithConfiguredVerifierAndFeeManager.setUp(); - (, , s_configDigest) = s_verifier.latestConfigDetails(FEED_ID); + s_configDigest = v3ConfigDigest; } function test_correctlyUnsetsVerifier() public { diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierSetConfigFromSourceTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierSetConfigFromSourceTest.t.sol deleted file mode 100644 index 9ee9b5272a7..00000000000 --- a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierSetConfigFromSourceTest.t.sol +++ /dev/null @@ -1,134 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity 0.8.19; - -import {BaseTest, BaseTestWithMultipleConfiguredDigests} from "./BaseVerifierTest.t.sol"; -import {Common} from "../../../libraries/Common.sol"; - -contract VerifierSetConfigFromSourceTest is BaseTest { - function setUp() public virtual override { - BaseTest.setUp(); - } - - function test_revertsIfCalledByNonOwner() public { - vm.expectRevert("Only callable by owner"); - Signer[] memory signers = _getSigners(MAX_ORACLES); - - changePrank(USER); - s_verifier.setConfigFromSource( - FEED_ID, - 12345, - address(12345), - 0, - _getSignerAddresses(signers), - s_offchaintransmitters, - FAULT_TOLERANCE, - bytes(""), - VERIFIER_VERSION, - bytes(""), - new Common.AddressAndWeight[](0) - ); - } -} - -contract VerifierSetConfigFromSourceMultipleDigestsTest is BaseTestWithMultipleConfiguredDigests { - function test_correctlyUpdatesTheDigestInTheProxy() public { - Signer[] memory newSigners = _getSigners(15); - - s_verifier.setConfigFromSource( - FEED_ID, - 12345, - address(12345), - 0, - _getSignerAddresses(newSigners), - s_offchaintransmitters, - 4, - bytes(""), - VERIFIER_VERSION, - bytes(""), - new Common.AddressAndWeight[](0) - ); - - (, , bytes32 configDigest) = s_verifier.latestConfigDetails(FEED_ID); - address verifierAddr = s_verifierProxy.getVerifier(configDigest); - assertEq(verifierAddr, address(s_verifier)); - } - - function test_correctlyUpdatesDigestsOnMultipleVerifiersInTheProxy() public { - Signer[] memory newSigners = _getSigners(15); - - s_verifier.setConfigFromSource( - FEED_ID_2, - 12345, - address(12345), - 0, - _getSignerAddresses(newSigners), - s_offchaintransmitters, - 4, - bytes(""), - VERIFIER_VERSION, - bytes(""), - new Common.AddressAndWeight[](0) - ); - - (, , bytes32 configDigest) = s_verifier.latestConfigDetails(FEED_ID_2); - address verifierAddr = s_verifierProxy.getVerifier(configDigest); - assertEq(verifierAddr, address(s_verifier)); - - s_verifier_2.setConfigFromSource( - FEED_ID_3, - 12345, - address(12345), - 0, - _getSignerAddresses(newSigners), - s_offchaintransmitters, - 4, - bytes(""), - VERIFIER_VERSION, - bytes(""), - new Common.AddressAndWeight[](0) - ); - - (, , bytes32 configDigest2) = s_verifier_2.latestConfigDetails(FEED_ID_3); - address verifierAddr2 = s_verifierProxy.getVerifier(configDigest2); - assertEq(verifierAddr2, address(s_verifier_2)); - } - - function test_correctlySetsConfigWhenDigestsAreRemoved() public { - s_verifier.deactivateConfig(FEED_ID, s_configDigestTwo); - - Signer[] memory newSigners = _getSigners(15); - - s_verifier.setConfigFromSource( - FEED_ID, - 12345, - address(s_verifier), - 0, - _getSignerAddresses(newSigners), - s_offchaintransmitters, - 4, - bytes(""), - VERIFIER_VERSION, - bytes(""), - new Common.AddressAndWeight[](0) - ); - - bytes32 expectedConfigDigest = _configDigestFromConfigData( - FEED_ID, - 12345, - address(s_verifier), - s_numConfigsSet + 1, - _getSignerAddresses(newSigners), - s_offchaintransmitters, - 4, - bytes(""), - VERIFIER_VERSION, - bytes("") - ); - - (uint32 configCount, uint32 blockNumber, bytes32 configDigest) = s_verifier.latestConfigDetails(FEED_ID); - - assertEq(configCount, s_numConfigsSet + 1); - assertEq(blockNumber, block.number); - assertEq(configDigest, expectedConfigDigest); - } -} diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierSetConfigTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierSetConfigTest.t.sol index 972ead81230..02784226863 100644 --- a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierSetConfigTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierSetConfigTest.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.19; import {BaseTest, BaseTestWithMultipleConfiguredDigests} from "./BaseVerifierTest.t.sol"; -import {Verifier} from "../../../v0.3.0/Verifier.sol"; +import {Verifier} from "../../Verifier.sol"; import {Common} from "../../../libraries/Common.sol"; contract VerifierSetConfigTest is BaseTest { @@ -17,6 +17,9 @@ contract VerifierSetConfigTest is BaseTest { changePrank(USER); s_verifier.setConfig( FEED_ID, + SOURCE_CHAIN_ID, + SOURCE_ADDRESS, + 1, _getSignerAddresses(signers), s_offchaintransmitters, FAULT_TOLERANCE, @@ -32,6 +35,9 @@ contract VerifierSetConfigTest is BaseTest { vm.expectRevert(abi.encodeWithSelector(Verifier.ExcessSigners.selector, signers.length, MAX_ORACLES)); s_verifier.setConfig( FEED_ID, + SOURCE_CHAIN_ID, + SOURCE_ADDRESS, + 1, signers, s_offchaintransmitters, FAULT_TOLERANCE, @@ -47,6 +53,9 @@ contract VerifierSetConfigTest is BaseTest { Signer[] memory signers = _getSigners(MAX_ORACLES); s_verifier.setConfig( FEED_ID, + SOURCE_CHAIN_ID, + SOURCE_ADDRESS, + 1, _getSignerAddresses(signers), s_offchaintransmitters, 0, @@ -67,6 +76,9 @@ contract VerifierSetConfigTest is BaseTest { ); s_verifier.setConfig( FEED_ID, + SOURCE_CHAIN_ID, + SOURCE_ADDRESS, + 1, signers, s_offchaintransmitters, FAULT_TOLERANCE, @@ -84,6 +96,9 @@ contract VerifierSetConfigTest is BaseTest { vm.expectRevert(abi.encodeWithSelector(Verifier.NonUniqueSignatures.selector)); s_verifier.setConfig( FEED_ID, + SOURCE_CHAIN_ID, + SOURCE_ADDRESS, + 1, signerAddrs, s_offchaintransmitters, FAULT_TOLERANCE, @@ -101,6 +116,9 @@ contract VerifierSetConfigTest is BaseTest { vm.expectRevert(abi.encodeWithSelector(Verifier.ZeroAddress.selector)); s_verifier.setConfig( FEED_ID, + SOURCE_CHAIN_ID, + SOURCE_ADDRESS, + 1, signerAddrs, s_offchaintransmitters, FAULT_TOLERANCE, @@ -117,6 +135,9 @@ contract VerifierSetConfigTest is BaseTest { s_verifierProxy.initializeVerifier(address(s_verifier)); s_verifier.setConfig( FEED_ID, + SOURCE_CHAIN_ID, + SOURCE_ADDRESS, + 1, _getSignerAddresses(signers), s_offchaintransmitters, FAULT_TOLERANCE, @@ -126,10 +147,10 @@ contract VerifierSetConfigTest is BaseTest { new Common.AddressAndWeight[](0) ); - bytes32 expectedConfigDigest = _configDigestFromConfigData( + bytes32 configDigest = _configDigestFromConfigData( FEED_ID, - block.chainid, - address(s_verifier), + SOURCE_CHAIN_ID, + SOURCE_ADDRESS, 1, _getSignerAddresses(signers), s_offchaintransmitters, @@ -139,15 +160,9 @@ contract VerifierSetConfigTest is BaseTest { bytes("") ); - (uint32 configCount, uint32 blockNumber, bytes32 configDigest) = s_verifier.latestConfigDetails(FEED_ID); + (uint32 configCount, uint32 blockNumber) = s_verifier.latestConfigDetails(configDigest); assertEq(configCount, 1); assertEq(blockNumber, block.number); - assertEq(configDigest, expectedConfigDigest); - - (bool scanLogs, bytes32 configDigestTwo, uint32 epoch) = s_verifier.latestConfigDigestAndEpoch(FEED_ID); - assertEq(scanLogs, false); - assertEq(configDigestTwo, expectedConfigDigest); - assertEq(epoch, 0); } } @@ -157,6 +172,9 @@ contract VerifierSetConfigWhenThereAreMultipleDigestsTest is BaseTestWithMultipl s_verifier.setConfig( FEED_ID, + SOURCE_CHAIN_ID, + SOURCE_ADDRESS, + 1, _getSignerAddresses(newSigners), s_offchaintransmitters, 4, @@ -166,7 +184,19 @@ contract VerifierSetConfigWhenThereAreMultipleDigestsTest is BaseTestWithMultipl new Common.AddressAndWeight[](0) ); - (, , bytes32 configDigest) = s_verifier.latestConfigDetails(FEED_ID); + bytes32 configDigest = _configDigestFromConfigData( + FEED_ID, + SOURCE_CHAIN_ID, + SOURCE_ADDRESS, + 1, + _getSignerAddresses(newSigners), + s_offchaintransmitters, + 4, + bytes(""), + VERIFIER_VERSION, + bytes("") + ); + address verifierAddr = s_verifierProxy.getVerifier(configDigest); assertEq(verifierAddr, address(s_verifier)); } @@ -176,6 +206,9 @@ contract VerifierSetConfigWhenThereAreMultipleDigestsTest is BaseTestWithMultipl s_verifier.setConfig( FEED_ID_2, + SOURCE_CHAIN_ID, + SOURCE_ADDRESS, + 1, _getSignerAddresses(newSigners), s_offchaintransmitters, 4, @@ -185,12 +218,27 @@ contract VerifierSetConfigWhenThereAreMultipleDigestsTest is BaseTestWithMultipl new Common.AddressAndWeight[](0) ); - (, , bytes32 configDigest) = s_verifier.latestConfigDetails(FEED_ID_2); + bytes32 configDigest = _configDigestFromConfigData( + FEED_ID_2, + SOURCE_CHAIN_ID, + SOURCE_ADDRESS, + 1, + _getSignerAddresses(newSigners), + s_offchaintransmitters, + 4, + bytes(""), + VERIFIER_VERSION, + bytes("") + ); + address verifierAddr = s_verifierProxy.getVerifier(configDigest); assertEq(verifierAddr, address(s_verifier)); s_verifier_2.setConfig( FEED_ID_3, + SOURCE_CHAIN_ID, + SOURCE_ADDRESS, + 1, _getSignerAddresses(newSigners), s_offchaintransmitters, 4, @@ -200,18 +248,33 @@ contract VerifierSetConfigWhenThereAreMultipleDigestsTest is BaseTestWithMultipl new Common.AddressAndWeight[](0) ); - (, , bytes32 configDigest2) = s_verifier_2.latestConfigDetails(FEED_ID_3); + bytes32 configDigest2 = _configDigestFromConfigData( + FEED_ID_3, + SOURCE_CHAIN_ID, + SOURCE_ADDRESS, + 1, + _getSignerAddresses(newSigners), + s_offchaintransmitters, + 4, + bytes(""), + VERIFIER_VERSION, + bytes("") + ); + address verifierAddr2 = s_verifierProxy.getVerifier(configDigest2); assertEq(verifierAddr2, address(s_verifier_2)); } function test_correctlySetsConfigWhenDigestsAreRemoved() public { - s_verifier.deactivateConfig(FEED_ID, s_configDigestTwo); + s_verifier.deactivateConfig(s_configDigestTwo); Signer[] memory newSigners = _getSigners(15); s_verifier.setConfig( FEED_ID, + SOURCE_CHAIN_ID, + SOURCE_ADDRESS, + 1, _getSignerAddresses(newSigners), s_offchaintransmitters, 4, @@ -223,9 +286,22 @@ contract VerifierSetConfigWhenThereAreMultipleDigestsTest is BaseTestWithMultipl bytes32 expectedConfigDigest = _configDigestFromConfigData( FEED_ID, - block.chainid, - address(s_verifier), - s_numConfigsSet + 1, + SOURCE_CHAIN_ID, + SOURCE_ADDRESS, + 1, + _getSignerAddresses(newSigners), + s_offchaintransmitters, + 4, + bytes(""), + VERIFIER_VERSION, + bytes("") + ); + + bytes32 configDigest = _configDigestFromConfigData( + FEED_ID, + SOURCE_CHAIN_ID, + SOURCE_ADDRESS, + 1, _getSignerAddresses(newSigners), s_offchaintransmitters, 4, @@ -234,7 +310,7 @@ contract VerifierSetConfigWhenThereAreMultipleDigestsTest is BaseTestWithMultipl bytes("") ); - (uint32 configCount, uint32 blockNumber, bytes32 configDigest) = s_verifier.latestConfigDetails(FEED_ID); + (uint32 configCount, uint32 blockNumber) = s_verifier.latestConfigDetails(configDigest); assertEq(configCount, s_numConfigsSet + 1); assertEq(blockNumber, block.number); diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierTest.t.sol index 81f65f0c6eb..7f8fc472c35 100644 --- a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierTest.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.19; import {BaseTest} from "./BaseVerifierTest.t.sol"; -import {Verifier} from "../../../v0.3.0/Verifier.sol"; +import {Verifier} from "../../Verifier.sol"; contract VerifierConstructorTest is BaseTest { function test_revertsIfInitializedWithEmptyVerifierProxy() public { @@ -14,18 +14,12 @@ contract VerifierConstructorTest is BaseTest { Verifier v = new Verifier(address(s_verifierProxy)); assertEq(v.owner(), ADMIN); - (bool scanLogs, bytes32 configDigest, uint32 epoch) = v.latestConfigDigestAndEpoch(FEED_ID); - assertEq(scanLogs, false); - assertEq(configDigest, EMPTY_BYTES); - assertEq(epoch, 0); - - (uint32 configCount, uint32 blockNumber, bytes32 configDigestTwo) = v.latestConfigDetails(FEED_ID); + (uint32 configCount, uint32 blockNumber) = v.latestConfigDetails(FEED_ID); assertEq(configCount, 0); assertEq(blockNumber, 0); - assertEq(configDigestTwo, EMPTY_BYTES); string memory typeAndVersion = s_verifier.typeAndVersion(); - assertEq(typeAndVersion, "Verifier 1.2.0"); + assertEq(typeAndVersion, "Verifier 2.0.0"); } } diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierUnsetConfigTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierUnsetConfigTest.t.sol index e192a2e9e08..64c9f77a7e7 100644 --- a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierUnsetConfigTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierUnsetConfigTest.t.sol @@ -2,55 +2,23 @@ pragma solidity 0.8.19; import {BaseTestWithMultipleConfiguredDigests} from "./BaseVerifierTest.t.sol"; -import {Verifier} from "../../../v0.3.0/Verifier.sol"; +import {Verifier} from "../../Verifier.sol"; contract VerificationdeactivateConfigWhenThereAreMultipleDigestsTest is BaseTestWithMultipleConfiguredDigests { function test_revertsIfCalledByNonOwner() public { vm.expectRevert("Only callable by owner"); changePrank(USER); - s_verifier.deactivateConfig(FEED_ID, bytes32("")); + s_verifier.deactivateConfig(bytes32("")); } function test_revertsIfRemovingAnEmptyDigest() public { vm.expectRevert(abi.encodeWithSelector(Verifier.DigestEmpty.selector)); - s_verifier.deactivateConfig(FEED_ID, bytes32("")); + s_verifier.deactivateConfig(bytes32("")); } function test_revertsIfRemovingAnNonExistentDigest() public { - vm.expectRevert(abi.encodeWithSelector(Verifier.DigestNotSet.selector, FEED_ID, bytes32("mock-digest"))); - s_verifier.deactivateConfig(FEED_ID, bytes32("mock-digest")); - } - - function test_correctlyRemovesAMiddleDigest() public { - s_verifier.deactivateConfig(FEED_ID, s_configDigestTwo); - (, , bytes32 lastConfigDigest) = s_verifier.latestConfigDetails(FEED_ID); - assertEq(lastConfigDigest, s_configDigestThree); - } - - function test_correctlyRemovesTheFirstDigest() public { - s_verifier.deactivateConfig(FEED_ID, s_configDigestOne); - (, , bytes32 lastConfigDigest) = s_verifier.latestConfigDetails(FEED_ID); - assertEq(lastConfigDigest, s_configDigestThree); - } - - function test_correctlyUnsetsDigestsInSequence() public { - // Delete config digest 2 - s_verifier.deactivateConfig(FEED_ID, s_configDigestTwo); - (, , bytes32 lastConfigDigest) = s_verifier.latestConfigDetails(FEED_ID); - assertEq(lastConfigDigest, s_configDigestThree); - - // Delete config digest 1 - s_verifier.deactivateConfig(FEED_ID, s_configDigestOne); - (, , lastConfigDigest) = s_verifier.latestConfigDetails(FEED_ID); - assertEq(lastConfigDigest, s_configDigestThree); - - // Delete config digest 3 - vm.expectRevert( - abi.encodeWithSelector(Verifier.CannotDeactivateLatestConfig.selector, FEED_ID, s_configDigestThree) - ); - s_verifier.deactivateConfig(FEED_ID, s_configDigestThree); - (, , lastConfigDigest) = s_verifier.latestConfigDetails(FEED_ID); - assertEq(lastConfigDigest, s_configDigestThree); + vm.expectRevert(abi.encodeWithSelector(Verifier.DigestNotSet.selector, bytes32("mock-digest"))); + s_verifier.deactivateConfig(bytes32("mock-digest")); } } diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierVerifyTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierVerifyTest.t.sol index 1c14ba974c0..151314df22a 100644 --- a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierVerifyTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierVerifyTest.t.sol @@ -2,8 +2,8 @@ pragma solidity 0.8.19; import {BaseTestWithConfiguredVerifierAndFeeManager} from "./BaseVerifierTest.t.sol"; -import {Verifier} from "../../../v0.3.0/Verifier.sol"; -import {VerifierProxy} from "../../../v0.3.0/VerifierProxy.sol"; +import {Verifier} from "../../Verifier.sol"; +import {VerifierProxy} from "../../VerifierProxy.sol"; import {AccessControllerInterface} from "../../../../shared/interfaces/AccessControllerInterface.sol"; import {Common} from "../../../libraries/Common.sol"; @@ -16,8 +16,7 @@ contract VerifierVerifyTest is BaseTestWithConfiguredVerifierAndFeeManager { function setUp() public virtual override { BaseTestWithConfiguredVerifierAndFeeManager.setUp(); - (, , bytes32 configDigest) = s_verifier.latestConfigDetails(FEED_ID); - s_reportContext[0] = configDigest; + s_reportContext[0] = v1ConfigDigest; s_reportContext[1] = bytes32(abi.encode(uint32(5), uint8(1))); s_testReportOne = _createV1Report( FEED_ID, @@ -160,12 +159,12 @@ contract VerifierVerifySingleConfigDigestTest is VerifierVerifyTest { reportContext, _getSigners(FAULT_TOLERANCE + 1) ); - vm.expectRevert(abi.encodeWithSelector(Verifier.DigestInactive.selector, FEED_ID, reportContext[0])); + vm.expectRevert(abi.encodeWithSelector(Verifier.DigestInactive.selector, reportContext[0])); changePrank(address(s_verifierProxy)); s_verifier.verify(signedReport, msg.sender); } - function test_revertsIfReportHasUnconfiguredFeedID() public { + function test_revertsIfReportHasUnconfiguredConfigDigest() public { V1Report memory report = _createV1Report( FEED_ID_2, OBSERVATIONS_TIMESTAMP, @@ -177,8 +176,9 @@ contract VerifierVerifySingleConfigDigestTest is VerifierVerifyTest { BLOCKNUMBER_LOWER_BOUND, uint32(block.timestamp) ); + s_reportContext[0] = keccak256("unconfigured-digesty"); bytes memory signedReport = _generateV1EncodedBlob(report, s_reportContext, _getSigners(FAULT_TOLERANCE + 1)); - vm.expectRevert(abi.encodeWithSelector(Verifier.DigestInactive.selector, FEED_ID_2, s_reportContext[0])); + vm.expectRevert(abi.encodeWithSelector(Verifier.DigestInactive.selector, s_reportContext[0])); changePrank(address(s_verifierProxy)); s_verifier.verify(signedReport, msg.sender); } @@ -212,20 +212,6 @@ contract VerifierVerifySingleConfigDigestTest is VerifierVerifyTest { assertReportsEqual(response, s_testReportOne); } - function test_setsTheCorrectEpoch() public { - s_reportContext[1] = bytes32(uint256(5 << 8)); - bytes memory signedReport = _generateV1EncodedBlob( - s_testReportOne, - s_reportContext, - _getSigners(FAULT_TOLERANCE + 1) - ); - changePrank(address(s_verifierProxy)); - s_verifier.verify(signedReport, msg.sender); - - (, , uint32 latestEpoch) = s_verifier.latestConfigDigestAndEpoch(FEED_ID); - assertEq(latestEpoch, 5); - } - function test_emitsAnEventIfReportVerified() public { bytes memory signedReport = _generateV1EncodedBlob( s_testReportOne, @@ -247,9 +233,12 @@ contract VerifierVerifyMultipleConfigDigestTest is VerifierVerifyTest { function setUp() public override { VerifierVerifyTest.setUp(); - (, , s_oldConfigDigest) = s_verifier.latestConfigDetails(FEED_ID); + s_oldConfigDigest = v1ConfigDigest; s_verifier.setConfig( FEED_ID, + SOURCE_CHAIN_ID, + SOURCE_ADDRESS, + 2, _getSignerAddresses(_getSigners(20)), s_offchaintransmitters, FAULT_TOLERANCE_TWO, @@ -258,11 +247,22 @@ contract VerifierVerifyMultipleConfigDigestTest is VerifierVerifyTest { bytes(""), new Common.AddressAndWeight[](0) ); - (, , s_newConfigDigest) = s_verifier.latestConfigDetails(FEED_ID); + s_newConfigDigest = _configDigestFromConfigData( + FEED_ID, + SOURCE_CHAIN_ID, + SOURCE_ADDRESS, + 2, + _getSignerAddresses(_getSigners(20)), + s_offchaintransmitters, + FAULT_TOLERANCE_TWO, + bytes(""), + VERIFIER_VERSION, + bytes("") + ); } function test_revertsIfVerifyingWithAnUnsetDigest() public { - s_verifier.deactivateConfig(FEED_ID, (s_oldConfigDigest)); + s_verifier.deactivateConfig(s_oldConfigDigest); bytes memory signedReport = _generateV1EncodedBlob( s_testReportOne, @@ -270,7 +270,7 @@ contract VerifierVerifyMultipleConfigDigestTest is VerifierVerifyTest { _getSigners(FAULT_TOLERANCE + 1) ); changePrank(address(s_verifierProxy)); - vm.expectRevert(abi.encodeWithSelector(Verifier.DigestInactive.selector, FEED_ID, s_reportContext[0])); + vm.expectRevert(abi.encodeWithSelector(Verifier.DigestInactive.selector, s_reportContext[0])); s_verifier.verify(signedReport, msg.sender); } From cb6125c5850befeb0604225b0aae447fe7f5fc6e Mon Sep 17 00:00:00 2001 From: Michael Fletcher Date: Tue, 19 Nov 2024 23:24:06 +0000 Subject: [PATCH 4/8] Remaining test + fixes --- .../src/v0.8/llo-feeds/v0.5.0/Verifier.sol | 35 +++--- .../test/fee-manager/BaseFeeManager.t.sol | 12 ++ .../FeeManager.getFeeAndReward.t.sol | 114 +++++++++++++++++ .../v0.5.0/test/mocks/MockConfigurator.sol | 76 +++++++++++ .../test/verifier/BaseVerifierTest.t.sol | 9 +- .../test/verifier/VerifierSetConfigTest.t.sol | 118 ++++++++++++++++++ 6 files changed, 349 insertions(+), 15 deletions(-) create mode 100644 contracts/src/v0.8/llo-feeds/v0.5.0/test/mocks/MockConfigurator.sol diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/Verifier.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/Verifier.sol index 55e1c542291..9309ffe44c6 100644 --- a/contracts/src/v0.8/llo-feeds/v0.5.0/Verifier.sol +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/Verifier.sol @@ -389,22 +389,29 @@ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface { uint64 offchainConfigVersion, bytes memory offchainConfig ) internal pure returns (bytes32) { + + bytes[] memory signersAsBytes = new bytes[](signers.length); + for (uint i; i < signers.length; ++i){ + signersAsBytes[i] = abi.encodePacked(signers[i]); + } + uint256 h = uint256( - keccak256( - abi.encode( - configId, - sourceChainId, - sourceAddress, - configCount, - signers, - offchainTransmitters, - f, - onchainConfig, - offchainConfigVersion, - offchainConfig + keccak256( + abi.encode( + configId, + sourceChainId, + sourceAddress, + configCount, + signersAsBytes, + offchainTransmitters, + f, + onchainConfig, + offchainConfigVersion, + offchainConfig + ) ) - ) - ); + ); + uint256 prefixMask = type(uint256).max << (256 - 16); // 0xFFFF00..00 // 0x0009 corresponds to ConfigDigestPrefixMercuryV02 in libocr uint256 prefix = 0x0009 << (256 - 16); // 0x000900..00 diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/fee-manager/BaseFeeManager.t.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/fee-manager/BaseFeeManager.t.sol index 0d598cdac52..764bf4f088f 100644 --- a/contracts/src/v0.8/llo-feeds/v0.5.0/test/fee-manager/BaseFeeManager.t.sol +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/fee-manager/BaseFeeManager.t.sol @@ -140,6 +140,18 @@ contract BaseFeeManagerTest is Test { changePrank(originalAddr); } + function setSubscriberGlobalDiscount(address subscriber, address token, uint256 discount, address sender) public { + //record the current address and switch to the recipient + address originalAddr = msg.sender; + changePrank(sender); + + //set the discount + feeManager.updateSubscriberGlobalDiscount(subscriber, token, uint64(discount)); + + //change back to the original address + changePrank(originalAddr); + } + function setNativeSurcharge(uint256 surcharge, address sender) public { //record the current address and switch to the recipient address originalAddr = msg.sender; diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/fee-manager/FeeManager.getFeeAndReward.t.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/fee-manager/FeeManager.getFeeAndReward.t.sol index 1b0f95d51bd..68b5f9c95a9 100644 --- a/contracts/src/v0.8/llo-feeds/v0.5.0/test/fee-manager/FeeManager.getFeeAndReward.t.sol +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/fee-manager/FeeManager.getFeeAndReward.t.sol @@ -603,4 +603,118 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest { //fee should be half the default assertEq(discount, FEE_SCALAR / 2); } + + function test_GlobalDiscountWithNative() public { + //set the global discount to 50% + setSubscriberGlobalDiscount(USER, address(native), FEE_SCALAR / 2, ADMIN); + + //get the discount applied + uint256 discount = getAppliedDiscount(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //fee should be half the default + assertEq(discount, FEE_SCALAR / 2); + } + + function test_GlobalDiscountWithLink() public { + //set the global discount to 50% + setSubscriberGlobalDiscount(USER, address(link), FEE_SCALAR / 2, ADMIN); + + //get the discount applied + uint256 discount = getAppliedDiscount(getV3Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER); + + //fee should be half the default + assertEq(discount, FEE_SCALAR / 2); + } + + function test_GlobalDiscountWithNativeAndLink() public { + //set the global discount to 50% + setSubscriberGlobalDiscount(USER, address(native), FEE_SCALAR / 2, ADMIN); + setSubscriberGlobalDiscount(USER, address(link), FEE_SCALAR / 2, ADMIN); + + //get the discount applied + uint256 discount = getAppliedDiscount(getV3Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER); + + //fee should be half the default + assertEq(discount, FEE_SCALAR / 2); + } + + function test_GlobalDiscountIsOverridenByIndividualDiscountNative() public { + //set the global discount to 50% + setSubscriberGlobalDiscount(USER, address(native), FEE_SCALAR / 2, ADMIN); + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), FEE_SCALAR / 4, ADMIN); + + //get the discount applied + uint256 discount = getAppliedDiscount(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //fee should be half the default + assertEq(discount, FEE_SCALAR / 4); + } + + function test_GlobalDiscountIsOverridenByIndividualDiscountLink() public { + //set the global discount to 50% + setSubscriberGlobalDiscount(USER, address(link), FEE_SCALAR / 2, ADMIN); + setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(link), FEE_SCALAR / 4, ADMIN); + + //get the discount applied + uint256 discount = getAppliedDiscount(getV3Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER); + + //fee should be half the default + assertEq(discount, FEE_SCALAR / 4); + } + + function test_GlobalDiscountIsUpdatedAfterBeingSetToZeroLink() public { + //set the global discount to 50% + setSubscriberGlobalDiscount(USER, address(link), FEE_SCALAR / 2, ADMIN); + + //get the discount applied + uint256 discount = getAppliedDiscount(getV3Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER); + + //fee should be half the default + assertEq(discount, FEE_SCALAR / 2); + + //set the global discount to zero + setSubscriberGlobalDiscount(USER, address(link), 0, ADMIN); + + //get the discount applied + discount = getAppliedDiscount(getV3Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER); + + //fee should be zero + assertEq(discount, 0); + } + + function test_GlobalDiscountIsUpdatedAfterBeingSetToZeroNative() public { + //set the global discount to 50% + setSubscriberGlobalDiscount(USER, address(native), FEE_SCALAR / 2, ADMIN); + + //get the discount applied + uint256 discount = getAppliedDiscount(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //fee should be half the default + assertEq(discount, FEE_SCALAR / 2); + + //set the global discount to zero + setSubscriberGlobalDiscount(USER, address(native), 0, ADMIN); + + //get the discount applied + discount = getAppliedDiscount(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER); + + //fee should be zero + assertEq(discount, 0); + } + + function test_GlobalDiscountCantBeSetToMoreThanMaximum() public { + //should revert with invalid discount + vm.expectRevert(INVALID_DISCOUNT_ERROR); + + //set the global discount to 101% + setSubscriberGlobalDiscount(USER, address(native), FEE_SCALAR + 1, ADMIN); + } + + function test_onlyOwnerCanSetGlobalDiscount() public { + //should revert with unauthorized + vm.expectRevert(ONLY_CALLABLE_BY_OWNER_ERROR); + + //set the global discount to 50% + setSubscriberGlobalDiscount(USER, address(native), FEE_SCALAR / 2, USER); + } } diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/mocks/MockConfigurator.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/mocks/MockConfigurator.sol new file mode 100644 index 00000000000..f9dab43140b --- /dev/null +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/mocks/MockConfigurator.sol @@ -0,0 +1,76 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.19; + +// Derived from v0.5/Configurator.sol +contract MockConfigurator { + struct ConfigurationState { + uint64 configCount; + uint32 latestConfigBlockNumber; + bytes32 configDigest; + } + + mapping(bytes32 => ConfigurationState) public s_configurationStates; + + function setStagingConfig( + bytes32 configId, + bytes[] memory signers, + bytes32[] memory offchainTransmitters, + uint8 f, + bytes memory onchainConfig, + uint64 offchainConfigVersion, + bytes memory offchainConfig + ) external { + ConfigurationState storage configurationState = s_configurationStates[configId]; + + uint64 newConfigCount = ++configurationState.configCount; + + bytes32 configDigest = _configDigestFromConfigData( + configId, + block.chainid, + address(this), + newConfigCount, + signers, + offchainTransmitters, + f, + onchainConfig, + offchainConfigVersion, + offchainConfig + ); + + s_configurationStates[configId].configDigest = configDigest; + configurationState.latestConfigBlockNumber = uint32(block.number); + } + + function _configDigestFromConfigData( + bytes32 configId, + uint256 sourceChainId, + address sourceAddress, + uint64 configCount, + bytes[] memory signers, + bytes32[] memory offchainTransmitters, + uint8 f, + bytes memory onchainConfig, + uint64 offchainConfigVersion, + bytes memory offchainConfig + ) internal pure returns (bytes32) { + uint256 h = uint256( + keccak256( + abi.encode( + configId, + sourceChainId, + sourceAddress, + configCount, + signers, + offchainTransmitters, + f, + onchainConfig, + offchainConfigVersion, + offchainConfig + ) + ) + ); + uint256 prefixMask = type(uint256).max << (256 - 16); + uint256 prefix = 0x0009 << (256 - 16); + return bytes32((prefix & prefixMask) | (h & ~prefixMask)); + } +} diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/BaseVerifierTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/BaseVerifierTest.t.sol index b1aa872be0f..541f0268016 100644 --- a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/BaseVerifierTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/BaseVerifierTest.t.sol @@ -191,6 +191,13 @@ contract BaseTest is Test { uint64 offchainConfigVersion, bytes memory offchainConfig ) internal pure returns (bytes32) { + + // Convert addresses to bytes array to match configurator + bytes[] memory signersAsBytes = new bytes[](signers.length); + for (uint i; i < signers.length; ++i){ + signersAsBytes[i] = abi.encodePacked(signers[i]); + } + uint256 h = uint256( keccak256( abi.encode( @@ -198,7 +205,7 @@ contract BaseTest is Test { chainId, verifierAddr, configCount, - signers, + signersAsBytes, offchainTransmitters, f, onchainConfig, diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierSetConfigTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierSetConfigTest.t.sol index 02784226863..ba7cc6276c2 100644 --- a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierSetConfigTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierSetConfigTest.t.sol @@ -4,6 +4,7 @@ pragma solidity 0.8.19; import {BaseTest, BaseTestWithMultipleConfiguredDigests} from "./BaseVerifierTest.t.sol"; import {Verifier} from "../../Verifier.sol"; import {Common} from "../../../libraries/Common.sol"; +import {MockConfigurator} from "../mocks/MockConfigurator.sol"; contract VerifierSetConfigTest is BaseTest { function setUp() public virtual override { @@ -316,4 +317,121 @@ contract VerifierSetConfigWhenThereAreMultipleDigestsTest is BaseTestWithMultipl assertEq(blockNumber, block.number); assertEq(configDigest, expectedConfigDigest); } + + function test_revertsIfDuplicateConfigIsSet() public { + // Set initial config + s_verifier.setConfig( + FEED_ID, + SOURCE_CHAIN_ID, + SOURCE_ADDRESS, + 1, + _getSignerAddresses(_getSigners(15)), + s_offchaintransmitters, + 4, + bytes(""), + VERIFIER_VERSION, + bytes(""), + new Common.AddressAndWeight[](0) + ); + + // Try to set same config again + vm.expectRevert(abi.encodeWithSelector(Verifier.NonUniqueSignatures.selector)); + s_verifier.setConfig( + FEED_ID, + SOURCE_CHAIN_ID, + SOURCE_ADDRESS, + 1, + _getSignerAddresses(_getSigners(15)), + s_offchaintransmitters, + 4, + bytes(""), + VERIFIER_VERSION, + bytes(""), + new Common.AddressAndWeight[](0) + ); + } + + function test_incrementalConfigUpdates() public { + // Set initial config + s_verifier.setConfig( + FEED_ID, + SOURCE_CHAIN_ID, + SOURCE_ADDRESS, + 1, + _getSignerAddresses(_getSigners(15)), + s_offchaintransmitters, + 4, + bytes(""), + VERIFIER_VERSION, + bytes(""), + new Common.AddressAndWeight[](0) + ); + + // Try to set same config again + s_verifier.setConfig( + FEED_ID, + SOURCE_CHAIN_ID, + SOURCE_ADDRESS, + 2, + _getSignerAddresses(_getSigners(15)), + s_offchaintransmitters, + 4, + bytes(""), + VERIFIER_VERSION, + bytes(""), + new Common.AddressAndWeight[](0) + ); + + s_verifier.setConfig( + FEED_ID, + SOURCE_CHAIN_ID, + SOURCE_ADDRESS, + 3, + _getSignerAddresses(_getSigners(15)), + s_offchaintransmitters, + 4, + bytes(""), + VERIFIER_VERSION, + bytes(""), + new Common.AddressAndWeight[](0) + ); + } + + function test_configDigestMatchesConfiguratorDigest() public { + MockConfigurator configurator = new MockConfigurator(); + + // Convert addresses to bytes array + Signer[] memory signers = _getSigners(15); + bytes[] memory signersAsBytes = new bytes[](signers.length); + for (uint i; i < signers.length; ++i){ + signersAsBytes[i] = abi.encodePacked(signers[i].signerAddress); + } + + configurator.setStagingConfig( + FEED_ID, + signersAsBytes, + s_offchaintransmitters, + 4, + bytes(""), + VERIFIER_VERSION, + bytes("") + ); + + bytes32 expectedConfigDigest = _configDigestFromConfigData( + FEED_ID, + block.chainid, + address(configurator), + 1, + _getSignerAddresses(signers), + s_offchaintransmitters, + 4, + bytes(""), + VERIFIER_VERSION, + bytes("") + ); + + (,,bytes32 configDigest) = configurator.s_configurationStates(FEED_ID); + + assertEq(configDigest, expectedConfigDigest); + } } From 31ac6fa3051c5c1abae81683df0dab4fe6bc640b Mon Sep 17 00:00:00 2001 From: Michael Fletcher Date: Wed, 20 Nov 2024 12:13:45 +0000 Subject: [PATCH 5/8] Restore interface --- .../src/v0.8/llo-feeds/v0.5.0/Verifier.sol | 2 +- .../llo-feeds/v0.5.0/interfaces/IVerifier.sol | 2 +- .../v0.5.0/test/gas/Gas_VerifierTest.t.sol | 2 +- .../v0.5.0/test/mocks/ErroredVerifier.sol | 2 +- .../test/verifier/BaseVerifierTest.t.sol | 12 +++---- .../test/verifier/VerifierSetConfigTest.t.sol | 32 +++++++++---------- .../test/verifier/VerifierVerifyTest.t.sol | 2 +- 7 files changed, 27 insertions(+), 27 deletions(-) diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/Verifier.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/Verifier.sol index 9309ffe44c6..a3ca4019643 100644 --- a/contracts/src/v0.8/llo-feeds/v0.5.0/Verifier.sol +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/Verifier.sol @@ -255,7 +255,7 @@ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface { } /// @inheritdoc IVerifier - function setConfig( + function setConfigFromSource( bytes32 configId, uint256 sourceChainId, address sourceAddress, diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/interfaces/IVerifier.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/interfaces/IVerifier.sol index 152101362ea..f57f4b9bc93 100644 --- a/contracts/src/v0.8/llo-feeds/v0.5.0/interfaces/IVerifier.sol +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/interfaces/IVerifier.sol @@ -32,7 +32,7 @@ interface IVerifier is IERC165 { * @param offchainConfig serialized configuration used by the oracles exclusively and only passed through the contract * @param recipientAddressesAndWeights the addresses and weights of all the recipients to receive rewards */ - function setConfig( + function setConfigFromSource( bytes32 configId, uint256 sourceChainId, address sourceAddress, diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/gas/Gas_VerifierTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/gas/Gas_VerifierTest.t.sol index a9bd067696a..00e65618968 100644 --- a/contracts/src/v0.8/llo-feeds/v0.5.0/test/gas/Gas_VerifierTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/gas/Gas_VerifierTest.t.sol @@ -17,7 +17,7 @@ contract Verifier_setConfig is BaseTest { } function testSetConfigSuccess_gas() public { - s_verifier.setConfig( + s_verifier.setConfigFromSource( FEED_ID, SOURCE_CHAIN_ID, SOURCE_ADDRESS, diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/mocks/ErroredVerifier.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/mocks/ErroredVerifier.sol index da0ad973cb1..67b9e0cefd8 100644 --- a/contracts/src/v0.8/llo-feeds/v0.5.0/test/mocks/ErroredVerifier.sol +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/mocks/ErroredVerifier.sol @@ -41,7 +41,7 @@ contract ErroredVerifier is IVerifier { } - function setConfig( + function setConfigFromSource( bytes32, uint256, address, diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/BaseVerifierTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/BaseVerifierTest.t.sol index 541f0268016..9b24563fa66 100644 --- a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/BaseVerifierTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/BaseVerifierTest.t.sol @@ -296,7 +296,7 @@ contract BaseTestWithConfiguredVerifierAndFeeManager is BaseTest { Signer[] memory signers = _getSigners(MAX_ORACLES); s_verifierProxy.initializeVerifier(address(s_verifier)); - s_verifier.setConfig( + s_verifier.setConfigFromSource( FEED_ID, SOURCE_CHAIN_ID, SOURCE_ADDRESS, @@ -323,7 +323,7 @@ contract BaseTestWithConfiguredVerifierAndFeeManager is BaseTest { bytes("") ); - s_verifier.setConfig( + s_verifier.setConfigFromSource( FEED_ID_V3, SOURCE_CHAIN_ID, SOURCE_ADDRESS, @@ -486,7 +486,7 @@ contract BaseTestWithMultipleConfiguredDigests is BaseTestWithConfiguredVerifier // Verifier 1, Feed 1, Config 2 Signer[] memory secondSetOfSigners = _getSigners(8); - s_verifier.setConfig( + s_verifier.setConfigFromSource( FEED_ID, SOURCE_CHAIN_ID, SOURCE_ADDRESS, @@ -515,7 +515,7 @@ contract BaseTestWithMultipleConfiguredDigests is BaseTestWithConfiguredVerifier // Verifier 1, Feed 1, Config 3 Signer[] memory thirdSetOfSigners = _getSigners(5); - s_verifier.setConfig( + s_verifier.setConfigFromSource( FEED_ID, SOURCE_CHAIN_ID, SOURCE_ADDRESS, @@ -542,7 +542,7 @@ contract BaseTestWithMultipleConfiguredDigests is BaseTestWithConfiguredVerifier ); // Verifier 1, Feed 2, Config 1 - s_verifier.setConfig( + s_verifier.setConfigFromSource( FEED_ID_2, SOURCE_CHAIN_ID, SOURCE_ADDRESS, @@ -570,7 +570,7 @@ contract BaseTestWithMultipleConfiguredDigests is BaseTestWithConfiguredVerifier // Verifier 2, Feed 3, Config 1 s_verifierProxy.initializeVerifier(address(s_verifier_2)); - s_verifier_2.setConfig( + s_verifier_2.setConfigFromSource( FEED_ID_3, SOURCE_CHAIN_ID, SOURCE_ADDRESS, diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierSetConfigTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierSetConfigTest.t.sol index ba7cc6276c2..ec88410d3ac 100644 --- a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierSetConfigTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierSetConfigTest.t.sol @@ -16,7 +16,7 @@ contract VerifierSetConfigTest is BaseTest { Signer[] memory signers = _getSigners(MAX_ORACLES); changePrank(USER); - s_verifier.setConfig( + s_verifier.setConfigFromSource( FEED_ID, SOURCE_CHAIN_ID, SOURCE_ADDRESS, @@ -34,7 +34,7 @@ contract VerifierSetConfigTest is BaseTest { function test_revertsIfSetWithTooManySigners() public { address[] memory signers = new address[](MAX_ORACLES + 1); vm.expectRevert(abi.encodeWithSelector(Verifier.ExcessSigners.selector, signers.length, MAX_ORACLES)); - s_verifier.setConfig( + s_verifier.setConfigFromSource( FEED_ID, SOURCE_CHAIN_ID, SOURCE_ADDRESS, @@ -52,7 +52,7 @@ contract VerifierSetConfigTest is BaseTest { function test_revertsIfFaultToleranceIsZero() public { vm.expectRevert(abi.encodeWithSelector(Verifier.FaultToleranceMustBePositive.selector)); Signer[] memory signers = _getSigners(MAX_ORACLES); - s_verifier.setConfig( + s_verifier.setConfigFromSource( FEED_ID, SOURCE_CHAIN_ID, SOURCE_ADDRESS, @@ -75,7 +75,7 @@ contract VerifierSetConfigTest is BaseTest { vm.expectRevert( abi.encodeWithSelector(Verifier.InsufficientSigners.selector, signers.length, FAULT_TOLERANCE * 3 + 1) ); - s_verifier.setConfig( + s_verifier.setConfigFromSource( FEED_ID, SOURCE_CHAIN_ID, SOURCE_ADDRESS, @@ -95,7 +95,7 @@ contract VerifierSetConfigTest is BaseTest { address[] memory signerAddrs = _getSignerAddresses(signers); signerAddrs[0] = signerAddrs[1]; vm.expectRevert(abi.encodeWithSelector(Verifier.NonUniqueSignatures.selector)); - s_verifier.setConfig( + s_verifier.setConfigFromSource( FEED_ID, SOURCE_CHAIN_ID, SOURCE_ADDRESS, @@ -115,7 +115,7 @@ contract VerifierSetConfigTest is BaseTest { address[] memory signerAddrs = _getSignerAddresses(signers); signerAddrs[0] = address(0); vm.expectRevert(abi.encodeWithSelector(Verifier.ZeroAddress.selector)); - s_verifier.setConfig( + s_verifier.setConfigFromSource( FEED_ID, SOURCE_CHAIN_ID, SOURCE_ADDRESS, @@ -134,7 +134,7 @@ contract VerifierSetConfigTest is BaseTest { Signer[] memory signers = _getSigners(MAX_ORACLES); s_verifierProxy.initializeVerifier(address(s_verifier)); - s_verifier.setConfig( + s_verifier.setConfigFromSource( FEED_ID, SOURCE_CHAIN_ID, SOURCE_ADDRESS, @@ -171,7 +171,7 @@ contract VerifierSetConfigWhenThereAreMultipleDigestsTest is BaseTestWithMultipl function test_correctlyUpdatesTheDigestInTheProxy() public { Signer[] memory newSigners = _getSigners(15); - s_verifier.setConfig( + s_verifier.setConfigFromSource( FEED_ID, SOURCE_CHAIN_ID, SOURCE_ADDRESS, @@ -205,7 +205,7 @@ contract VerifierSetConfigWhenThereAreMultipleDigestsTest is BaseTestWithMultipl function test_correctlyUpdatesDigestsOnMultipleVerifiersInTheProxy() public { Signer[] memory newSigners = _getSigners(15); - s_verifier.setConfig( + s_verifier.setConfigFromSource( FEED_ID_2, SOURCE_CHAIN_ID, SOURCE_ADDRESS, @@ -235,7 +235,7 @@ contract VerifierSetConfigWhenThereAreMultipleDigestsTest is BaseTestWithMultipl address verifierAddr = s_verifierProxy.getVerifier(configDigest); assertEq(verifierAddr, address(s_verifier)); - s_verifier_2.setConfig( + s_verifier_2.setConfigFromSource( FEED_ID_3, SOURCE_CHAIN_ID, SOURCE_ADDRESS, @@ -271,7 +271,7 @@ contract VerifierSetConfigWhenThereAreMultipleDigestsTest is BaseTestWithMultipl Signer[] memory newSigners = _getSigners(15); - s_verifier.setConfig( + s_verifier.setConfigFromSource( FEED_ID, SOURCE_CHAIN_ID, SOURCE_ADDRESS, @@ -320,7 +320,7 @@ contract VerifierSetConfigWhenThereAreMultipleDigestsTest is BaseTestWithMultipl function test_revertsIfDuplicateConfigIsSet() public { // Set initial config - s_verifier.setConfig( + s_verifier.setConfigFromSource( FEED_ID, SOURCE_CHAIN_ID, SOURCE_ADDRESS, @@ -336,7 +336,7 @@ contract VerifierSetConfigWhenThereAreMultipleDigestsTest is BaseTestWithMultipl // Try to set same config again vm.expectRevert(abi.encodeWithSelector(Verifier.NonUniqueSignatures.selector)); - s_verifier.setConfig( + s_verifier.setConfigFromSource( FEED_ID, SOURCE_CHAIN_ID, SOURCE_ADDRESS, @@ -353,7 +353,7 @@ contract VerifierSetConfigWhenThereAreMultipleDigestsTest is BaseTestWithMultipl function test_incrementalConfigUpdates() public { // Set initial config - s_verifier.setConfig( + s_verifier.setConfigFromSource( FEED_ID, SOURCE_CHAIN_ID, SOURCE_ADDRESS, @@ -368,7 +368,7 @@ contract VerifierSetConfigWhenThereAreMultipleDigestsTest is BaseTestWithMultipl ); // Try to set same config again - s_verifier.setConfig( + s_verifier.setConfigFromSource( FEED_ID, SOURCE_CHAIN_ID, SOURCE_ADDRESS, @@ -382,7 +382,7 @@ contract VerifierSetConfigWhenThereAreMultipleDigestsTest is BaseTestWithMultipl new Common.AddressAndWeight[](0) ); - s_verifier.setConfig( + s_verifier.setConfigFromSource( FEED_ID, SOURCE_CHAIN_ID, SOURCE_ADDRESS, diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierVerifyTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierVerifyTest.t.sol index 151314df22a..96306ede6ae 100644 --- a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierVerifyTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierVerifyTest.t.sol @@ -234,7 +234,7 @@ contract VerifierVerifyMultipleConfigDigestTest is VerifierVerifyTest { function setUp() public override { VerifierVerifyTest.setUp(); s_oldConfigDigest = v1ConfigDigest; - s_verifier.setConfig( + s_verifier.setConfigFromSource( FEED_ID, SOURCE_CHAIN_ID, SOURCE_ADDRESS, From 1b1824378416d68da2dbf798a4a57809f98b9ed5 Mon Sep 17 00:00:00 2001 From: Michael Fletcher Date: Wed, 20 Nov 2024 17:20:10 +0000 Subject: [PATCH 6/8] Fix setConfig migration --- .../src/v0.8/llo-feeds/v0.5.0/Verifier.sol | 221 ++++------ .../llo-feeds/v0.5.0/interfaces/IVerifier.sol | 41 +- .../v0.5.0/test/gas/Gas_VerifierTest.t.sol | 10 +- .../v0.5.0/test/mocks/ErroredVerifier.sol | 19 +- .../test/verifier/BaseVerifierTest.t.sol | 104 ++--- .../test/verifier/VerifierSetConfigTest.t.sol | 377 ++++++++++++------ .../v0.5.0/test/verifier/VerifierTest.t.sol | 3 +- .../test/verifier/VerifierVerifyTest.t.sol | 87 +++- 8 files changed, 473 insertions(+), 389 deletions(-) diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/Verifier.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/Verifier.sol index a3ca4019643..371aa3e9d30 100644 --- a/contracts/src/v0.8/llo-feeds/v0.5.0/Verifier.sol +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/Verifier.sol @@ -37,24 +37,15 @@ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface { Role role; } - struct Config { - // Fault tolerance - uint8 f; - // Marks whether or not a configuration is active - bool isActive; - // Map of signer addresses to oracles - mapping(address => Signer) oracles; - } - struct VerifierState { - // The number of configs for this DON - uint32 configCount; // The block number of the block the last time the configuration was updated. uint32 latestConfigBlockNumber; // Whether the config is deactivated bool isActive; // Fault tolerance uint8 f; + // Number of signers + uint8 oracleCount; // Map of signer addresses to oracles mapping(address => Signer) oracles; } @@ -65,16 +56,16 @@ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface { /// @notice This event is emitted whenever a new DON configuration is set. event ConfigSet( - bytes32 indexed configId, - uint32 previousConfigBlockNumber, - bytes32 configDigest, - uint64 configCount, + bytes32 indexed configDigest, address[] signers, - bytes32[] offchainTransmitters, - uint8 f, - bytes onchainConfig, - uint64 offchainConfigVersion, - bytes offchainConfig + uint8 f + ); + + /// @notice This event is + event ConfigUpdated( + bytes32 indexed configDigest, + address[] prevSigners, + address[] newSigners ); /// @notice This event is emitted whenever a configuration is deactivated @@ -139,6 +130,9 @@ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface { /// @notice This error is thrown whenever a report fails to verify due to bad or duplicate signatures error BadVerification(); + /// @notice This error is thrown whenever a config digest is already set when setting the configuration + error ConfigDigestAlreadySet(); + /// @notice The address of the verifier proxy address private immutable i_verifierProxyAddr; @@ -255,78 +249,64 @@ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface { } /// @inheritdoc IVerifier - function setConfigFromSource( - bytes32 configId, - uint256 sourceChainId, - address sourceAddress, - uint32 configCount, - address[] memory signers, - bytes32[] memory offchainTransmitters, + function updateConfig( + bytes32 configDigest, + address[] calldata prevSigners, + address[] calldata newSigners, + uint8 f + ) external override checkConfigValid(newSigners.length, f) onlyOwner { + VerifierState storage config = s_verifierStates[configDigest]; + + if (config.f == 0) revert DigestNotSet(configDigest); + + // We must be removing the number of signers that were originally set + if(config.oracleCount != prevSigners.length){ + revert NonUniqueSignatures(); + } + + for (uint256 i; i < prevSigners.length; ++i) { + // Check the signers being removed are not zero address or duplicates + if(config.oracles[prevSigners[i]].role == Role.Unset){ + revert NonUniqueSignatures(); + } + + delete config.oracles[prevSigners[i]]; + } + + // Once signers have been cleared we can set the new signers + _setConfig(configDigest, newSigners, f, new Common.AddressAndWeight[](0), true); + + + emit ConfigUpdated(configDigest, prevSigners, newSigners); + } + + /// @inheritdoc IVerifier + function setConfig( + bytes32 configDigest, + address[] calldata signers, uint8 f, - bytes memory onchainConfig, - uint64 offchainConfigVersion, - bytes memory offchainConfig, Common.AddressAndWeight[] memory recipientAddressesAndWeights ) external override checkConfigValid(signers.length, f) onlyOwner { - _setConfig( - configId, - sourceChainId, - sourceAddress, - configCount, - signers, - offchainTransmitters, - f, - onchainConfig, - offchainConfigVersion, - offchainConfig, - recipientAddressesAndWeights - ); + _setConfig(configDigest, signers, f, recipientAddressesAndWeights, false); } - /// @notice Sets config based on the given arguments - /// @param configId Config ID to set config for - /// @param sourceChainId Chain ID of source config - /// @param sourceAddress Address of source config Verifier - /// @param configCount The number of times a new configuration has been set - /// @param signers addresses with which oracles sign the reports - /// @param offchainTransmitters CSA key for the ith Oracle - /// @param f number of faulty oracles the system can tolerate - /// @param onchainConfig serialized configuration used by the contract (and possibly oracles) - /// @param offchainConfigVersion version number for offchainEncoding schema - /// @param offchainConfig serialized configuration used by the oracles exclusively and only passed through the contract - /// @param recipientAddressesAndWeights the addresses and weights of all the recipients to receive rewards function _setConfig( - bytes32 configId, - uint256 sourceChainId, - address sourceAddress, - uint32 configCount, - address[] memory signers, - bytes32[] memory offchainTransmitters, + bytes32 configDigest, + address[] calldata signers, uint8 f, - bytes memory onchainConfig, - uint64 offchainConfigVersion, - bytes memory offchainConfig, - Common.AddressAndWeight[] memory recipientAddressesAndWeights + Common.AddressAndWeight[] memory recipientAddressesAndWeights, + bool updateConfig ) internal { - bytes32 configDigest = _configDigestFromConfigData( - configId, - sourceChainId, - sourceAddress, - configCount, - signers, - offchainTransmitters, - f, - onchainConfig, - offchainConfigVersion, - offchainConfig - ); - VerifierState storage verifierState = s_verifierStates[configDigest]; + if(verifierState.f > 0 && !updateConfig) { + revert ConfigDigestAlreadySet(); + } + verifierState.latestConfigBlockNumber = uint32(block.number); - verifierState.configCount = configCount; verifierState.f = f; verifierState.isActive = true; + verifierState.oracleCount = uint8(signers.length); for (uint8 i; i < signers.length; ++i) { address signerAddr = signers[i]; @@ -345,77 +325,19 @@ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface { }); } - IVerifierProxy(i_verifierProxyAddr).setVerifier( - bytes32(0), - configDigest, - recipientAddressesAndWeights - ); - - emit ConfigSet( - configId, - 0, - configDigest, - configCount, - signers, - offchainTransmitters, - f, - onchainConfig, - offchainConfigVersion, - offchainConfig - ); - } - - /// @notice Generates the config digest from config data - /// @param configId to set config for - /// @param sourceChainId Chain ID of source config - /// @param sourceAddress Address of source config Verifier - /// @param configCount ordinal number of this config setting among all config settings over the life of this contract - /// @param signers ith element is address ith oracle uses to sign a report - /// @param offchainTransmitters ith element is address ith oracle used to transmit reports (in this case used for flexible additional field, such as CSA pub keys) - /// @param f maximum number of faulty/dishonest oracles the protocol can tolerate while still working correctly - /// @param onchainConfig serialized configuration used by the contract (and possibly oracles) - /// @param offchainConfigVersion version of the serialization format used for "offchainConfig" parameter - /// @param offchainConfig serialized configuration used by the oracles exclusively and only passed through the contract - /// @dev This function is a modified version of the method from OCR2Abstract - function _configDigestFromConfigData( - bytes32 configId, - uint256 sourceChainId, - address sourceAddress, - uint64 configCount, - address[] memory signers, - bytes32[] memory offchainTransmitters, - uint8 f, - bytes memory onchainConfig, - uint64 offchainConfigVersion, - bytes memory offchainConfig - ) internal pure returns (bytes32) { - - bytes[] memory signersAsBytes = new bytes[](signers.length); - for (uint i; i < signers.length; ++i){ - signersAsBytes[i] = abi.encodePacked(signers[i]); - } - - uint256 h = uint256( - keccak256( - abi.encode( - configId, - sourceChainId, - sourceAddress, - configCount, - signersAsBytes, - offchainTransmitters, - f, - onchainConfig, - offchainConfigVersion, - offchainConfig - ) - ) + if(!updateConfig) { + IVerifierProxy(i_verifierProxyAddr).setVerifier( + bytes32(0), + configDigest, + recipientAddressesAndWeights ); - uint256 prefixMask = type(uint256).max << (256 - 16); // 0xFFFF00..00 - // 0x0009 corresponds to ConfigDigestPrefixMercuryV02 in libocr - uint256 prefix = 0x0009 << (256 - 16); // 0x000900..00 - return bytes32((prefix & prefixMask) | (h & ~prefixMask)); + emit ConfigSet( + configDigest, + signers, + f + ); + } } /// @inheritdoc IVerifier @@ -441,10 +363,9 @@ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface { /// @inheritdoc IVerifier function latestConfigDetails( bytes32 configDigest - ) external view override returns (uint32 configCount, uint32 blockNumber) { + ) external view override returns (uint32 blockNumber) { VerifierState storage verifierState = s_verifierStates[configDigest]; return ( - verifierState.configCount, verifierState.latestConfigBlockNumber ); } diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/interfaces/IVerifier.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/interfaces/IVerifier.sol index f57f4b9bc93..304ef31b94f 100644 --- a/contracts/src/v0.8/llo-feeds/v0.5.0/interfaces/IVerifier.sol +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/interfaces/IVerifier.sol @@ -19,33 +19,33 @@ interface IVerifier is IERC165 { function verify(bytes calldata signedReport, address sender) external returns (bytes memory verifierResponse); /** - * @notice identical to `setConfig` except with args for sourceChainId and sourceAddress - * @param configId Config ID to set config for - * @param sourceChainId Chain ID of source config - * @param sourceAddress Address of source config Verifier - * @param configCount The config count for the configuration + * @notice sets a configuration and its associated keys and f + * @param configDigest The digest of the configuration we're setting * @param signers addresses with which oracles sign the reports - * @param offchainTransmitters CSA key for the ith Oracle * @param f number of faulty oracles the system can tolerate - * @param onchainConfig serialized configuration used by the contract (and possibly oracles) - * @param offchainConfigVersion version number for offchainEncoding schema - * @param offchainConfig serialized configuration used by the oracles exclusively and only passed through the contract * @param recipientAddressesAndWeights the addresses and weights of all the recipients to receive rewards */ - function setConfigFromSource( - bytes32 configId, - uint256 sourceChainId, - address sourceAddress, - uint32 configCount, - address[] memory signers, - bytes32[] memory offchainTransmitters, + function setConfig( + bytes32 configDigest, + address[] calldata signers, uint8 f, - bytes memory onchainConfig, - uint64 offchainConfigVersion, - bytes memory offchainConfig, Common.AddressAndWeight[] memory recipientAddressesAndWeights ) external; + /** + * @notice updates a configuration that has been set + * @param configDigest The digest of the configuration we're updating + * @param prevSigners the existing signers that need to be removed + * @param newSigners the signers to be added + * @param f the newnumber of faulty oracles the system can tolerate + */ + function updateConfig( + bytes32 configDigest, + address[] calldata prevSigners, + address[] calldata newSigners, + uint8 f + ) external; + /** * @notice Activates the configuration for a config digest * @param configDigest The config digest to activate @@ -63,10 +63,9 @@ interface IVerifier is IERC165 { /** * @notice information about current offchain reporting protocol configuration * @param configDigest Config Digest to fetch data for - * @return configCount ordinal number of current config, out of all configs applied to this contract so far * @return blockNumber block at which this config was set */ function latestConfigDetails( bytes32 configDigest - ) external view returns (uint32 configCount, uint32 blockNumber); + ) external view returns (uint32 blockNumber); } diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/gas/Gas_VerifierTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/gas/Gas_VerifierTest.t.sol index 00e65618968..bbbda4f619f 100644 --- a/contracts/src/v0.8/llo-feeds/v0.5.0/test/gas/Gas_VerifierTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/gas/Gas_VerifierTest.t.sol @@ -17,7 +17,7 @@ contract Verifier_setConfig is BaseTest { } function testSetConfigSuccess_gas() public { - s_verifier.setConfigFromSource( + bytes32 configDigest = _configDigestFromConfigData( FEED_ID, SOURCE_CHAIN_ID, SOURCE_ADDRESS, @@ -27,7 +27,13 @@ contract Verifier_setConfig is BaseTest { FAULT_TOLERANCE, bytes(""), 1, - bytes(""), + bytes("") + ); + + s_verifier.setConfig( + configDigest, + s_signerAddrs, + FAULT_TOLERANCE, new Common.AddressAndWeight[](0) ); } diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/mocks/ErroredVerifier.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/mocks/ErroredVerifier.sol index 67b9e0cefd8..c92bcb1ac27 100644 --- a/contracts/src/v0.8/llo-feeds/v0.5.0/test/mocks/ErroredVerifier.sol +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/mocks/ErroredVerifier.sol @@ -13,6 +13,7 @@ contract ErroredVerifier is IVerifier { error FailedToVerify(); error FailedToSetConfig(); + error FailedToUnsetConfig(); error FailedToActivateConfig(); error FailedToDeactivateConfig(); error FailedToActivateFeed(); @@ -40,19 +41,15 @@ contract ErroredVerifier is IVerifier { revert FailedToVerify(); } + function updateConfig(bytes32, address[] calldata, address[] calldata, uint8) external pure { + revert FailedToUnsetConfig(); + } - function setConfigFromSource( + function setConfig( bytes32, - uint256, - address, - uint32, - address[] memory, - bytes32[] memory, + address[] calldata, uint8, - bytes memory, - uint64, - bytes memory, - Common.AddressAndWeight[] memory + Common.AddressAndWeight[] calldata ) external pure override { revert FailedToSetConfig(); } @@ -65,7 +62,7 @@ contract ErroredVerifier is IVerifier { revert FailedToDeactivateConfig(); } - function latestConfigDetails(bytes32) external pure override returns (uint32, uint32) { + function latestConfigDetails(bytes32) external pure override returns (uint32) { revert FailedToGetLatestConfigDetails(); } } diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/BaseVerifierTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/BaseVerifierTest.t.sol index 9b24563fa66..db220f6547f 100644 --- a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/BaseVerifierTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/BaseVerifierTest.t.sol @@ -296,20 +296,7 @@ contract BaseTestWithConfiguredVerifierAndFeeManager is BaseTest { Signer[] memory signers = _getSigners(MAX_ORACLES); s_verifierProxy.initializeVerifier(address(s_verifier)); - s_verifier.setConfigFromSource( - FEED_ID, - SOURCE_CHAIN_ID, - SOURCE_ADDRESS, - 1, - _getSignerAddresses(signers), - s_offchaintransmitters, - FAULT_TOLERANCE, - bytes(""), - VERIFIER_VERSION, - bytes(""), - new Common.AddressAndWeight[](0) - ); - + v1ConfigDigest = _configDigestFromConfigData( FEED_ID, SOURCE_CHAIN_ID, @@ -323,20 +310,13 @@ contract BaseTestWithConfiguredVerifierAndFeeManager is BaseTest { bytes("") ); - s_verifier.setConfigFromSource( - FEED_ID_V3, - SOURCE_CHAIN_ID, - SOURCE_ADDRESS, - 1, + s_verifier.setConfig( + v1ConfigDigest, _getSignerAddresses(signers), - s_offchaintransmitters, FAULT_TOLERANCE, - bytes(""), - VERIFIER_VERSION, - bytes(""), new Common.AddressAndWeight[](0) ); - + v3ConfigDigest = _configDigestFromConfigData( FEED_ID_V3, SOURCE_CHAIN_ID, @@ -350,6 +330,13 @@ contract BaseTestWithConfiguredVerifierAndFeeManager is BaseTest { bytes("") ); + s_verifier.setConfig( + v3ConfigDigest, + _getSignerAddresses(signers), + FAULT_TOLERANCE, + new Common.AddressAndWeight[](0) + ); + link = new ERC20Mock("LINK", "LINK", ADMIN, 0); native = new WERC20Mock(); @@ -486,7 +473,7 @@ contract BaseTestWithMultipleConfiguredDigests is BaseTestWithConfiguredVerifier // Verifier 1, Feed 1, Config 2 Signer[] memory secondSetOfSigners = _getSigners(8); - s_verifier.setConfigFromSource( + s_configDigestTwo = _configDigestFromConfigData( FEED_ID, SOURCE_CHAIN_ID, SOURCE_ADDRESS, @@ -496,26 +483,18 @@ contract BaseTestWithMultipleConfiguredDigests is BaseTestWithConfiguredVerifier FAULT_TOLERANCE_TWO, bytes(""), 2, - bytes(""), - new Common.AddressAndWeight[](0) + bytes("") ); - - s_configDigestTwo = _configDigestFromConfigData( - FEED_ID, - SOURCE_CHAIN_ID, - SOURCE_ADDRESS, - 2, + s_verifier.setConfig( + s_configDigestTwo, _getSignerAddresses(secondSetOfSigners), - s_offchaintransmitters, FAULT_TOLERANCE_TWO, - bytes(""), - 2, - bytes("") + new Common.AddressAndWeight[](0) ); // Verifier 1, Feed 1, Config 3 Signer[] memory thirdSetOfSigners = _getSigners(5); - s_verifier.setConfigFromSource( + s_configDigestThree = _configDigestFromConfigData( FEED_ID, SOURCE_CHAIN_ID, SOURCE_ADDRESS, @@ -525,24 +504,17 @@ contract BaseTestWithMultipleConfiguredDigests is BaseTestWithConfiguredVerifier FAULT_TOLERANCE_THREE, bytes(""), 3, - bytes(""), - new Common.AddressAndWeight[](0) + bytes("") ); - s_configDigestThree = _configDigestFromConfigData( - FEED_ID, - SOURCE_CHAIN_ID, - SOURCE_ADDRESS, - 3, + s_verifier.setConfig( + s_configDigestThree, _getSignerAddresses(thirdSetOfSigners), - s_offchaintransmitters, FAULT_TOLERANCE_THREE, - bytes(""), - 3, - bytes("") + new Common.AddressAndWeight[](0) ); // Verifier 1, Feed 2, Config 1 - s_verifier.setConfigFromSource( + s_configDigestFour = _configDigestFromConfigData( FEED_ID_2, SOURCE_CHAIN_ID, SOURCE_ADDRESS, @@ -552,25 +524,18 @@ contract BaseTestWithMultipleConfiguredDigests is BaseTestWithConfiguredVerifier FAULT_TOLERANCE, bytes(""), 4, - bytes(""), - new Common.AddressAndWeight[](0) + bytes("") ); - s_configDigestFour = _configDigestFromConfigData( - FEED_ID_2, - SOURCE_CHAIN_ID, - SOURCE_ADDRESS, - 1, + s_verifier.setConfig( + s_configDigestFour, _getSignerAddresses(signers), - s_offchaintransmitters, FAULT_TOLERANCE, - bytes(""), - 4, - bytes("") + new Common.AddressAndWeight[](0) ); // Verifier 2, Feed 3, Config 1 s_verifierProxy.initializeVerifier(address(s_verifier_2)); - s_verifier_2.setConfigFromSource( + s_configDigestFive = _configDigestFromConfigData( FEED_ID_3, SOURCE_CHAIN_ID, SOURCE_ADDRESS, @@ -580,20 +545,13 @@ contract BaseTestWithMultipleConfiguredDigests is BaseTestWithConfiguredVerifier FAULT_TOLERANCE, bytes(""), 5, - bytes(""), - new Common.AddressAndWeight[](0) + bytes("") ); - s_configDigestFive = _configDigestFromConfigData( - FEED_ID_3, - SOURCE_CHAIN_ID, - SOURCE_ADDRESS, - 1, + s_verifier_2.setConfig( + s_configDigestFive, _getSignerAddresses(signers), - s_offchaintransmitters, FAULT_TOLERANCE, - bytes(""), - 5, - bytes("") + new Common.AddressAndWeight[](0) ); } } diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierSetConfigTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierSetConfigTest.t.sol index ec88410d3ac..9276450e133 100644 --- a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierSetConfigTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierSetConfigTest.t.sol @@ -15,8 +15,7 @@ contract VerifierSetConfigTest is BaseTest { vm.expectRevert("Only callable by owner"); Signer[] memory signers = _getSigners(MAX_ORACLES); - changePrank(USER); - s_verifier.setConfigFromSource( + bytes32 configDigest = _configDigestFromConfigData( FEED_ID, SOURCE_CHAIN_ID, SOURCE_ADDRESS, @@ -26,15 +25,22 @@ contract VerifierSetConfigTest is BaseTest { FAULT_TOLERANCE, bytes(""), VERIFIER_VERSION, - bytes(""), + bytes("") + ); + + changePrank(USER); + s_verifier.setConfig( + configDigest, + _getSignerAddresses(signers), + FAULT_TOLERANCE, new Common.AddressAndWeight[](0) ); } function test_revertsIfSetWithTooManySigners() public { address[] memory signers = new address[](MAX_ORACLES + 1); - vm.expectRevert(abi.encodeWithSelector(Verifier.ExcessSigners.selector, signers.length, MAX_ORACLES)); - s_verifier.setConfigFromSource( + + bytes32 configDigest = _configDigestFromConfigData( FEED_ID, SOURCE_CHAIN_ID, SOURCE_ADDRESS, @@ -44,15 +50,22 @@ contract VerifierSetConfigTest is BaseTest { FAULT_TOLERANCE, bytes(""), VERIFIER_VERSION, - bytes(""), + bytes("") + ); + + vm.expectRevert(abi.encodeWithSelector(Verifier.ExcessSigners.selector, signers.length, MAX_ORACLES)); + s_verifier.setConfig( + configDigest, + signers, + FAULT_TOLERANCE, new Common.AddressAndWeight[](0) ); } function test_revertsIfFaultToleranceIsZero() public { - vm.expectRevert(abi.encodeWithSelector(Verifier.FaultToleranceMustBePositive.selector)); Signer[] memory signers = _getSigners(MAX_ORACLES); - s_verifier.setConfigFromSource( + + bytes32 configDigest = _configDigestFromConfigData( FEED_ID, SOURCE_CHAIN_ID, SOURCE_ADDRESS, @@ -62,7 +75,14 @@ contract VerifierSetConfigTest is BaseTest { 0, bytes(""), VERIFIER_VERSION, - bytes(""), + bytes("") + ); + + vm.expectRevert(abi.encodeWithSelector(Verifier.FaultToleranceMustBePositive.selector)); + s_verifier.setConfig( + configDigest, + _getSignerAddresses(signers), + 0, new Common.AddressAndWeight[](0) ); } @@ -72,10 +92,7 @@ contract VerifierSetConfigTest is BaseTest { signers[0] = address(1000); signers[1] = address(1001); - vm.expectRevert( - abi.encodeWithSelector(Verifier.InsufficientSigners.selector, signers.length, FAULT_TOLERANCE * 3 + 1) - ); - s_verifier.setConfigFromSource( + bytes32 configDigest = _configDigestFromConfigData( FEED_ID, SOURCE_CHAIN_ID, SOURCE_ADDRESS, @@ -85,7 +102,16 @@ contract VerifierSetConfigTest is BaseTest { FAULT_TOLERANCE, bytes(""), VERIFIER_VERSION, - bytes(""), + bytes("") + ); + + vm.expectRevert( + abi.encodeWithSelector(Verifier.InsufficientSigners.selector, signers.length, FAULT_TOLERANCE * 3 + 1) + ); + s_verifier.setConfig( + configDigest, + signers, + FAULT_TOLERANCE, new Common.AddressAndWeight[](0) ); } @@ -94,8 +120,8 @@ contract VerifierSetConfigTest is BaseTest { Signer[] memory signers = _getSigners(MAX_ORACLES); address[] memory signerAddrs = _getSignerAddresses(signers); signerAddrs[0] = signerAddrs[1]; - vm.expectRevert(abi.encodeWithSelector(Verifier.NonUniqueSignatures.selector)); - s_verifier.setConfigFromSource( + + bytes32 configDigest = _configDigestFromConfigData( FEED_ID, SOURCE_CHAIN_ID, SOURCE_ADDRESS, @@ -105,7 +131,14 @@ contract VerifierSetConfigTest is BaseTest { FAULT_TOLERANCE, bytes(""), VERIFIER_VERSION, - bytes(""), + bytes("") + ); + + vm.expectRevert(abi.encodeWithSelector(Verifier.NonUniqueSignatures.selector)); + s_verifier.setConfig( + configDigest, + signerAddrs, + FAULT_TOLERANCE, new Common.AddressAndWeight[](0) ); } @@ -114,8 +147,8 @@ contract VerifierSetConfigTest is BaseTest { Signer[] memory signers = _getSigners(MAX_ORACLES); address[] memory signerAddrs = _getSignerAddresses(signers); signerAddrs[0] = address(0); - vm.expectRevert(abi.encodeWithSelector(Verifier.ZeroAddress.selector)); - s_verifier.setConfigFromSource( + + bytes32 configDigest = _configDigestFromConfigData( FEED_ID, SOURCE_CHAIN_ID, SOURCE_ADDRESS, @@ -125,7 +158,14 @@ contract VerifierSetConfigTest is BaseTest { FAULT_TOLERANCE, bytes(""), VERIFIER_VERSION, - bytes(""), + bytes("") + ); + + vm.expectRevert(abi.encodeWithSelector(Verifier.ZeroAddress.selector)); + s_verifier.setConfig( + configDigest, + signerAddrs, + FAULT_TOLERANCE, new Common.AddressAndWeight[](0) ); } @@ -134,7 +174,8 @@ contract VerifierSetConfigTest is BaseTest { Signer[] memory signers = _getSigners(MAX_ORACLES); s_verifierProxy.initializeVerifier(address(s_verifier)); - s_verifier.setConfigFromSource( + + bytes32 configDigest = _configDigestFromConfigData( FEED_ID, SOURCE_CHAIN_ID, SOURCE_ADDRESS, @@ -144,34 +185,159 @@ contract VerifierSetConfigTest is BaseTest { FAULT_TOLERANCE, bytes(""), VERIFIER_VERSION, - bytes(""), - new Common.AddressAndWeight[](0) + bytes("") ); - bytes32 configDigest = _configDigestFromConfigData( - FEED_ID, - SOURCE_CHAIN_ID, - SOURCE_ADDRESS, - 1, + s_verifier.setConfig( + configDigest, _getSignerAddresses(signers), - s_offchaintransmitters, FAULT_TOLERANCE, - bytes(""), - VERIFIER_VERSION, - bytes("") + new Common.AddressAndWeight[](0) + ); + + uint32 blockNumber = s_verifier.latestConfigDetails(configDigest); + assertEq(blockNumber, block.number); + } +} + +contract VerifierUpdateConfigTest is BaseTest { + + function setUp() public virtual override { + BaseTest.setUp(); + + s_verifierProxy.initializeVerifier(address(s_verifier)); + } + + function test_updateConfig() public { + // Get initial signers and config digest + address[] memory signerAddresses = _getSignerAddresses(_getSigners(15)); + bytes32 configDigest = keccak256("test222"); + + // Set initial config + s_verifier.setConfig( + configDigest, + signerAddresses, + 4, + new Common.AddressAndWeight[](0) + ); + + // Unset the config + s_verifier.updateConfig(configDigest, signerAddresses, signerAddresses, 4); + } + + function test_updateConfigRevertsIfFIsZero() public { + // Get initial signers and config digest + address[] memory signerAddresses = _getSignerAddresses(_getSigners(15)); + bytes32 configDigest = keccak256("test"); + + // Set initial config + s_verifier.setConfig( + configDigest, + signerAddresses, + 4, + new Common.AddressAndWeight[](0) ); - (uint32 configCount, uint32 blockNumber) = s_verifier.latestConfigDetails(configDigest); - assertEq(configCount, 1); + // Try to update with f=0 + vm.expectRevert(Verifier.FaultToleranceMustBePositive.selector); + s_verifier.updateConfig(configDigest, signerAddresses, signerAddresses, 0); + } + + function test_updateConfigRevertsIfFTooHigh() public { + // Get initial signers and config digest + address[] memory signerAddresses = _getSignerAddresses(_getSigners(15)); + bytes32 configDigest = keccak256("test"); + + // Set initial config + s_verifier.setConfig( + configDigest, + signerAddresses, + 4, + new Common.AddressAndWeight[](0) + ); + + // Try to update with f too high + vm.expectRevert(abi.encodeWithSelector(Verifier.InsufficientSigners.selector, signerAddresses.length, 46)); + s_verifier.updateConfig(configDigest, signerAddresses, signerAddresses, 15); + } + + function test_updateConfigWithDifferentSigners() public { + // Get initial signers and config digest + address[] memory initialSigners = _getSignerAddresses(_getSigners(15)); + bytes32 configDigest = keccak256("test"); + + // Set initial config + s_verifier.setConfig( + configDigest, + initialSigners, + 4, + new Common.AddressAndWeight[](0) + ); + + // Get new signers + address[] memory newSigners = _getSignerAddresses(_getSigners(20)); + + // Update config with new signers + s_verifier.updateConfig(configDigest, initialSigners, newSigners, 6); + + // Verify config was updated + uint32 blockNumber = s_verifier.latestConfigDetails(configDigest); assertEq(blockNumber, block.number); } + + function test_updateConfigRevertsIfDigestNotSet() public { + address[] memory signerAddresses = _getSignerAddresses(_getSigners(15)); + bytes32 nonExistentDigest = keccak256("nonexistent"); + + vm.expectRevert(abi.encodeWithSelector(Verifier.DigestNotSet.selector, nonExistentDigest)); + s_verifier.updateConfig(nonExistentDigest, signerAddresses, signerAddresses, 4); + } + + function test_updateConfigRevertsIfPrevSignersLengthMismatch() public { + // Get initial signers and config digest + address[] memory initialSigners = _getSignerAddresses(_getSigners(15)); + bytes32 configDigest = keccak256("test"); + + // Set initial config + s_verifier.setConfig( + configDigest, + initialSigners, + 4, + new Common.AddressAndWeight[](0) + ); + + // Try to update with wrong number of previous signers + address[] memory wrongPrevSigners = _getSignerAddresses(_getSigners(10)); + address[] memory newSigners = _getSignerAddresses(_getSigners(15)); + + vm.expectRevert(Verifier.NonUniqueSignatures.selector); + s_verifier.updateConfig(configDigest, wrongPrevSigners, newSigners, 4); + } + + function test_updateConfigRevertsIfCalledByNonOwner() public { + address[] memory signerAddresses = _getSignerAddresses(_getSigners(15)); + bytes32 configDigest = keccak256("test"); + + // Set initial config + s_verifier.setConfig( + configDigest, + signerAddresses, + 4, + new Common.AddressAndWeight[](0) + ); + + // Try to update as non-owner + changePrank(USER); + vm.expectRevert("Only callable by owner"); + s_verifier.updateConfig(configDigest, signerAddresses, signerAddresses, 4); + } } contract VerifierSetConfigWhenThereAreMultipleDigestsTest is BaseTestWithMultipleConfiguredDigests { function test_correctlyUpdatesTheDigestInTheProxy() public { Signer[] memory newSigners = _getSigners(15); - s_verifier.setConfigFromSource( + bytes32 configDigest = _configDigestFromConfigData( FEED_ID, SOURCE_CHAIN_ID, SOURCE_ADDRESS, @@ -181,21 +347,14 @@ contract VerifierSetConfigWhenThereAreMultipleDigestsTest is BaseTestWithMultipl 4, bytes(""), VERIFIER_VERSION, - bytes(""), - new Common.AddressAndWeight[](0) + bytes("") ); - bytes32 configDigest = _configDigestFromConfigData( - FEED_ID, - SOURCE_CHAIN_ID, - SOURCE_ADDRESS, - 1, + s_verifier.setConfig( + configDigest, _getSignerAddresses(newSigners), - s_offchaintransmitters, 4, - bytes(""), - VERIFIER_VERSION, - bytes("") + new Common.AddressAndWeight[](0) ); address verifierAddr = s_verifierProxy.getVerifier(configDigest); @@ -205,7 +364,7 @@ contract VerifierSetConfigWhenThereAreMultipleDigestsTest is BaseTestWithMultipl function test_correctlyUpdatesDigestsOnMultipleVerifiersInTheProxy() public { Signer[] memory newSigners = _getSigners(15); - s_verifier.setConfigFromSource( + bytes32 configDigest = _configDigestFromConfigData( FEED_ID_2, SOURCE_CHAIN_ID, SOURCE_ADDRESS, @@ -215,27 +374,20 @@ contract VerifierSetConfigWhenThereAreMultipleDigestsTest is BaseTestWithMultipl 4, bytes(""), VERIFIER_VERSION, - bytes(""), - new Common.AddressAndWeight[](0) + bytes("") ); - bytes32 configDigest = _configDigestFromConfigData( - FEED_ID_2, - SOURCE_CHAIN_ID, - SOURCE_ADDRESS, - 1, + s_verifier.setConfig( + configDigest, _getSignerAddresses(newSigners), - s_offchaintransmitters, 4, - bytes(""), - VERIFIER_VERSION, - bytes("") + new Common.AddressAndWeight[](0) ); address verifierAddr = s_verifierProxy.getVerifier(configDigest); assertEq(verifierAddr, address(s_verifier)); - s_verifier_2.setConfigFromSource( + bytes32 configDigest2 = _configDigestFromConfigData( FEED_ID_3, SOURCE_CHAIN_ID, SOURCE_ADDRESS, @@ -245,21 +397,14 @@ contract VerifierSetConfigWhenThereAreMultipleDigestsTest is BaseTestWithMultipl 4, bytes(""), VERIFIER_VERSION, - bytes(""), - new Common.AddressAndWeight[](0) + bytes("") ); - bytes32 configDigest2 = _configDigestFromConfigData( - FEED_ID_3, - SOURCE_CHAIN_ID, - SOURCE_ADDRESS, - 1, + s_verifier_2.setConfig( + configDigest2, _getSignerAddresses(newSigners), - s_offchaintransmitters, 4, - bytes(""), - VERIFIER_VERSION, - bytes("") + new Common.AddressAndWeight[](0) ); address verifierAddr2 = s_verifierProxy.getVerifier(configDigest2); @@ -271,21 +416,7 @@ contract VerifierSetConfigWhenThereAreMultipleDigestsTest is BaseTestWithMultipl Signer[] memory newSigners = _getSigners(15); - s_verifier.setConfigFromSource( - FEED_ID, - SOURCE_CHAIN_ID, - SOURCE_ADDRESS, - 1, - _getSignerAddresses(newSigners), - s_offchaintransmitters, - 4, - bytes(""), - VERIFIER_VERSION, - bytes(""), - new Common.AddressAndWeight[](0) - ); - - bytes32 expectedConfigDigest = _configDigestFromConfigData( + bytes32 configDigest = _configDigestFromConfigData( FEED_ID, SOURCE_CHAIN_ID, SOURCE_ADDRESS, @@ -298,31 +429,23 @@ contract VerifierSetConfigWhenThereAreMultipleDigestsTest is BaseTestWithMultipl bytes("") ); - bytes32 configDigest = _configDigestFromConfigData( - FEED_ID, - SOURCE_CHAIN_ID, - SOURCE_ADDRESS, - 1, + s_verifier.setConfig( + configDigest, _getSignerAddresses(newSigners), - s_offchaintransmitters, 4, - bytes(""), - VERIFIER_VERSION, - bytes("") + new Common.AddressAndWeight[](0) ); - (uint32 configCount, uint32 blockNumber) = s_verifier.latestConfigDetails(configDigest); + uint32 blockNumber = s_verifier.latestConfigDetails(configDigest); - assertEq(configCount, s_numConfigsSet + 1); assertEq(blockNumber, block.number); - assertEq(configDigest, expectedConfigDigest); } function test_revertsIfDuplicateConfigIsSet() public { // Set initial config - s_verifier.setConfigFromSource( + bytes32 configDigest = _configDigestFromConfigData( FEED_ID, - SOURCE_CHAIN_ID, + SOURCE_CHAIN_ID, SOURCE_ADDRESS, 1, _getSignerAddresses(_getSigners(15)), @@ -330,32 +453,31 @@ contract VerifierSetConfigWhenThereAreMultipleDigestsTest is BaseTestWithMultipl 4, bytes(""), VERIFIER_VERSION, - bytes(""), + bytes("") + ); + + s_verifier.setConfig( + configDigest, + _getSignerAddresses(_getSigners(15)), + 4, new Common.AddressAndWeight[](0) ); // Try to set same config again - vm.expectRevert(abi.encodeWithSelector(Verifier.NonUniqueSignatures.selector)); - s_verifier.setConfigFromSource( - FEED_ID, - SOURCE_CHAIN_ID, - SOURCE_ADDRESS, - 1, + vm.expectRevert(abi.encodeWithSelector(Verifier.ConfigDigestAlreadySet.selector)); + s_verifier.setConfig( + configDigest, _getSignerAddresses(_getSigners(15)), - s_offchaintransmitters, 4, - bytes(""), - VERIFIER_VERSION, - bytes(""), new Common.AddressAndWeight[](0) ); } function test_incrementalConfigUpdates() public { // Set initial config - s_verifier.setConfigFromSource( + bytes32 configDigest1 = _configDigestFromConfigData( FEED_ID, - SOURCE_CHAIN_ID, + SOURCE_CHAIN_ID, SOURCE_ADDRESS, 1, _getSignerAddresses(_getSigners(15)), @@ -363,12 +485,18 @@ contract VerifierSetConfigWhenThereAreMultipleDigestsTest is BaseTestWithMultipl 4, bytes(""), VERIFIER_VERSION, - bytes(""), + bytes("") + ); + + s_verifier.setConfig( + configDigest1, + _getSignerAddresses(_getSigners(15)), + 4, new Common.AddressAndWeight[](0) ); - // Try to set same config again - s_verifier.setConfigFromSource( + // Set second config + bytes32 configDigest2 = _configDigestFromConfigData( FEED_ID, SOURCE_CHAIN_ID, SOURCE_ADDRESS, @@ -378,11 +506,18 @@ contract VerifierSetConfigWhenThereAreMultipleDigestsTest is BaseTestWithMultipl 4, bytes(""), VERIFIER_VERSION, - bytes(""), + bytes("") + ); + + s_verifier.setConfig( + configDigest2, + _getSignerAddresses(_getSigners(15)), + 4, new Common.AddressAndWeight[](0) ); - s_verifier.setConfigFromSource( + // Set third config + bytes32 configDigest3 = _configDigestFromConfigData( FEED_ID, SOURCE_CHAIN_ID, SOURCE_ADDRESS, @@ -392,7 +527,13 @@ contract VerifierSetConfigWhenThereAreMultipleDigestsTest is BaseTestWithMultipl 4, bytes(""), VERIFIER_VERSION, - bytes(""), + bytes("") + ); + + s_verifier.setConfig( + configDigest3, + _getSignerAddresses(_getSigners(15)), + 4, new Common.AddressAndWeight[](0) ); } diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierTest.t.sol index 7f8fc472c35..ec0268bb74a 100644 --- a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierTest.t.sol @@ -14,8 +14,7 @@ contract VerifierConstructorTest is BaseTest { Verifier v = new Verifier(address(s_verifierProxy)); assertEq(v.owner(), ADMIN); - (uint32 configCount, uint32 blockNumber) = v.latestConfigDetails(FEED_ID); - assertEq(configCount, 0); + (uint32 blockNumber) = v.latestConfigDetails(FEED_ID); assertEq(blockNumber, 0); string memory typeAndVersion = s_verifier.typeAndVersion(); diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierVerifyTest.t.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierVerifyTest.t.sol index 96306ede6ae..8441bf6d06b 100644 --- a/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierVerifyTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/test/verifier/VerifierVerifyTest.t.sol @@ -234,7 +234,8 @@ contract VerifierVerifyMultipleConfigDigestTest is VerifierVerifyTest { function setUp() public override { VerifierVerifyTest.setUp(); s_oldConfigDigest = v1ConfigDigest; - s_verifier.setConfigFromSource( + + s_newConfigDigest = _configDigestFromConfigData( FEED_ID, SOURCE_CHAIN_ID, SOURCE_ADDRESS, @@ -244,20 +245,14 @@ contract VerifierVerifyMultipleConfigDigestTest is VerifierVerifyTest { FAULT_TOLERANCE_TWO, bytes(""), VERIFIER_VERSION, - bytes(""), - new Common.AddressAndWeight[](0) + bytes("") ); - s_newConfigDigest = _configDigestFromConfigData( - FEED_ID, - SOURCE_CHAIN_ID, - SOURCE_ADDRESS, - 2, + + s_verifier.setConfig( + s_newConfigDigest, _getSignerAddresses(_getSigners(20)), - s_offchaintransmitters, FAULT_TOLERANCE_TWO, - bytes(""), - VERIFIER_VERSION, - bytes("") + new Common.AddressAndWeight[](0) ); } @@ -311,4 +306,72 @@ contract VerifierVerifyMultipleConfigDigestTest is VerifierVerifyTest { changePrank(address(s_verifierProxy)); s_verifier.verify(signedReport, msg.sender); } + + function test_verifyAfterConfigUpdate() public { + // Get initial signers and set initial config + address[] memory initialSigners = _getSignerAddresses(_getSigners(15)); + bytes32 configDigest = keccak256("test"); + + s_verifier.setConfig( + configDigest, + initialSigners, + 4, + new Common.AddressAndWeight[](0) + ); + + // Get new signers and update config + address[] memory newSigners = _getSignerAddresses(_getSigners(20)); + s_verifier.updateConfig(configDigest, initialSigners, newSigners, 6); + + // Verify report with new signers should pass + s_reportContext[0] = configDigest; + bytes memory signedReportNewSigners = _generateV1EncodedBlob( + s_testReportOne, + s_reportContext, + _getSigners(7) // More than f=6 signers + ); + + bytes memory response = s_verifierProxy.verify(signedReportNewSigners, bytes("")); + assertReportsEqual(response, s_testReportOne); + + // Verify report with old signers should fail + bytes memory signedReportOldSigners = _generateV1EncodedBlob( + s_testReportOne, + s_reportContext, + _getSigners(5) // Old number of signers + ); + vm.expectRevert( + abi.encodeWithSelector(Verifier.IncorrectSignatureCount.selector, 5, 7) + ); + + s_verifierProxy.verify(signedReportOldSigners, bytes("")); + } + + function test_verifyAfterConfigUpdateWithExistingSigners() public { + // Get initial signers and set initial config + address[] memory signers = _getSignerAddresses(_getSigners(15)); + bytes32 configDigest = keccak256("test"); + + s_verifier.setConfig( + configDigest, + signers, + 4, + new Common.AddressAndWeight[](0) + ); + + // Update config with same signers and f + s_verifier.updateConfig(configDigest, signers, signers, 4); + + // Verify report should pass + s_reportContext[0] = configDigest; + bytes memory signedReport = _generateV1EncodedBlob( + s_testReportOne, + s_reportContext, + _getSigners(5) // More than f=4 signers + ); + + bytes memory response = s_verifierProxy.verify(signedReport, bytes("")); + assertReportsEqual(response, s_testReportOne); + + } } From 6e45c517d8162ee691fe431a234dd6b2d910cc30 Mon Sep 17 00:00:00 2001 From: Michael Fletcher Date: Fri, 22 Nov 2024 21:35:11 +0000 Subject: [PATCH 7/8] Audit fixes --- .../src/v0.8/llo-feeds/v0.5.0/FeeManager.sol | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/FeeManager.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/FeeManager.sol index 36d97644906..42ad8044759 100644 --- a/contracts/src/v0.8/llo-feeds/v0.5.0/FeeManager.sol +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/FeeManager.sol @@ -184,7 +184,7 @@ contract FeeManager is IFeeManager, ConfirmedOwner, TypeAndVersionInterface { ); if (fee.amount == 0) { - _tryReturnChange(subscriber, msg.value); + _transfer(subscriber, msg.value); return; } @@ -240,7 +240,7 @@ contract FeeManager is IFeeManager, ConfirmedOwner, TypeAndVersionInterface { if (numberOfLinkFees != 0 || numberOfNativeFees != 0) { _handleFeesAndRewards(subscriber, feesAndRewards, numberOfLinkFees, numberOfNativeFees); } else { - _tryReturnChange(subscriber, msg.value); + _transfer(subscriber, msg.value); } } @@ -361,9 +361,7 @@ contract FeeManager is IFeeManager, ConfirmedOwner, TypeAndVersionInterface { function withdraw(address assetAddress, address recipient, uint192 quantity) external onlyOwner { //address 0 is used to withdraw native in the context of withdrawing if (assetAddress == address(0)) { - (bool success, ) = payable(recipient).call{value: quantity}(""); - - if (!success) revert InvalidReceivingAddress(); + _transfer(recipient, quantity); return; } @@ -498,12 +496,13 @@ contract FeeManager is IFeeManager, ConfirmedOwner, TypeAndVersionInterface { } // a refund may be needed if the payee has paid in excess of the fee - _tryReturnChange(subscriber, change); + _transfer(subscriber, change); } - function _tryReturnChange(address subscriber, uint256 quantity) internal { + function _transfer(address to, uint256 quantity) internal { if (quantity != 0) { - payable(subscriber).transfer(quantity); + (bool success, ) = payable(to).call{value: quantity}(""); + if (!success) revert InvalidReceivingAddress(); } } From 1db7f341fb8360dcf562e4fd9f6fb44ba62a1da8 Mon Sep 17 00:00:00 2001 From: Michael Fletcher Date: Mon, 2 Dec 2024 18:02:55 +0000 Subject: [PATCH 8/8] wrappers / abi --- .../scripts/native_solc_compile_all_llo-feeds | 21 +- .../src/v0.8/llo-feeds/v0.5.0/Verifier.sol | 6 +- contracts/verify_v0_4_0_contracts.sh | 165 ++ .../fee_manager_v0_5_0/fee_manager_v0_5_0.go | 1786 +++++++++++++++++ .../generated/llo_feeds/llo_feeds.go | 1318 ------------ .../llo_feeds_test/llo_feeds_test.go | 202 -- .../reward_manager_v0_5_0.go | 1420 +++++++++++++ .../verifier_proxy_v0_5_0.go | 1387 +++++++++++++ .../verifier_v0_5_0/verifier_v0_5_0.go | 1385 +++++++++++++ ...rapper-dependency-versions-do-not-edit.txt | 33 +- core/gethwrappers/llo-feeds/go_generate.go | 35 +- 11 files changed, 6199 insertions(+), 1559 deletions(-) create mode 100755 contracts/verify_v0_4_0_contracts.sh create mode 100644 core/gethwrappers/llo-feeds/generated/fee_manager_v0_5_0/fee_manager_v0_5_0.go delete mode 100644 core/gethwrappers/llo-feeds/generated/llo_feeds/llo_feeds.go delete mode 100644 core/gethwrappers/llo-feeds/generated/llo_feeds_test/llo_feeds_test.go create mode 100644 core/gethwrappers/llo-feeds/generated/reward_manager_v0_5_0/reward_manager_v0_5_0.go create mode 100644 core/gethwrappers/llo-feeds/generated/verifier_proxy_v0_5_0/verifier_proxy_v0_5_0.go create mode 100644 core/gethwrappers/llo-feeds/generated/verifier_v0_5_0/verifier_v0_5_0.go diff --git a/contracts/scripts/native_solc_compile_all_llo-feeds b/contracts/scripts/native_solc_compile_all_llo-feeds index bbcd53df900..8cafea5cb4c 100755 --- a/contracts/scripts/native_solc_compile_all_llo-feeds +++ b/contracts/scripts/native_solc_compile_all_llo-feeds @@ -9,7 +9,6 @@ echo " └─────────────────────── SOLC_VERSION="0.8.19" OPTIMIZE_RUNS=1000000 - SCRIPTPATH="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" python3 -m pip install --require-hashes -r "$SCRIPTPATH"/requirements.txt solc-select install $SOLC_VERSION @@ -19,15 +18,15 @@ export SOLC_VERSION=$SOLC_VERSION ROOT="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; cd ../../ && pwd -P )" compileContract () { - local contract - contract=$(basename "$1" ".sol") - - solc --overwrite --optimize --optimize-runs $OPTIMIZE_RUNS --metadata-hash none \ - -o "$ROOT"/contracts/solc/v$SOLC_VERSION/"$contract" \ - --abi --bin --allow-paths "$ROOT"/contracts/src/v0.8\ - "$ROOT"/contracts/src/v0.8/"$1" + local contract dir + contract=$(basename "$1" ".sol") + dir=$(dirname "$1") + + solc --overwrite --optimize --optimize-runs $OPTIMIZE_RUNS --metadata-hash none \ + -o "$ROOT"/contracts/solc/v$SOLC_VERSION/"$dir"/"$contract" \ + --abi --bin --allow-paths "$ROOT"/contracts/src/v0.8\ + "$ROOT"/contracts/src/v0.8/"$1" } - compileContract llo-feeds/v0.3.0/Verifier.sol compileContract llo-feeds/v0.3.0/VerifierProxy.sol compileContract llo-feeds/v0.3.0/FeeManager.sol @@ -38,6 +37,10 @@ compileContract llo-feeds/v0.4.0/DestinationFeeManager.sol compileContract llo-feeds/v0.4.0/DestinationRewardManager.sol compileContract llo-feeds/v0.5.0/configuration/ChannelConfigStore.sol compileContract llo-feeds/v0.5.0/configuration/Configurator.sol +compileContract llo-feeds/v0.5.0/Verifier.sol +compileContract llo-feeds/v0.5.0/VerifierProxy.sol +compileContract llo-feeds/v0.5.0/FeeManager.sol +compileContract llo-feeds/v0.5.0/RewardManager.sol # Test | Mocks compileContract llo-feeds/v0.3.0/test/mocks/ErroredVerifier.sol diff --git a/contracts/src/v0.8/llo-feeds/v0.5.0/Verifier.sol b/contracts/src/v0.8/llo-feeds/v0.5.0/Verifier.sol index 371aa3e9d30..a081e737e7c 100644 --- a/contracts/src/v0.8/llo-feeds/v0.5.0/Verifier.sol +++ b/contracts/src/v0.8/llo-feeds/v0.5.0/Verifier.sol @@ -295,11 +295,11 @@ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface { address[] calldata signers, uint8 f, Common.AddressAndWeight[] memory recipientAddressesAndWeights, - bool updateConfig + bool _updateConfig ) internal { VerifierState storage verifierState = s_verifierStates[configDigest]; - if(verifierState.f > 0 && !updateConfig) { + if(verifierState.f > 0 && !_updateConfig) { revert ConfigDigestAlreadySet(); } @@ -325,7 +325,7 @@ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface { }); } - if(!updateConfig) { + if(!_updateConfig) { IVerifierProxy(i_verifierProxyAddr).setVerifier( bytes32(0), configDigest, diff --git a/contracts/verify_v0_4_0_contracts.sh b/contracts/verify_v0_4_0_contracts.sh new file mode 100755 index 00000000000..19ca77b9601 --- /dev/null +++ b/contracts/verify_v0_4_0_contracts.sh @@ -0,0 +1,165 @@ +#!/bin/bash + +# Default values +ETHERSCAN_API_KEY="xxx" +VERIFIER_URL="https://api-sepolia.blastscan.io/api" +COMPILER_VERSION="0.8.19+commit.7dd6d404" +NUM_OF_OPTIMIZATIONS=1000000 +DEPLOYMENT_INFO_FILE="deployment-info.json" + +# Function to parse command line arguments +parse_args() { + while [[ $# -gt 0 ]]; do + case $1 in + --etherscan-api-key) + ETHERSCAN_API_KEY="$2" + shift 2 + ;; + --verifier-url) + VERIFIER_URL="$2" + shift 2 + ;; + --compiler-version) + COMPILER_VERSION="$2" + shift 2 + ;; + --num-of-optimizations) + NUM_OF_OPTIMIZATIONS="$2" + shift 2 + ;; + --deployment-info) + DEPLOYMENT_INFO_FILE="$2" + shift 2 + ;; + *) + echo "Unknown option: $1" + exit 1 + ;; + esac + done +} + +# Function to verify a contract +verify_contract() { + local contract_name="$1" + local address="$2" + local constructor_args="$3" + local file_path="$4" + + if [ -z "$address" ] || [ "$address" == "null" ]; then + echo "Error: Invalid address for $contract_name" + exit 1 + fi + + local cmd="forge verify-contract" + cmd+=" --etherscan-api-key $ETHERSCAN_API_KEY" + cmd+=" --verifier-url $VERIFIER_URL" + cmd+=" $address" + cmd+=" $file_path:$contract_name" + cmd+=" --compiler-version $COMPILER_VERSION" + + if [ -n "$constructor_args" ]; then + cmd+=" --constructor-args $constructor_args" + fi + + cmd+=" --num-of-optimizations $NUM_OF_OPTIMIZATIONS" + + echo "Verifying $contract_name..." + + # Execute the command + if ! eval "$cmd"; then + echo "Verification failed for $contract_name" + exit 1 + fi + + echo "Verification successful for $contract_name" +} + +# Function to safely get JSON value +get_json_value() { + local value=$(echo "$DEPLOYMENT_INFO" | jq -r "$1") + if [ "$value" == "null" ] || [ -z "$value" ]; then + echo "" + else + echo "$value" + fi +} + +# Main execution +parse_args "$@" + +# Check if the deployment info file exists +if [ ! -f "$DEPLOYMENT_INFO_FILE" ]; then + echo "Error: Deployment info file '$DEPLOYMENT_INFO_FILE' not found." + exit 1 +fi + +# Read deployment info +DEPLOYMENT_INFO=$(cat "$DEPLOYMENT_INFO_FILE") + +# Verify DestinationFeeManager if present +if [ "$(get_json_value '.contracts.DestinationFeeManager')" != "" ]; then + address=$(get_json_value '.contracts.DestinationFeeManager.address') + linkToken=$(get_json_value '.contracts.DestinationFeeManager.params.linkToken') + nativeToken=$(get_json_value '.contracts.DestinationFeeManager.params.nativeToken') + verifier=$(get_json_value '.contracts.DestinationFeeManager.params.verifier') + rewardManager=$(get_json_value '.contracts.DestinationFeeManager.params.rewardManager') + + if [ -n "$address" ] && [ -n "$linkToken" ] && [ -n "$nativeToken" ] && [ -n "$verifier" ] && [ -n "$rewardManager" ]; then + constructor_args=$(cast abi-encode "constructor(address,address,address,address)" "$linkToken" "$nativeToken" "$verifier" "$rewardManager") + verify_contract "DestinationFeeManager" "$address" "$constructor_args" "src/v0.8/llo-feeds/v0.4.0/DestinationFeeManager.sol" + else + echo "Error: Missing parameters for DestinationFeeManager" + exit 1 + fi +else + echo "DestinationFeeManager not found in deployment info. Skipping." +fi + +# Verify DestinationRewardManager if present +if [ "$(get_json_value '.contracts.DestinationRewardManager')" != "" ]; then + address=$(get_json_value '.contracts.DestinationRewardManager.address') + linkToken=$(get_json_value '.contracts.DestinationRewardManager.params.linkToken') + + if [ -n "$address" ] && [ -n "$linkToken" ]; then + constructor_args=$(cast abi-encode "constructor(address)" "$linkToken") + verify_contract "DestinationRewardManager" "$address" "$constructor_args" "src/v0.8/llo-feeds/v0.4.0/DestinationRewardManager.sol" + else + echo "Error: Missing parameters for DestinationRewardManager" + exit 1 + fi +else + echo "DestinationRewardManager not found in deployment info. Skipping." +fi + +# Verify DestinationVerifier if present +if [ "$(get_json_value '.contracts.DestinationVerifier')" != "" ]; then + address=$(get_json_value '.contracts.DestinationVerifier.address') + destinationVerifierProxy=$(get_json_value '.contracts.DestinationVerifier.params.destinationVerifierProxy') + + if [ -n "$address" ] && [ -n "$destinationVerifierProxy" ]; then + constructor_args=$(cast abi-encode "constructor(address)" "$destinationVerifierProxy") + verify_contract "DestinationVerifier" "$address" "$constructor_args" "src/v0.8/llo-feeds/v0.4.0/DestinationVerifier.sol" + else + echo "Error: Missing parameters for DestinationVerifier" + exit 1 + fi +else + echo "DestinationVerifier not found in deployment info. Skipping." +fi + +# Verify DestinationVerifierProxy if present +if [ "$(get_json_value '.contracts.DestinationVerifierProxy')" != "" ]; then + address=$(get_json_value '.contracts.DestinationVerifierProxy.address') + + if [ -n "$address" ]; then + verify_contract "DestinationVerifierProxy" "$address" "" "src/v0.8/llo-feeds/v0.4.0/DestinationVerifierProxy.sol" + else + echo "Error: Missing address for DestinationVerifierProxy" + exit 1 + fi +else + echo "DestinationVerifierProxy not found in deployment info. Skipping." +fi + +echo "All present contracts verified successfully." diff --git a/core/gethwrappers/llo-feeds/generated/fee_manager_v0_5_0/fee_manager_v0_5_0.go b/core/gethwrappers/llo-feeds/generated/fee_manager_v0_5_0/fee_manager_v0_5_0.go new file mode 100644 index 00000000000..64b70873b0a --- /dev/null +++ b/core/gethwrappers/llo-feeds/generated/fee_manager_v0_5_0/fee_manager_v0_5_0.go @@ -0,0 +1,1786 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package fee_manager_v0_5_0 + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type CommonAddressAndWeight struct { + Addr common.Address + Weight uint64 +} + +type CommonAsset struct { + AssetAddress common.Address + Amount *big.Int +} + +type IRewardManagerFeePayment struct { + PoolId [32]byte + Amount *big.Int +} + +var FeeManagerMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_linkAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_nativeAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_proxyAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_rewardManagerAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ExpiredReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDeposit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDiscount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidQuote\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReceivingAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSurcharge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroDeficit\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"structCommon.Asset\",\"name\":\"fee\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"structCommon.Asset\",\"name\":\"reward\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"appliedDiscount\",\"type\":\"uint256\"}],\"name\":\"DiscountApplied\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"internalType\":\"uint192\",\"name\":\"amount\",\"type\":\"uint192\"}],\"indexed\":false,\"internalType\":\"structIRewardManager.FeePayment[]\",\"name\":\"rewards\",\"type\":\"tuple[]\"}],\"name\":\"InsufficientLink\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"linkQuantity\",\"type\":\"uint256\"}],\"name\":\"LinkDeficitCleared\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"newSurcharge\",\"type\":\"uint64\"}],\"name\":\"NativeSurchargeUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"discount\",\"type\":\"uint64\"}],\"name\":\"SubscriberDiscountUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"adminAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint192\",\"name\":\"quantity\",\"type\":\"uint192\"}],\"name\":\"Withdraw\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"quoteAddress\",\"type\":\"address\"}],\"name\":\"getFeeAndReward\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structCommon.Asset\",\"name\":\"\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structCommon.Asset\",\"name\":\"\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_linkAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_nativeAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_proxyAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_rewardManager\",\"outputs\":[{\"internalType\":\"contractIRewardManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkAvailableForPayment\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"payLinkDeficit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"parameterPayload\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"}],\"name\":\"processFee\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes[]\",\"name\":\"payloads\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"parameterPayload\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"}],\"name\":\"processFeeBulk\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"s_globalDiscounts\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"s_linkDeficit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_nativeSurcharge\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"s_subscriberDiscounts\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"rewardRecipientAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"setFeeRecipients\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"surcharge\",\"type\":\"uint64\"}],\"name\":\"setNativeSurcharge\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"discount\",\"type\":\"uint64\"}],\"name\":\"updateSubscriberDiscount\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"discount\",\"type\":\"uint64\"}],\"name\":\"updateSubscriberGlobalDiscount\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint192\",\"name\":\"quantity\",\"type\":\"uint192\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x6101006040523480156200001257600080fd5b506040516200374038038062003740833981016040819052620000359162000288565b33806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf81620001c0565b5050506001600160a01b0384161580620000e057506001600160a01b038316155b80620000f357506001600160a01b038216155b806200010657506001600160a01b038116155b15620001255760405163e6c4247b60e01b815260040160405180910390fd5b6001600160a01b03848116608081905284821660a05283821660c05290821660e081905260405163095ea7b360e01b81526004810191909152600019602482015263095ea7b3906044016020604051808303816000875af11580156200018f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001b59190620002e5565b505050505062000310565b336001600160a01b038216036200021a5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b03811681146200028357600080fd5b919050565b600080600080608085870312156200029f57600080fd5b620002aa856200026b565b9350620002ba602086016200026b565b9250620002ca604086016200026b565b9150620002da606086016200026b565b905092959194509250565b600060208284031215620002f857600080fd5b815180151581146200030957600080fd5b9392505050565b60805160a05160c05160e05161334062000400600039600081816102c301528181611644015281816117d20152818161209101526122df015260008181610383015281816107d701528181610f47015261171801526000818161033c01528181610ab301528181610d6a01528181611164015281816111bb015281816114b901528181611fb701526120600152600081816105280152818161095201528181610a5c01528181610d1301528181610eaa015281816110530152818161118901528181611212015281816113aa015281816114150152818161145501528181611c32015261215201526133406000f3fe6080604052600436106101805760003560e01c806376cf3187116100d6578063dba45fe01161007f578063ea4b861b11610059578063ea4b861b14610516578063f2fde38b1461054a578063f65df9621461056a57600080fd5b8063dba45fe014610478578063e03dab1a1461048b578063e389d9a4146104f657600080fd5b80638da5cb5b116100b05780638da5cb5b14610418578063ce7817d114610443578063d09dc3391461046357600080fd5b806376cf3187146103a557806379ba5097146103c557806387d6d843146103da57600080fd5b806332f5f746116101385780636387866811610112578063638786681461032a5780636c2f1a171461035e5780636d1342cb1461037157600080fd5b806332f5f7461461029b5780633aa5ac07146102b1578063505380941461030a57600080fd5b8063181f5a7711610169578063181f5a77146101f55780631cc7f2d8146102415780631d4d84a21461027957600080fd5b8063013f542b1461018557806301ffc9a7146101c5575b600080fd5b34801561019157600080fd5b506101b26101a036600461289a565b60046020526000908152604090205481565b6040519081526020015b60405180910390f35b3480156101d157600080fd5b506101e56101e03660046128b3565b61058a565b60405190151581526020016101bc565b34801561020157600080fd5b50604080518082018252601081527f4665654d616e6167657220322e312e3000000000000000000000000000000000602082015290516101bc9190612919565b34801561024d57600080fd5b506101b261025c36600461299c565b600360209081526000928352604080842090915290825290205481565b34801561028557600080fd5b506102996102943660046129fb565b610623565b005b3480156102a757600080fd5b506101b260055481565b3480156102bd57600080fd5b506102e57f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101bc565b34801561031657600080fd5b50610299610325366004612a5e565b610725565b34801561033657600080fd5b506102e57f000000000000000000000000000000000000000000000000000000000000000081565b61029961036c366004612ac2565b6107bf565b34801561037d57600080fd5b506102e57f000000000000000000000000000000000000000000000000000000000000000081565b3480156103b157600080fd5b506102996103c0366004612b71565b610a06565b3480156103d157600080fd5b50610299610bbb565b3480156103e657600080fd5b506101b26103f5366004612bb8565b600260209081526000938452604080852082529284528284209052825290205481565b34801561042457600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166102e5565b34801561044f57600080fd5b5061029961045e366004612bef565b610cbd565b34801561046f57600080fd5b506101b2610e79565b610299610486366004612c40565b610f2f565b34801561049757600080fd5b506104ab6104a6366004612d9e565b6110cb565b60408051845173ffffffffffffffffffffffffffffffffffffffff9081168252602095860151868301528451169181019190915292909101516060830152608082015260a0016101bc565b34801561050257600080fd5b5061029961051136600461289a565b61151b565b34801561052257600080fd5b506102e57f000000000000000000000000000000000000000000000000000000000000000081565b34801561055657600080fd5b50610299610565366004612df7565b6116ec565b34801561057657600080fd5b50610299610585366004612e14565b611700565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fdba45fe000000000000000000000000000000000000000000000000000000000148061061d57507fffffffff0000000000000000000000000000000000000000000000000000000082167f6c2f1a1700000000000000000000000000000000000000000000000000000000145b92915050565b61062b611842565b73ffffffffffffffffffffffffffffffffffffffff831661066f5761066a828277ffffffffffffffffffffffffffffffffffffffffffffffff166118c5565b505050565b6106aa73ffffffffffffffffffffffffffffffffffffffff84168377ffffffffffffffffffffffffffffffffffffffffffffffff8416611969565b6040805133815273ffffffffffffffffffffffffffffffffffffffff848116602083015285168183015277ffffffffffffffffffffffffffffffffffffffffffffffff8316606082015290517f7ff78a71698bdb18dcca96f52ab25e0a1b146fb6a49adf8e6845299e49021f299181900360800190a1505050565b61072d611842565b670de0b6b3a764000067ffffffffffffffff82161115610779576040517f05e8ac2900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff811660058190556040519081527f08f7c0d17932ddb8523bc06754d42ff19ebc77d76a8b9bfde02c28ab1ed3d6399060200160405180910390a150565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161461082e576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008467ffffffffffffffff81111561084957610849612cc4565b60405190808252806020026020018201604052801561088257816020015b61086f61280d565b8152602001906001900390816108675790505b5090506000806000805b888110156109cd5760008060006108c88d8d868181106108ae576108ae612e93565b90506020028101906108c09190612ec2565b8d8d8d611a3d565b92509250925082602001516000146109b95760405180608001604052808e8e878181106108f7576108f7612e93565b90506020028101906109099190612ec2565b61091291612f27565b81526020018481526020018381526020018281525088868061093390612f92565b97508151811061094557610945612e93565b60200260200101819052507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff16036109b2578660010196506109b9565b8560010195505b505050806109c690612f92565b905061088c565b50821515806109db57508115155b156109f1576109ec85858585611b4d565b6109fb565b6109fb85346118c5565b505050505050505050565b610a0e611842565b670de0b6b3a764000067ffffffffffffffff82161115610a5a576040517f997ea36000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614158015610b0257507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b15610b39576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff838116600081815260036020908152604080832094871680845294825280832067ffffffffffffffff87169081905581519586529185019190915290927f5eba5a8afa39780f0f99b6cbeb95f3da6a7040ca00abd46bdc91a0a060134139910160405180910390a3505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610c41576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610cc5611842565b670de0b6b3a764000067ffffffffffffffff82161115610d11576040517f997ea36000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614158015610db957507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b15610df0576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff848116600081815260026020908152604080832088845282528083209487168084529482529182902067ffffffffffffffff86169081905582519485529084015285927f5eba5a8afa39780f0f99b6cbeb95f3da6a7040ca00abd46bdc91a0a060134139910160405180910390a350505050565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015610f06573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f2a9190612fca565b905090565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610f9e576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806000610fb08888888888611a3d565b9250925092508260200151600003610fd457610fcc84346118c5565b5050506110c4565b604080516001808252818301909252600091816020015b610ff361280d565b815260200190600190039081610feb57505060408051608081019091529091508061101e8a8c612f27565b8152602001858152602001848152602001838152508160008151811061104657611046612e93565b60200260200101819052507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff16036110b6576109ec858260016000611b4d565b6109fb858260006001611b4d565b5050505050565b604080518082018252600080825260208083018290528351808501855282815280820183905284518086018652838152808301849052855180870190965283865291850183905292938261111e88612fe3565b90507fffff0000000000000000000000000000000000000000000000000000000000008082169081016111b957505073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811683527f0000000000000000000000000000000000000000000000000000000000000000168152909350915060009050611512565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff161415801561126157507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614155b15611298576040517ff861803000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060008b8060200190518101906112b1919061303c565b77ffffffffffffffffffffffffffffffffffffffffffffffff91821698509116955063ffffffff1693505050428210159050611319576040517fb6c405f500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff808e1660009081526002602090815260408083208984528252808320938f1683529290529081205490819003611393575073ffffffffffffffffffffffffffffffffffffffff808e166000908152600360209081526040808320938f16835292905220545b73ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001687526113f96113e182670de0b6b3a76400006130ae565b6113eb90866130c1565b670de0b6b3a7640000612361565b602088015273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116908d16036114865773ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016885260208088015190890152611503565b6005546000906114a2906113e190670de0b6b3a76400006130d8565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168a5290506114fc6114f283670de0b6b3a76400006130ae565b6113eb90836130c1565b60208a0152505b96995094975094955050505050505b93509350939050565b611523611842565b6000818152600460205260408120549081900361156c576040517f03aad31200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828152600460205260408082208290558051600180825281830190925290816020015b604080518082019091526000808252602082015281526020019060019003908161159157905050905060405180604001604052808481526020018377ffffffffffffffffffffffffffffffffffffffffffffffff16815250816000815181106115fc576115fc612e93565b60209081029190910101526040517fb0d9fa1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063b0d9fa199061167b908490309060040161314b565b600060405180830381600087803b15801561169557600080fd5b505af11580156116a9573d6000803e3d6000fd5b50505050827f843f0b103e50b42b08f9d30f12f961845a6d02623730872e24644899c0dd9895836040516116df91815260200190565b60405180910390a2505050565b6116f4611842565b6116fd81612399565b50565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161480159061175e575060005473ffffffffffffffffffffffffffffffffffffffff163314155b15611795576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f14060f2300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906314060f239061180b90869086908690600401613183565b600060405180830381600087803b15801561182557600080fd5b505af1158015611839573d6000803e3d6000fd5b50505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146118c3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610c38565b565b80156119655760008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114611925576040519150601f19603f3d011682016040523d82523d6000602084013e61192a565b606091505b505090508061066a576040517fef2af20100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261066a9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261248e565b6040805180820190915260008082526020820152604080518082019091526000808252602082015260003073ffffffffffffffffffffffffffffffffffffffff851603611ab6576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611ac4888a018a613203565b915050600081611ad390612fe3565b905060007e010000000000000000000000000000000000000000000000000000000000007fffff000000000000000000000000000000000000000000000000000000000000831614611b2e57611b2b888a018a612df7565b90505b611b398784836110cb565b955095509550505050955095509592505050565b60008267ffffffffffffffff811115611b6857611b68612cc4565b604051908082528060200260200182016040528015611bad57816020015b6040805180820190915260008082526020820152815260200190600190039081611b865790505b50905060008267ffffffffffffffff811115611bcb57611bcb612cc4565b604051908082528060200260200182016040528015611c1057816020015b6040805180820190915260008082526020820152815260200190600190039081611be95790505b509050600080808080611c23888a6130d8565b905060005b81811015611f72577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168b8281518110611c7957611c79612e93565b6020026020010151602001516000015173ffffffffffffffffffffffffffffffffffffffff1603611d3f5760405180604001604052808c8381518110611cc157611cc1612e93565b60200260200101516000015181526020018c8381518110611ce457611ce4612e93565b6020026020010151604001516020015177ffffffffffffffffffffffffffffffffffffffffffffffff16815250888580611d1d90612f92565b965081518110611d2f57611d2f612e93565b6020026020010181905250611e34565b60405180604001604052808c8381518110611d5c57611d5c612e93565b60200260200101516000015181526020018c8381518110611d7f57611d7f612e93565b6020026020010151604001516020015177ffffffffffffffffffffffffffffffffffffffffffffffff16815250878480611db890612f92565b955081518110611dca57611dca612e93565b60200260200101819052508a8181518110611de757611de7612e93565b6020026020010151602001516020015186611e0291906130d8565b95508a8181518110611e1657611e16612e93565b6020026020010151604001516020015185611e3191906130d8565b94505b8a8181518110611e4657611e46612e93565b602002602001015160600151600014611f62578b73ffffffffffffffffffffffffffffffffffffffff168b8281518110611e8257611e82612e93565b6020026020010151600001517f88b15eb682210089cddf967648e2cb2a4535aeadc8f8f36050922e33c04e71258d8481518110611ec157611ec1612e93565b6020026020010151602001518e8581518110611edf57611edf612e93565b6020026020010151604001518f8681518110611efd57611efd612e93565b602002602001015160600151604051611f5993929190835173ffffffffffffffffffffffffffffffffffffffff908116825260209485015185830152835116604082015291909201516060820152608081019190915260a00190565b60405180910390a35b611f6b81612f92565b9050611c28565b50600034156120405734861115611fb5576040517fb2e532de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0876040518263ffffffff1660e01b81526004016000604051808303818588803b15801561201d57600080fd5b505af1158015612031573d6000803e3d6000fd5b50505050508534039050612088565b85156120885761208873ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168d308961259a565b87511561211d577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b0d9fa19898e6040518363ffffffff1660e01b81526004016120ea92919061314b565b600060405180830381600087803b15801561210457600080fd5b505af1158015612118573d6000803e3d6000fd5b505050505b865115612349576040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156121ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121d29190612fca565b8511156122a25760005b8751811015612265578781815181106121f7576121f7612e93565b60200260200101516020015177ffffffffffffffffffffffffffffffffffffffffffffffff16600460008a848151811061223357612233612e93565b6020908102919091018101515182528101919091526040016000208054909101905561225e81612f92565b90506121dc565b507ff52e5907b69d97c33392936c12d78b494463b78c5b72df50b4c497eee5720b678760405161229591906132a7565b60405180910390a1612349565b6040517fb0d9fa1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063b0d9fa1990612316908a90309060040161314b565b600060405180830381600087803b15801561233057600080fd5b505af1158015612344573d6000803e3d6000fd5b505050505b6123538c826118c5565b505050505050505050505050565b6000821561238f57816123756001856130ae565b61237f91906132ba565b61238a9060016130d8565b612392565b60005b9392505050565b3373ffffffffffffffffffffffffffffffffffffffff821603612418576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610c38565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60006124f0826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166125fe9092919063ffffffff16565b80519091501561066a578080602001905181019061250e91906132f5565b61066a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610c38565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526125f89085907f23b872dd00000000000000000000000000000000000000000000000000000000906084016119bb565b50505050565b606061260d8484600085612615565b949350505050565b6060824710156126a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610c38565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516126d09190613317565b60006040518083038185875af1925050503d806000811461270d576040519150601f19603f3d011682016040523d82523d6000602084013e612712565b606091505b50915091506127238783838761272e565b979650505050505050565b606083156127c45782516000036127bd5773ffffffffffffffffffffffffffffffffffffffff85163b6127bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610c38565b508161260d565b61260d83838151156127d95781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c389190612919565b6040518060800160405280600080191681526020016128556040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600081525090565b815260200161288d6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600081525090565b8152602001600081525090565b6000602082840312156128ac57600080fd5b5035919050565b6000602082840312156128c557600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461239257600080fd5b60005b838110156129105781810151838201526020016128f8565b50506000910152565b60208152600082518060208401526129388160408501602087016128f5565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b73ffffffffffffffffffffffffffffffffffffffff811681146116fd57600080fd5b80356129978161296a565b919050565b600080604083850312156129af57600080fd5b82356129ba8161296a565b915060208301356129ca8161296a565b809150509250929050565b77ffffffffffffffffffffffffffffffffffffffffffffffff811681146116fd57600080fd5b600080600060608486031215612a1057600080fd5b8335612a1b8161296a565b92506020840135612a2b8161296a565b91506040840135612a3b816129d5565b809150509250925092565b803567ffffffffffffffff8116811461299757600080fd5b600060208284031215612a7057600080fd5b61239282612a46565b60008083601f840112612a8b57600080fd5b50813567ffffffffffffffff811115612aa357600080fd5b602083019150836020828501011115612abb57600080fd5b9250929050565b600080600080600060608688031215612ada57600080fd5b853567ffffffffffffffff80821115612af257600080fd5b818801915088601f830112612b0657600080fd5b813581811115612b1557600080fd5b8960208260051b8501011115612b2a57600080fd5b602092830197509550908701359080821115612b4557600080fd5b50612b5288828901612a79565b9094509250612b6590506040870161298c565b90509295509295909350565b600080600060608486031215612b8657600080fd5b8335612b918161296a565b92506020840135612ba18161296a565b9150612baf60408501612a46565b90509250925092565b600080600060608486031215612bcd57600080fd5b8335612bd88161296a565b9250602084013591506040840135612a3b8161296a565b60008060008060808587031215612c0557600080fd5b8435612c108161296a565b9350602085013592506040850135612c278161296a565b9150612c3560608601612a46565b905092959194509250565b600080600080600060608688031215612c5857600080fd5b853567ffffffffffffffff80821115612c7057600080fd5b612c7c89838a01612a79565b90975095506020880135915080821115612c9557600080fd5b50612ca288828901612a79565b9094509250506040860135612cb68161296a565b809150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112612d0457600080fd5b813567ffffffffffffffff80821115612d1f57612d1f612cc4565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715612d6557612d65612cc4565b81604052838152866020858801011115612d7e57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600060608486031215612db357600080fd5b8335612dbe8161296a565b9250602084013567ffffffffffffffff811115612dda57600080fd5b612de686828701612cf3565b9250506040840135612a3b8161296a565b600060208284031215612e0957600080fd5b81356123928161296a565b600080600060408486031215612e2957600080fd5b83359250602084013567ffffffffffffffff80821115612e4857600080fd5b818601915086601f830112612e5c57600080fd5b813581811115612e6b57600080fd5b8760208260061b8501011115612e8057600080fd5b6020830194508093505050509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112612ef757600080fd5b83018035915067ffffffffffffffff821115612f1257600080fd5b602001915036819003821315612abb57600080fd5b8035602083101561061d577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff602084900360031b1b1692915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612fc357612fc3612f63565b5060010190565b600060208284031215612fdc57600080fd5b5051919050565b80516020808301519190811015613022577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b805163ffffffff8116811461299757600080fd5b60008060008060008060c0878903121561305557600080fd5b8651955061306560208801613028565b945061307360408801613028565b93506060870151613083816129d5565b6080880151909350613094816129d5565b91506130a260a08801613028565b90509295509295509295565b8181038181111561061d5761061d612f63565b808202811582820484141761061d5761061d612f63565b8082018082111561061d5761061d612f63565b600081518084526020808501945080840160005b838110156131405781518051885283015177ffffffffffffffffffffffffffffffffffffffffffffffff1683880152604090960195908201906001016130ff565b509495945050505050565b60408152600061315e60408301856130eb565b905073ffffffffffffffffffffffffffffffffffffffff831660208301529392505050565b8381526040602080830182905282820184905260009190859060608501845b878110156131f65783356131b58161296a565b73ffffffffffffffffffffffffffffffffffffffff16825267ffffffffffffffff6131e1858501612a46565b168284015292840192908401906001016131a2565b5098975050505050505050565b6000806080838503121561321657600080fd5b83601f84011261322557600080fd5b6040516060810167ffffffffffffffff828210818311171561324957613249612cc4565b81604052829150606086018781111561326157600080fd5b865b8181101561327b578035845260209384019301613263565b509294509135918083111561328f57600080fd5b505061329d85828601612cf3565b9150509250929050565b60208152600061239260208301846130eb565b6000826132f0577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561330757600080fd5b8151801515811461239257600080fd5b600082516133298184602087016128f5565b919091019291505056fea164736f6c6343000813000a", +} + +var FeeManagerABI = FeeManagerMetaData.ABI + +var FeeManagerBin = FeeManagerMetaData.Bin + +func DeployFeeManager(auth *bind.TransactOpts, backend bind.ContractBackend, _linkAddress common.Address, _nativeAddress common.Address, _proxyAddress common.Address, _rewardManagerAddress common.Address) (common.Address, *types.Transaction, *FeeManager, error) { + parsed, err := FeeManagerMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(FeeManagerBin), backend, _linkAddress, _nativeAddress, _proxyAddress, _rewardManagerAddress) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &FeeManager{address: address, abi: *parsed, FeeManagerCaller: FeeManagerCaller{contract: contract}, FeeManagerTransactor: FeeManagerTransactor{contract: contract}, FeeManagerFilterer: FeeManagerFilterer{contract: contract}}, nil +} + +type FeeManager struct { + address common.Address + abi abi.ABI + FeeManagerCaller + FeeManagerTransactor + FeeManagerFilterer +} + +type FeeManagerCaller struct { + contract *bind.BoundContract +} + +type FeeManagerTransactor struct { + contract *bind.BoundContract +} + +type FeeManagerFilterer struct { + contract *bind.BoundContract +} + +type FeeManagerSession struct { + Contract *FeeManager + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type FeeManagerCallerSession struct { + Contract *FeeManagerCaller + CallOpts bind.CallOpts +} + +type FeeManagerTransactorSession struct { + Contract *FeeManagerTransactor + TransactOpts bind.TransactOpts +} + +type FeeManagerRaw struct { + Contract *FeeManager +} + +type FeeManagerCallerRaw struct { + Contract *FeeManagerCaller +} + +type FeeManagerTransactorRaw struct { + Contract *FeeManagerTransactor +} + +func NewFeeManager(address common.Address, backend bind.ContractBackend) (*FeeManager, error) { + abi, err := abi.JSON(strings.NewReader(FeeManagerABI)) + if err != nil { + return nil, err + } + contract, err := bindFeeManager(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &FeeManager{address: address, abi: abi, FeeManagerCaller: FeeManagerCaller{contract: contract}, FeeManagerTransactor: FeeManagerTransactor{contract: contract}, FeeManagerFilterer: FeeManagerFilterer{contract: contract}}, nil +} + +func NewFeeManagerCaller(address common.Address, caller bind.ContractCaller) (*FeeManagerCaller, error) { + contract, err := bindFeeManager(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &FeeManagerCaller{contract: contract}, nil +} + +func NewFeeManagerTransactor(address common.Address, transactor bind.ContractTransactor) (*FeeManagerTransactor, error) { + contract, err := bindFeeManager(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &FeeManagerTransactor{contract: contract}, nil +} + +func NewFeeManagerFilterer(address common.Address, filterer bind.ContractFilterer) (*FeeManagerFilterer, error) { + contract, err := bindFeeManager(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &FeeManagerFilterer{contract: contract}, nil +} + +func bindFeeManager(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := FeeManagerMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_FeeManager *FeeManagerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _FeeManager.Contract.FeeManagerCaller.contract.Call(opts, result, method, params...) +} + +func (_FeeManager *FeeManagerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _FeeManager.Contract.FeeManagerTransactor.contract.Transfer(opts) +} + +func (_FeeManager *FeeManagerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _FeeManager.Contract.FeeManagerTransactor.contract.Transact(opts, method, params...) +} + +func (_FeeManager *FeeManagerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _FeeManager.Contract.contract.Call(opts, result, method, params...) +} + +func (_FeeManager *FeeManagerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _FeeManager.Contract.contract.Transfer(opts) +} + +func (_FeeManager *FeeManagerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _FeeManager.Contract.contract.Transact(opts, method, params...) +} + +func (_FeeManager *FeeManagerCaller) GetFeeAndReward(opts *bind.CallOpts, subscriber common.Address, report []byte, quoteAddress common.Address) (CommonAsset, CommonAsset, *big.Int, error) { + var out []interface{} + err := _FeeManager.contract.Call(opts, &out, "getFeeAndReward", subscriber, report, quoteAddress) + + if err != nil { + return *new(CommonAsset), *new(CommonAsset), *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(CommonAsset)).(*CommonAsset) + out1 := *abi.ConvertType(out[1], new(CommonAsset)).(*CommonAsset) + out2 := *abi.ConvertType(out[2], new(*big.Int)).(**big.Int) + + return out0, out1, out2, err + +} + +func (_FeeManager *FeeManagerSession) GetFeeAndReward(subscriber common.Address, report []byte, quoteAddress common.Address) (CommonAsset, CommonAsset, *big.Int, error) { + return _FeeManager.Contract.GetFeeAndReward(&_FeeManager.CallOpts, subscriber, report, quoteAddress) +} + +func (_FeeManager *FeeManagerCallerSession) GetFeeAndReward(subscriber common.Address, report []byte, quoteAddress common.Address) (CommonAsset, CommonAsset, *big.Int, error) { + return _FeeManager.Contract.GetFeeAndReward(&_FeeManager.CallOpts, subscriber, report, quoteAddress) +} + +func (_FeeManager *FeeManagerCaller) ILinkAddress(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _FeeManager.contract.Call(opts, &out, "i_linkAddress") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_FeeManager *FeeManagerSession) ILinkAddress() (common.Address, error) { + return _FeeManager.Contract.ILinkAddress(&_FeeManager.CallOpts) +} + +func (_FeeManager *FeeManagerCallerSession) ILinkAddress() (common.Address, error) { + return _FeeManager.Contract.ILinkAddress(&_FeeManager.CallOpts) +} + +func (_FeeManager *FeeManagerCaller) INativeAddress(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _FeeManager.contract.Call(opts, &out, "i_nativeAddress") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_FeeManager *FeeManagerSession) INativeAddress() (common.Address, error) { + return _FeeManager.Contract.INativeAddress(&_FeeManager.CallOpts) +} + +func (_FeeManager *FeeManagerCallerSession) INativeAddress() (common.Address, error) { + return _FeeManager.Contract.INativeAddress(&_FeeManager.CallOpts) +} + +func (_FeeManager *FeeManagerCaller) IProxyAddress(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _FeeManager.contract.Call(opts, &out, "i_proxyAddress") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_FeeManager *FeeManagerSession) IProxyAddress() (common.Address, error) { + return _FeeManager.Contract.IProxyAddress(&_FeeManager.CallOpts) +} + +func (_FeeManager *FeeManagerCallerSession) IProxyAddress() (common.Address, error) { + return _FeeManager.Contract.IProxyAddress(&_FeeManager.CallOpts) +} + +func (_FeeManager *FeeManagerCaller) IRewardManager(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _FeeManager.contract.Call(opts, &out, "i_rewardManager") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_FeeManager *FeeManagerSession) IRewardManager() (common.Address, error) { + return _FeeManager.Contract.IRewardManager(&_FeeManager.CallOpts) +} + +func (_FeeManager *FeeManagerCallerSession) IRewardManager() (common.Address, error) { + return _FeeManager.Contract.IRewardManager(&_FeeManager.CallOpts) +} + +func (_FeeManager *FeeManagerCaller) LinkAvailableForPayment(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _FeeManager.contract.Call(opts, &out, "linkAvailableForPayment") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_FeeManager *FeeManagerSession) LinkAvailableForPayment() (*big.Int, error) { + return _FeeManager.Contract.LinkAvailableForPayment(&_FeeManager.CallOpts) +} + +func (_FeeManager *FeeManagerCallerSession) LinkAvailableForPayment() (*big.Int, error) { + return _FeeManager.Contract.LinkAvailableForPayment(&_FeeManager.CallOpts) +} + +func (_FeeManager *FeeManagerCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _FeeManager.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_FeeManager *FeeManagerSession) Owner() (common.Address, error) { + return _FeeManager.Contract.Owner(&_FeeManager.CallOpts) +} + +func (_FeeManager *FeeManagerCallerSession) Owner() (common.Address, error) { + return _FeeManager.Contract.Owner(&_FeeManager.CallOpts) +} + +func (_FeeManager *FeeManagerCaller) SGlobalDiscounts(opts *bind.CallOpts, arg0 common.Address, arg1 common.Address) (*big.Int, error) { + var out []interface{} + err := _FeeManager.contract.Call(opts, &out, "s_globalDiscounts", arg0, arg1) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_FeeManager *FeeManagerSession) SGlobalDiscounts(arg0 common.Address, arg1 common.Address) (*big.Int, error) { + return _FeeManager.Contract.SGlobalDiscounts(&_FeeManager.CallOpts, arg0, arg1) +} + +func (_FeeManager *FeeManagerCallerSession) SGlobalDiscounts(arg0 common.Address, arg1 common.Address) (*big.Int, error) { + return _FeeManager.Contract.SGlobalDiscounts(&_FeeManager.CallOpts, arg0, arg1) +} + +func (_FeeManager *FeeManagerCaller) SLinkDeficit(opts *bind.CallOpts, arg0 [32]byte) (*big.Int, error) { + var out []interface{} + err := _FeeManager.contract.Call(opts, &out, "s_linkDeficit", arg0) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_FeeManager *FeeManagerSession) SLinkDeficit(arg0 [32]byte) (*big.Int, error) { + return _FeeManager.Contract.SLinkDeficit(&_FeeManager.CallOpts, arg0) +} + +func (_FeeManager *FeeManagerCallerSession) SLinkDeficit(arg0 [32]byte) (*big.Int, error) { + return _FeeManager.Contract.SLinkDeficit(&_FeeManager.CallOpts, arg0) +} + +func (_FeeManager *FeeManagerCaller) SNativeSurcharge(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _FeeManager.contract.Call(opts, &out, "s_nativeSurcharge") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_FeeManager *FeeManagerSession) SNativeSurcharge() (*big.Int, error) { + return _FeeManager.Contract.SNativeSurcharge(&_FeeManager.CallOpts) +} + +func (_FeeManager *FeeManagerCallerSession) SNativeSurcharge() (*big.Int, error) { + return _FeeManager.Contract.SNativeSurcharge(&_FeeManager.CallOpts) +} + +func (_FeeManager *FeeManagerCaller) SSubscriberDiscounts(opts *bind.CallOpts, arg0 common.Address, arg1 [32]byte, arg2 common.Address) (*big.Int, error) { + var out []interface{} + err := _FeeManager.contract.Call(opts, &out, "s_subscriberDiscounts", arg0, arg1, arg2) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_FeeManager *FeeManagerSession) SSubscriberDiscounts(arg0 common.Address, arg1 [32]byte, arg2 common.Address) (*big.Int, error) { + return _FeeManager.Contract.SSubscriberDiscounts(&_FeeManager.CallOpts, arg0, arg1, arg2) +} + +func (_FeeManager *FeeManagerCallerSession) SSubscriberDiscounts(arg0 common.Address, arg1 [32]byte, arg2 common.Address) (*big.Int, error) { + return _FeeManager.Contract.SSubscriberDiscounts(&_FeeManager.CallOpts, arg0, arg1, arg2) +} + +func (_FeeManager *FeeManagerCaller) SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) { + var out []interface{} + err := _FeeManager.contract.Call(opts, &out, "supportsInterface", interfaceId) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_FeeManager *FeeManagerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _FeeManager.Contract.SupportsInterface(&_FeeManager.CallOpts, interfaceId) +} + +func (_FeeManager *FeeManagerCallerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _FeeManager.Contract.SupportsInterface(&_FeeManager.CallOpts, interfaceId) +} + +func (_FeeManager *FeeManagerCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _FeeManager.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_FeeManager *FeeManagerSession) TypeAndVersion() (string, error) { + return _FeeManager.Contract.TypeAndVersion(&_FeeManager.CallOpts) +} + +func (_FeeManager *FeeManagerCallerSession) TypeAndVersion() (string, error) { + return _FeeManager.Contract.TypeAndVersion(&_FeeManager.CallOpts) +} + +func (_FeeManager *FeeManagerTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _FeeManager.contract.Transact(opts, "acceptOwnership") +} + +func (_FeeManager *FeeManagerSession) AcceptOwnership() (*types.Transaction, error) { + return _FeeManager.Contract.AcceptOwnership(&_FeeManager.TransactOpts) +} + +func (_FeeManager *FeeManagerTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _FeeManager.Contract.AcceptOwnership(&_FeeManager.TransactOpts) +} + +func (_FeeManager *FeeManagerTransactor) PayLinkDeficit(opts *bind.TransactOpts, configDigest [32]byte) (*types.Transaction, error) { + return _FeeManager.contract.Transact(opts, "payLinkDeficit", configDigest) +} + +func (_FeeManager *FeeManagerSession) PayLinkDeficit(configDigest [32]byte) (*types.Transaction, error) { + return _FeeManager.Contract.PayLinkDeficit(&_FeeManager.TransactOpts, configDigest) +} + +func (_FeeManager *FeeManagerTransactorSession) PayLinkDeficit(configDigest [32]byte) (*types.Transaction, error) { + return _FeeManager.Contract.PayLinkDeficit(&_FeeManager.TransactOpts, configDigest) +} + +func (_FeeManager *FeeManagerTransactor) ProcessFee(opts *bind.TransactOpts, payload []byte, parameterPayload []byte, subscriber common.Address) (*types.Transaction, error) { + return _FeeManager.contract.Transact(opts, "processFee", payload, parameterPayload, subscriber) +} + +func (_FeeManager *FeeManagerSession) ProcessFee(payload []byte, parameterPayload []byte, subscriber common.Address) (*types.Transaction, error) { + return _FeeManager.Contract.ProcessFee(&_FeeManager.TransactOpts, payload, parameterPayload, subscriber) +} + +func (_FeeManager *FeeManagerTransactorSession) ProcessFee(payload []byte, parameterPayload []byte, subscriber common.Address) (*types.Transaction, error) { + return _FeeManager.Contract.ProcessFee(&_FeeManager.TransactOpts, payload, parameterPayload, subscriber) +} + +func (_FeeManager *FeeManagerTransactor) ProcessFeeBulk(opts *bind.TransactOpts, payloads [][]byte, parameterPayload []byte, subscriber common.Address) (*types.Transaction, error) { + return _FeeManager.contract.Transact(opts, "processFeeBulk", payloads, parameterPayload, subscriber) +} + +func (_FeeManager *FeeManagerSession) ProcessFeeBulk(payloads [][]byte, parameterPayload []byte, subscriber common.Address) (*types.Transaction, error) { + return _FeeManager.Contract.ProcessFeeBulk(&_FeeManager.TransactOpts, payloads, parameterPayload, subscriber) +} + +func (_FeeManager *FeeManagerTransactorSession) ProcessFeeBulk(payloads [][]byte, parameterPayload []byte, subscriber common.Address) (*types.Transaction, error) { + return _FeeManager.Contract.ProcessFeeBulk(&_FeeManager.TransactOpts, payloads, parameterPayload, subscriber) +} + +func (_FeeManager *FeeManagerTransactor) SetFeeRecipients(opts *bind.TransactOpts, configDigest [32]byte, rewardRecipientAndWeights []CommonAddressAndWeight) (*types.Transaction, error) { + return _FeeManager.contract.Transact(opts, "setFeeRecipients", configDigest, rewardRecipientAndWeights) +} + +func (_FeeManager *FeeManagerSession) SetFeeRecipients(configDigest [32]byte, rewardRecipientAndWeights []CommonAddressAndWeight) (*types.Transaction, error) { + return _FeeManager.Contract.SetFeeRecipients(&_FeeManager.TransactOpts, configDigest, rewardRecipientAndWeights) +} + +func (_FeeManager *FeeManagerTransactorSession) SetFeeRecipients(configDigest [32]byte, rewardRecipientAndWeights []CommonAddressAndWeight) (*types.Transaction, error) { + return _FeeManager.Contract.SetFeeRecipients(&_FeeManager.TransactOpts, configDigest, rewardRecipientAndWeights) +} + +func (_FeeManager *FeeManagerTransactor) SetNativeSurcharge(opts *bind.TransactOpts, surcharge uint64) (*types.Transaction, error) { + return _FeeManager.contract.Transact(opts, "setNativeSurcharge", surcharge) +} + +func (_FeeManager *FeeManagerSession) SetNativeSurcharge(surcharge uint64) (*types.Transaction, error) { + return _FeeManager.Contract.SetNativeSurcharge(&_FeeManager.TransactOpts, surcharge) +} + +func (_FeeManager *FeeManagerTransactorSession) SetNativeSurcharge(surcharge uint64) (*types.Transaction, error) { + return _FeeManager.Contract.SetNativeSurcharge(&_FeeManager.TransactOpts, surcharge) +} + +func (_FeeManager *FeeManagerTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _FeeManager.contract.Transact(opts, "transferOwnership", to) +} + +func (_FeeManager *FeeManagerSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _FeeManager.Contract.TransferOwnership(&_FeeManager.TransactOpts, to) +} + +func (_FeeManager *FeeManagerTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _FeeManager.Contract.TransferOwnership(&_FeeManager.TransactOpts, to) +} + +func (_FeeManager *FeeManagerTransactor) UpdateSubscriberDiscount(opts *bind.TransactOpts, subscriber common.Address, feedId [32]byte, token common.Address, discount uint64) (*types.Transaction, error) { + return _FeeManager.contract.Transact(opts, "updateSubscriberDiscount", subscriber, feedId, token, discount) +} + +func (_FeeManager *FeeManagerSession) UpdateSubscriberDiscount(subscriber common.Address, feedId [32]byte, token common.Address, discount uint64) (*types.Transaction, error) { + return _FeeManager.Contract.UpdateSubscriberDiscount(&_FeeManager.TransactOpts, subscriber, feedId, token, discount) +} + +func (_FeeManager *FeeManagerTransactorSession) UpdateSubscriberDiscount(subscriber common.Address, feedId [32]byte, token common.Address, discount uint64) (*types.Transaction, error) { + return _FeeManager.Contract.UpdateSubscriberDiscount(&_FeeManager.TransactOpts, subscriber, feedId, token, discount) +} + +func (_FeeManager *FeeManagerTransactor) UpdateSubscriberGlobalDiscount(opts *bind.TransactOpts, subscriber common.Address, token common.Address, discount uint64) (*types.Transaction, error) { + return _FeeManager.contract.Transact(opts, "updateSubscriberGlobalDiscount", subscriber, token, discount) +} + +func (_FeeManager *FeeManagerSession) UpdateSubscriberGlobalDiscount(subscriber common.Address, token common.Address, discount uint64) (*types.Transaction, error) { + return _FeeManager.Contract.UpdateSubscriberGlobalDiscount(&_FeeManager.TransactOpts, subscriber, token, discount) +} + +func (_FeeManager *FeeManagerTransactorSession) UpdateSubscriberGlobalDiscount(subscriber common.Address, token common.Address, discount uint64) (*types.Transaction, error) { + return _FeeManager.Contract.UpdateSubscriberGlobalDiscount(&_FeeManager.TransactOpts, subscriber, token, discount) +} + +func (_FeeManager *FeeManagerTransactor) Withdraw(opts *bind.TransactOpts, assetAddress common.Address, recipient common.Address, quantity *big.Int) (*types.Transaction, error) { + return _FeeManager.contract.Transact(opts, "withdraw", assetAddress, recipient, quantity) +} + +func (_FeeManager *FeeManagerSession) Withdraw(assetAddress common.Address, recipient common.Address, quantity *big.Int) (*types.Transaction, error) { + return _FeeManager.Contract.Withdraw(&_FeeManager.TransactOpts, assetAddress, recipient, quantity) +} + +func (_FeeManager *FeeManagerTransactorSession) Withdraw(assetAddress common.Address, recipient common.Address, quantity *big.Int) (*types.Transaction, error) { + return _FeeManager.Contract.Withdraw(&_FeeManager.TransactOpts, assetAddress, recipient, quantity) +} + +type FeeManagerDiscountAppliedIterator struct { + Event *FeeManagerDiscountApplied + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *FeeManagerDiscountAppliedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(FeeManagerDiscountApplied) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(FeeManagerDiscountApplied) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *FeeManagerDiscountAppliedIterator) Error() error { + return it.fail +} + +func (it *FeeManagerDiscountAppliedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type FeeManagerDiscountApplied struct { + ConfigDigest [32]byte + Subscriber common.Address + Fee CommonAsset + Reward CommonAsset + AppliedDiscount *big.Int + Raw types.Log +} + +func (_FeeManager *FeeManagerFilterer) FilterDiscountApplied(opts *bind.FilterOpts, configDigest [][32]byte, subscriber []common.Address) (*FeeManagerDiscountAppliedIterator, error) { + + var configDigestRule []interface{} + for _, configDigestItem := range configDigest { + configDigestRule = append(configDigestRule, configDigestItem) + } + var subscriberRule []interface{} + for _, subscriberItem := range subscriber { + subscriberRule = append(subscriberRule, subscriberItem) + } + + logs, sub, err := _FeeManager.contract.FilterLogs(opts, "DiscountApplied", configDigestRule, subscriberRule) + if err != nil { + return nil, err + } + return &FeeManagerDiscountAppliedIterator{contract: _FeeManager.contract, event: "DiscountApplied", logs: logs, sub: sub}, nil +} + +func (_FeeManager *FeeManagerFilterer) WatchDiscountApplied(opts *bind.WatchOpts, sink chan<- *FeeManagerDiscountApplied, configDigest [][32]byte, subscriber []common.Address) (event.Subscription, error) { + + var configDigestRule []interface{} + for _, configDigestItem := range configDigest { + configDigestRule = append(configDigestRule, configDigestItem) + } + var subscriberRule []interface{} + for _, subscriberItem := range subscriber { + subscriberRule = append(subscriberRule, subscriberItem) + } + + logs, sub, err := _FeeManager.contract.WatchLogs(opts, "DiscountApplied", configDigestRule, subscriberRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(FeeManagerDiscountApplied) + if err := _FeeManager.contract.UnpackLog(event, "DiscountApplied", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_FeeManager *FeeManagerFilterer) ParseDiscountApplied(log types.Log) (*FeeManagerDiscountApplied, error) { + event := new(FeeManagerDiscountApplied) + if err := _FeeManager.contract.UnpackLog(event, "DiscountApplied", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type FeeManagerInsufficientLinkIterator struct { + Event *FeeManagerInsufficientLink + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *FeeManagerInsufficientLinkIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(FeeManagerInsufficientLink) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(FeeManagerInsufficientLink) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *FeeManagerInsufficientLinkIterator) Error() error { + return it.fail +} + +func (it *FeeManagerInsufficientLinkIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type FeeManagerInsufficientLink struct { + Rewards []IRewardManagerFeePayment + Raw types.Log +} + +func (_FeeManager *FeeManagerFilterer) FilterInsufficientLink(opts *bind.FilterOpts) (*FeeManagerInsufficientLinkIterator, error) { + + logs, sub, err := _FeeManager.contract.FilterLogs(opts, "InsufficientLink") + if err != nil { + return nil, err + } + return &FeeManagerInsufficientLinkIterator{contract: _FeeManager.contract, event: "InsufficientLink", logs: logs, sub: sub}, nil +} + +func (_FeeManager *FeeManagerFilterer) WatchInsufficientLink(opts *bind.WatchOpts, sink chan<- *FeeManagerInsufficientLink) (event.Subscription, error) { + + logs, sub, err := _FeeManager.contract.WatchLogs(opts, "InsufficientLink") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(FeeManagerInsufficientLink) + if err := _FeeManager.contract.UnpackLog(event, "InsufficientLink", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_FeeManager *FeeManagerFilterer) ParseInsufficientLink(log types.Log) (*FeeManagerInsufficientLink, error) { + event := new(FeeManagerInsufficientLink) + if err := _FeeManager.contract.UnpackLog(event, "InsufficientLink", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type FeeManagerLinkDeficitClearedIterator struct { + Event *FeeManagerLinkDeficitCleared + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *FeeManagerLinkDeficitClearedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(FeeManagerLinkDeficitCleared) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(FeeManagerLinkDeficitCleared) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *FeeManagerLinkDeficitClearedIterator) Error() error { + return it.fail +} + +func (it *FeeManagerLinkDeficitClearedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type FeeManagerLinkDeficitCleared struct { + ConfigDigest [32]byte + LinkQuantity *big.Int + Raw types.Log +} + +func (_FeeManager *FeeManagerFilterer) FilterLinkDeficitCleared(opts *bind.FilterOpts, configDigest [][32]byte) (*FeeManagerLinkDeficitClearedIterator, error) { + + var configDigestRule []interface{} + for _, configDigestItem := range configDigest { + configDigestRule = append(configDigestRule, configDigestItem) + } + + logs, sub, err := _FeeManager.contract.FilterLogs(opts, "LinkDeficitCleared", configDigestRule) + if err != nil { + return nil, err + } + return &FeeManagerLinkDeficitClearedIterator{contract: _FeeManager.contract, event: "LinkDeficitCleared", logs: logs, sub: sub}, nil +} + +func (_FeeManager *FeeManagerFilterer) WatchLinkDeficitCleared(opts *bind.WatchOpts, sink chan<- *FeeManagerLinkDeficitCleared, configDigest [][32]byte) (event.Subscription, error) { + + var configDigestRule []interface{} + for _, configDigestItem := range configDigest { + configDigestRule = append(configDigestRule, configDigestItem) + } + + logs, sub, err := _FeeManager.contract.WatchLogs(opts, "LinkDeficitCleared", configDigestRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(FeeManagerLinkDeficitCleared) + if err := _FeeManager.contract.UnpackLog(event, "LinkDeficitCleared", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_FeeManager *FeeManagerFilterer) ParseLinkDeficitCleared(log types.Log) (*FeeManagerLinkDeficitCleared, error) { + event := new(FeeManagerLinkDeficitCleared) + if err := _FeeManager.contract.UnpackLog(event, "LinkDeficitCleared", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type FeeManagerNativeSurchargeUpdatedIterator struct { + Event *FeeManagerNativeSurchargeUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *FeeManagerNativeSurchargeUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(FeeManagerNativeSurchargeUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(FeeManagerNativeSurchargeUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *FeeManagerNativeSurchargeUpdatedIterator) Error() error { + return it.fail +} + +func (it *FeeManagerNativeSurchargeUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type FeeManagerNativeSurchargeUpdated struct { + NewSurcharge uint64 + Raw types.Log +} + +func (_FeeManager *FeeManagerFilterer) FilterNativeSurchargeUpdated(opts *bind.FilterOpts) (*FeeManagerNativeSurchargeUpdatedIterator, error) { + + logs, sub, err := _FeeManager.contract.FilterLogs(opts, "NativeSurchargeUpdated") + if err != nil { + return nil, err + } + return &FeeManagerNativeSurchargeUpdatedIterator{contract: _FeeManager.contract, event: "NativeSurchargeUpdated", logs: logs, sub: sub}, nil +} + +func (_FeeManager *FeeManagerFilterer) WatchNativeSurchargeUpdated(opts *bind.WatchOpts, sink chan<- *FeeManagerNativeSurchargeUpdated) (event.Subscription, error) { + + logs, sub, err := _FeeManager.contract.WatchLogs(opts, "NativeSurchargeUpdated") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(FeeManagerNativeSurchargeUpdated) + if err := _FeeManager.contract.UnpackLog(event, "NativeSurchargeUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_FeeManager *FeeManagerFilterer) ParseNativeSurchargeUpdated(log types.Log) (*FeeManagerNativeSurchargeUpdated, error) { + event := new(FeeManagerNativeSurchargeUpdated) + if err := _FeeManager.contract.UnpackLog(event, "NativeSurchargeUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type FeeManagerOwnershipTransferRequestedIterator struct { + Event *FeeManagerOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *FeeManagerOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(FeeManagerOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(FeeManagerOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *FeeManagerOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *FeeManagerOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type FeeManagerOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_FeeManager *FeeManagerFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*FeeManagerOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _FeeManager.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &FeeManagerOwnershipTransferRequestedIterator{contract: _FeeManager.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_FeeManager *FeeManagerFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *FeeManagerOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _FeeManager.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(FeeManagerOwnershipTransferRequested) + if err := _FeeManager.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_FeeManager *FeeManagerFilterer) ParseOwnershipTransferRequested(log types.Log) (*FeeManagerOwnershipTransferRequested, error) { + event := new(FeeManagerOwnershipTransferRequested) + if err := _FeeManager.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type FeeManagerOwnershipTransferredIterator struct { + Event *FeeManagerOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *FeeManagerOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(FeeManagerOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(FeeManagerOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *FeeManagerOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *FeeManagerOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type FeeManagerOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_FeeManager *FeeManagerFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*FeeManagerOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _FeeManager.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &FeeManagerOwnershipTransferredIterator{contract: _FeeManager.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_FeeManager *FeeManagerFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *FeeManagerOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _FeeManager.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(FeeManagerOwnershipTransferred) + if err := _FeeManager.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_FeeManager *FeeManagerFilterer) ParseOwnershipTransferred(log types.Log) (*FeeManagerOwnershipTransferred, error) { + event := new(FeeManagerOwnershipTransferred) + if err := _FeeManager.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type FeeManagerSubscriberDiscountUpdatedIterator struct { + Event *FeeManagerSubscriberDiscountUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *FeeManagerSubscriberDiscountUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(FeeManagerSubscriberDiscountUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(FeeManagerSubscriberDiscountUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *FeeManagerSubscriberDiscountUpdatedIterator) Error() error { + return it.fail +} + +func (it *FeeManagerSubscriberDiscountUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type FeeManagerSubscriberDiscountUpdated struct { + Subscriber common.Address + FeedId [32]byte + Token common.Address + Discount uint64 + Raw types.Log +} + +func (_FeeManager *FeeManagerFilterer) FilterSubscriberDiscountUpdated(opts *bind.FilterOpts, subscriber []common.Address, feedId [][32]byte) (*FeeManagerSubscriberDiscountUpdatedIterator, error) { + + var subscriberRule []interface{} + for _, subscriberItem := range subscriber { + subscriberRule = append(subscriberRule, subscriberItem) + } + var feedIdRule []interface{} + for _, feedIdItem := range feedId { + feedIdRule = append(feedIdRule, feedIdItem) + } + + logs, sub, err := _FeeManager.contract.FilterLogs(opts, "SubscriberDiscountUpdated", subscriberRule, feedIdRule) + if err != nil { + return nil, err + } + return &FeeManagerSubscriberDiscountUpdatedIterator{contract: _FeeManager.contract, event: "SubscriberDiscountUpdated", logs: logs, sub: sub}, nil +} + +func (_FeeManager *FeeManagerFilterer) WatchSubscriberDiscountUpdated(opts *bind.WatchOpts, sink chan<- *FeeManagerSubscriberDiscountUpdated, subscriber []common.Address, feedId [][32]byte) (event.Subscription, error) { + + var subscriberRule []interface{} + for _, subscriberItem := range subscriber { + subscriberRule = append(subscriberRule, subscriberItem) + } + var feedIdRule []interface{} + for _, feedIdItem := range feedId { + feedIdRule = append(feedIdRule, feedIdItem) + } + + logs, sub, err := _FeeManager.contract.WatchLogs(opts, "SubscriberDiscountUpdated", subscriberRule, feedIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(FeeManagerSubscriberDiscountUpdated) + if err := _FeeManager.contract.UnpackLog(event, "SubscriberDiscountUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_FeeManager *FeeManagerFilterer) ParseSubscriberDiscountUpdated(log types.Log) (*FeeManagerSubscriberDiscountUpdated, error) { + event := new(FeeManagerSubscriberDiscountUpdated) + if err := _FeeManager.contract.UnpackLog(event, "SubscriberDiscountUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type FeeManagerWithdrawIterator struct { + Event *FeeManagerWithdraw + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *FeeManagerWithdrawIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(FeeManagerWithdraw) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(FeeManagerWithdraw) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *FeeManagerWithdrawIterator) Error() error { + return it.fail +} + +func (it *FeeManagerWithdrawIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type FeeManagerWithdraw struct { + AdminAddress common.Address + Recipient common.Address + AssetAddress common.Address + Quantity *big.Int + Raw types.Log +} + +func (_FeeManager *FeeManagerFilterer) FilterWithdraw(opts *bind.FilterOpts) (*FeeManagerWithdrawIterator, error) { + + logs, sub, err := _FeeManager.contract.FilterLogs(opts, "Withdraw") + if err != nil { + return nil, err + } + return &FeeManagerWithdrawIterator{contract: _FeeManager.contract, event: "Withdraw", logs: logs, sub: sub}, nil +} + +func (_FeeManager *FeeManagerFilterer) WatchWithdraw(opts *bind.WatchOpts, sink chan<- *FeeManagerWithdraw) (event.Subscription, error) { + + logs, sub, err := _FeeManager.contract.WatchLogs(opts, "Withdraw") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(FeeManagerWithdraw) + if err := _FeeManager.contract.UnpackLog(event, "Withdraw", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_FeeManager *FeeManagerFilterer) ParseWithdraw(log types.Log) (*FeeManagerWithdraw, error) { + event := new(FeeManagerWithdraw) + if err := _FeeManager.contract.UnpackLog(event, "Withdraw", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_FeeManager *FeeManager) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _FeeManager.abi.Events["DiscountApplied"].ID: + return _FeeManager.ParseDiscountApplied(log) + case _FeeManager.abi.Events["InsufficientLink"].ID: + return _FeeManager.ParseInsufficientLink(log) + case _FeeManager.abi.Events["LinkDeficitCleared"].ID: + return _FeeManager.ParseLinkDeficitCleared(log) + case _FeeManager.abi.Events["NativeSurchargeUpdated"].ID: + return _FeeManager.ParseNativeSurchargeUpdated(log) + case _FeeManager.abi.Events["OwnershipTransferRequested"].ID: + return _FeeManager.ParseOwnershipTransferRequested(log) + case _FeeManager.abi.Events["OwnershipTransferred"].ID: + return _FeeManager.ParseOwnershipTransferred(log) + case _FeeManager.abi.Events["SubscriberDiscountUpdated"].ID: + return _FeeManager.ParseSubscriberDiscountUpdated(log) + case _FeeManager.abi.Events["Withdraw"].ID: + return _FeeManager.ParseWithdraw(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (FeeManagerDiscountApplied) Topic() common.Hash { + return common.HexToHash("0x88b15eb682210089cddf967648e2cb2a4535aeadc8f8f36050922e33c04e7125") +} + +func (FeeManagerInsufficientLink) Topic() common.Hash { + return common.HexToHash("0xf52e5907b69d97c33392936c12d78b494463b78c5b72df50b4c497eee5720b67") +} + +func (FeeManagerLinkDeficitCleared) Topic() common.Hash { + return common.HexToHash("0x843f0b103e50b42b08f9d30f12f961845a6d02623730872e24644899c0dd9895") +} + +func (FeeManagerNativeSurchargeUpdated) Topic() common.Hash { + return common.HexToHash("0x08f7c0d17932ddb8523bc06754d42ff19ebc77d76a8b9bfde02c28ab1ed3d639") +} + +func (FeeManagerOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (FeeManagerOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (FeeManagerSubscriberDiscountUpdated) Topic() common.Hash { + return common.HexToHash("0x5eba5a8afa39780f0f99b6cbeb95f3da6a7040ca00abd46bdc91a0a060134139") +} + +func (FeeManagerWithdraw) Topic() common.Hash { + return common.HexToHash("0x7ff78a71698bdb18dcca96f52ab25e0a1b146fb6a49adf8e6845299e49021f29") +} + +func (_FeeManager *FeeManager) Address() common.Address { + return _FeeManager.address +} + +type FeeManagerInterface interface { + GetFeeAndReward(opts *bind.CallOpts, subscriber common.Address, report []byte, quoteAddress common.Address) (CommonAsset, CommonAsset, *big.Int, error) + + ILinkAddress(opts *bind.CallOpts) (common.Address, error) + + INativeAddress(opts *bind.CallOpts) (common.Address, error) + + IProxyAddress(opts *bind.CallOpts) (common.Address, error) + + IRewardManager(opts *bind.CallOpts) (common.Address, error) + + LinkAvailableForPayment(opts *bind.CallOpts) (*big.Int, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + SGlobalDiscounts(opts *bind.CallOpts, arg0 common.Address, arg1 common.Address) (*big.Int, error) + + SLinkDeficit(opts *bind.CallOpts, arg0 [32]byte) (*big.Int, error) + + SNativeSurcharge(opts *bind.CallOpts) (*big.Int, error) + + SSubscriberDiscounts(opts *bind.CallOpts, arg0 common.Address, arg1 [32]byte, arg2 common.Address) (*big.Int, error) + + SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + PayLinkDeficit(opts *bind.TransactOpts, configDigest [32]byte) (*types.Transaction, error) + + ProcessFee(opts *bind.TransactOpts, payload []byte, parameterPayload []byte, subscriber common.Address) (*types.Transaction, error) + + ProcessFeeBulk(opts *bind.TransactOpts, payloads [][]byte, parameterPayload []byte, subscriber common.Address) (*types.Transaction, error) + + SetFeeRecipients(opts *bind.TransactOpts, configDigest [32]byte, rewardRecipientAndWeights []CommonAddressAndWeight) (*types.Transaction, error) + + SetNativeSurcharge(opts *bind.TransactOpts, surcharge uint64) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + UpdateSubscriberDiscount(opts *bind.TransactOpts, subscriber common.Address, feedId [32]byte, token common.Address, discount uint64) (*types.Transaction, error) + + UpdateSubscriberGlobalDiscount(opts *bind.TransactOpts, subscriber common.Address, token common.Address, discount uint64) (*types.Transaction, error) + + Withdraw(opts *bind.TransactOpts, assetAddress common.Address, recipient common.Address, quantity *big.Int) (*types.Transaction, error) + + FilterDiscountApplied(opts *bind.FilterOpts, configDigest [][32]byte, subscriber []common.Address) (*FeeManagerDiscountAppliedIterator, error) + + WatchDiscountApplied(opts *bind.WatchOpts, sink chan<- *FeeManagerDiscountApplied, configDigest [][32]byte, subscriber []common.Address) (event.Subscription, error) + + ParseDiscountApplied(log types.Log) (*FeeManagerDiscountApplied, error) + + FilterInsufficientLink(opts *bind.FilterOpts) (*FeeManagerInsufficientLinkIterator, error) + + WatchInsufficientLink(opts *bind.WatchOpts, sink chan<- *FeeManagerInsufficientLink) (event.Subscription, error) + + ParseInsufficientLink(log types.Log) (*FeeManagerInsufficientLink, error) + + FilterLinkDeficitCleared(opts *bind.FilterOpts, configDigest [][32]byte) (*FeeManagerLinkDeficitClearedIterator, error) + + WatchLinkDeficitCleared(opts *bind.WatchOpts, sink chan<- *FeeManagerLinkDeficitCleared, configDigest [][32]byte) (event.Subscription, error) + + ParseLinkDeficitCleared(log types.Log) (*FeeManagerLinkDeficitCleared, error) + + FilterNativeSurchargeUpdated(opts *bind.FilterOpts) (*FeeManagerNativeSurchargeUpdatedIterator, error) + + WatchNativeSurchargeUpdated(opts *bind.WatchOpts, sink chan<- *FeeManagerNativeSurchargeUpdated) (event.Subscription, error) + + ParseNativeSurchargeUpdated(log types.Log) (*FeeManagerNativeSurchargeUpdated, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*FeeManagerOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *FeeManagerOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*FeeManagerOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*FeeManagerOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *FeeManagerOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*FeeManagerOwnershipTransferred, error) + + FilterSubscriberDiscountUpdated(opts *bind.FilterOpts, subscriber []common.Address, feedId [][32]byte) (*FeeManagerSubscriberDiscountUpdatedIterator, error) + + WatchSubscriberDiscountUpdated(opts *bind.WatchOpts, sink chan<- *FeeManagerSubscriberDiscountUpdated, subscriber []common.Address, feedId [][32]byte) (event.Subscription, error) + + ParseSubscriberDiscountUpdated(log types.Log) (*FeeManagerSubscriberDiscountUpdated, error) + + FilterWithdraw(opts *bind.FilterOpts) (*FeeManagerWithdrawIterator, error) + + WatchWithdraw(opts *bind.WatchOpts, sink chan<- *FeeManagerWithdraw) (event.Subscription, error) + + ParseWithdraw(log types.Log) (*FeeManagerWithdraw, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/llo-feeds/generated/llo_feeds/llo_feeds.go b/core/gethwrappers/llo-feeds/generated/llo_feeds/llo_feeds.go deleted file mode 100644 index 0cf53356440..00000000000 --- a/core/gethwrappers/llo-feeds/generated/llo_feeds/llo_feeds.go +++ /dev/null @@ -1,1318 +0,0 @@ -// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package llo_feeds - -import ( - "errors" - "fmt" - "math/big" - "strings" - - ethereum "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/event" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" -) - -var ( - _ = errors.New - _ = big.NewInt - _ = strings.NewReader - _ = ethereum.NotFound - _ = bind.Bind - _ = common.Big1 - _ = types.BloomLookup - _ = event.NewSubscription - _ = abi.ConvertType -) - -type CommonAddressAndWeight struct { - Addr common.Address - Weight *big.Int -} - -type CommonAsset struct { - AssetAddress common.Address - Amount *big.Int -} - -type IFeeManagerQuote struct { - QuoteAddress common.Address -} - -var LLOFeeManagerMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_linkAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_nativeAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_proxyAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_rewardManagerAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ExpiredReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDeposit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDiscount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidQuote\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSurcharge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"linkQuantity\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nativeQuantity\",\"type\":\"uint256\"}],\"name\":\"InsufficientLink\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newSurcharge\",\"type\":\"uint256\"}],\"name\":\"NativeSurchargeSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"discount\",\"type\":\"uint256\"}],\"name\":\"SubscriberDiscountUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"adminAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"quantity\",\"type\":\"uint256\"}],\"name\":\"Withdraw\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"quoteAddress\",\"type\":\"address\"}],\"internalType\":\"structIFeeManager.Quote\",\"name\":\"quote\",\"type\":\"tuple\"}],\"name\":\"getFeeAndReward\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structCommon.Asset\",\"name\":\"\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structCommon.Asset\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkAvailableForPayment\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nativeSurcharge\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"}],\"name\":\"processFee\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"weight\",\"type\":\"uint256\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"rewardRecipientAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"setFeeRecipients\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"surcharge\",\"type\":\"uint256\"}],\"name\":\"setNativeSurcharge\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"subscriberDiscounts\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"discount\",\"type\":\"uint256\"}],\"name\":\"updateSubscriberDiscount\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"quantity\",\"type\":\"uint256\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6101006040523480156200001257600080fd5b50604051620024d4380380620024d4833981016040819052620000359162000288565b33806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf81620001c0565b5050506001600160a01b0384161580620000e057506001600160a01b038316155b80620000f357506001600160a01b038216155b806200010657506001600160a01b038116155b15620001255760405163e6c4247b60e01b815260040160405180910390fd5b6001600160a01b03848116608081905284821660a05283821660c05290821660e081905260405163095ea7b360e01b81526004810191909152600019602482015263095ea7b3906044016020604051808303816000875af11580156200018f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001b59190620002e5565b505050505062000310565b336001600160a01b038216036200021a5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b03811681146200028357600080fd5b919050565b600080600080608085870312156200029f57600080fd5b620002aa856200026b565b9350620002ba602086016200026b565b9250620002ca604086016200026b565b9150620002da606086016200026b565b905092959194509250565b600060208284031215620002f857600080fd5b815180151581146200030957600080fd5b9392505050565b60805160a05160c05160e051612128620003ac6000396000818161044c01528181610e5401526110b20152600081816103820152610b1b0152600081816106af015281816107020152818161090f01528181610c6901528181610d3001526112170152600081816106d40152818161075d0152818161089a01528181610a5d01528181610def01528181610fa301526111c001526121286000f3fe6080604052600436106100dd5760003560e01c806393798be71161007f578063f1387e1611610059578063f1387e16146102d6578063f237f1a8146102e9578063f2fde38b14610309578063f3fef3a31461032957600080fd5b806393798be714610255578063c541cbde14610293578063d09dc339146102c157600080fd5b80636b54d8a6116100bb5780636b54d8a6146101c757806379ba5097146101e75780637d75cc49146101fc5780638da5cb5b1461022057600080fd5b806301ffc9a7146100e2578063181f5a771461015957806369fd2b34146101a5575b600080fd5b3480156100ee57600080fd5b506101446100fd36600461167b565b7fffffffff00000000000000000000000000000000000000000000000000000000167ff1387e16000000000000000000000000000000000000000000000000000000001490565b60405190151581526020015b60405180910390f35b34801561016557600080fd5b50604080518082018252601081527f4665654d616e6167657220302e302e31000000000000000000000000000000006020820152905161015091906116c4565b3480156101b157600080fd5b506101c56101c0366004611730565b610349565b005b3480156101d357600080fd5b506101c56101e23660046117af565b6104bc565b3480156101f357600080fd5b506101c5610541565b34801561020857600080fd5b5061021260035481565b604051908152602001610150565b34801561022c57600080fd5b5060005460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610150565b34801561026157600080fd5b506102126102703660046117ea565b600260209081526000938452604080852082529284528284209052825290205481565b34801561029f57600080fd5b506102b36102ae366004611961565b61063e565b604051610150929190611a02565b3480156102cd57600080fd5b50610212610a2c565b6101c56102e4366004611a56565b610ae2565b3480156102f557600080fd5b506101c5610304366004611ace565b611174565b34801561031557600080fd5b506101c5610324366004611b16565b61131b565b34801561033557600080fd5b506101c5610344366004611b33565b61132f565b60005473ffffffffffffffffffffffffffffffffffffffff163314806103a457503373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016145b61040f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f4f6e6c79206f776e6572206f722070726f78790000000000000000000000000060448201526064015b60405180910390fd5b6040517f633b5f6e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063633b5f6e9061048590869086908690600401611b5f565b600060405180830381600087803b15801561049f57600080fd5b505af11580156104b3573d6000803e3d6000fd5b50505050505050565b6104c46114c9565b670de0b6b3a7640000811115610506576040517f05e8ac2900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60038190556040518181527f4fbcc2b7f4cb5518be923bd7c7c887e29e07b001e2a4a0fdd47c494696d8a1479060200160405180910390a150565b60015473ffffffffffffffffffffffffffffffffffffffff1633146105c2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610406565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60408051808201909152600080825260208201526040805180820190915260008082526020820152604080518082019091526000808252602082015260408051808201909152600080825260208201528551610120106107005773ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811683527f00000000000000000000000000000000000000000000000000000000000000001681529092509050610a24565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16856000015173ffffffffffffffffffffffffffffffffffffffff16141580156107b057507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16856000015173ffffffffffffffffffffffffffffffffffffffff1614155b156107e7576040517ff861803000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806000888060200190518101906108009190611c39565b63ffffffff169b5077ffffffffffffffffffffffffffffffffffffffffffffffff169b5077ffffffffffffffffffffffffffffffffffffffffffffffff169b5050505050505050505042811015610883576040517fb6c405f500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116808652602086018590528951909116036108f857835173ffffffffffffffffffffffffffffffffffffffff16855260208085015190860152610968565b73ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001685526003546109629061094a90670de0b6b3a7640000611d36565b6109549084611d49565b670de0b6b3a764000061154c565b60208601525b60006109738a611d86565b73ffffffffffffffffffffffffffffffffffffffff808d16600090815260026020908152604080832085845282528083208e519094168352928152919020549088015191925090670de0b6b3a7640000906109cf908390611d49565b6109d99190611dcb565b87602001516109e89190611e06565b876020018181525050610a048187602001516109549190611d49565b8660200151610a139190611e06565b602087015250949650929450505050505b935093915050565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015610ab9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610add9190611e19565b905090565b60005473ffffffffffffffffffffffffffffffffffffffff16331480610b3d57503373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016145b610ba3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f4f6e6c79206f776e6572206f722070726f7879000000000000000000000000006044820152606401610406565b3073ffffffffffffffffffffffffffffffffffffffff821603610bf2576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610c0083850185611ea0565b604080516020810190915260008152909250905081516101201015610c4c576000610c2d85870187611f6f565b9550505050505080806020019051810190610c489190612037565b9150505b600080610c5a33858561063e565b909250905060003415610dbd577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff1614610cf0576040517fb2e532de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3483602001511115610d2e576040517fb2e532de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db084602001516040518263ffffffff1660e01b81526004016000604051808303818588803b158015610d9a57600080fd5b505af1158015610dae573d6000803e3d6000fd5b50505050508260200151340390505b6000610dc9888a612065565b60208501519091501561111e57835173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116911603610ec4576040517f84afb76e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906384afb76e90610e8d9084908b9088906004016120a1565b600060405180830381600087803b158015610ea757600080fd5b505af1158015610ebb573d6000803e3d6000fd5b5050505061111e565b34600003610f7557835160208501516040517f23b872dd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a8116600483015230602483015260448201929092529116906323b872dd906064016020604051808303816000875af1158015610f4f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f7391906120f9565b505b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015610fff573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110239190611e19565b836020015111156110755760208084015185820151604080519283529282015282917feb6f22018570d97db6df12dc94f202b4e2b2888a6a5d4bd179422c91b29dcdf7910160405180910390a261111e565b6040517f84afb76e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906384afb76e906110eb908490309088906004016120a1565b600060405180830381600087803b15801561110557600080fd5b505af1158015611119573d6000803e3d6000fd5b505050505b81156111695760405173ffffffffffffffffffffffffffffffffffffffff88169083156108fc029084906000818181858888f19350505050158015611167573d6000803e3d6000fd5b505b505050505050505050565b61117c6114c9565b670de0b6b3a76400008111156111be576040517f997ea36000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415801561126657507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b1561129d576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff84811660008181526002602090815260408083208884528252808320948716808452948252918290208590558151938452830184905285927f41eb9ccd292d5906dc1f0ec108bed3e2b966e3071e033df938f7215f6d30ca84910160405180910390a350505050565b6113236114c9565b61132c81611586565b50565b6113376114c9565b73ffffffffffffffffffffffffffffffffffffffff821661139d576000805460405173ffffffffffffffffffffffffffffffffffffffff9091169183156108fc02918491818181858888f19350505050158015611398573d6000803e3d6000fd5b505050565b8173ffffffffffffffffffffffffffffffffffffffff1663a9059cbb6113d860005473ffffffffffffffffffffffffffffffffffffffff1690565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602481018490526044016020604051808303816000875af115801561144a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061146e91906120f9565b506040805133815273ffffffffffffffffffffffffffffffffffffffff841660208201529081018290527f9b1bfa7fa9ee420a16e124f794c35ac9f90472acc99140eb2f6447c714cad8eb9060600160405180910390a15050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461154a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610406565b565b6000821561157a5781611560600185611e06565b61156a9190611dcb565b611575906001611d36565b61157d565b60005b90505b92915050565b3373ffffffffffffffffffffffffffffffffffffffff821603611605576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610406565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60006020828403121561168d57600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146116bd57600080fd5b9392505050565b600060208083528351808285015260005b818110156116f1578581018301518582016040015282016116d5565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b60008060006040848603121561174557600080fd5b83359250602084013567ffffffffffffffff8082111561176457600080fd5b818601915086601f83011261177857600080fd5b81358181111561178757600080fd5b8760208260061b850101111561179c57600080fd5b6020830194508093505050509250925092565b6000602082840312156117c157600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461132c57600080fd5b6000806000606084860312156117ff57600080fd5b833561180a816117c8565b9250602084013591506040840135611821816117c8565b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516020810167ffffffffffffffff8111828210171561187e5761187e61182c565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156118cb576118cb61182c565b604052919050565b600082601f8301126118e457600080fd5b813567ffffffffffffffff8111156118fe576118fe61182c565b61192f60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611884565b81815284602083860101111561194457600080fd5b816020850160208301376000918101602001919091529392505050565b6000806000838503606081121561197757600080fd5b8435611982816117c8565b9350602085013567ffffffffffffffff81111561199e57600080fd5b6119aa878288016118d3565b93505060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0820112156119dd57600080fd5b506119e661185b565b60408501356119f4816117c8565b815292959194509192509050565b825173ffffffffffffffffffffffffffffffffffffffff1681526020808401519082015260808101825173ffffffffffffffffffffffffffffffffffffffff166040830152602083015160608301526116bd565b600080600060408486031215611a6b57600080fd5b833567ffffffffffffffff80821115611a8357600080fd5b818601915086601f830112611a9757600080fd5b813581811115611aa657600080fd5b876020828501011115611ab857600080fd5b60209283019550935050840135611821816117c8565b60008060008060808587031215611ae457600080fd5b8435611aef816117c8565b9350602085013592506040850135611b06816117c8565b9396929550929360600135925050565b600060208284031215611b2857600080fd5b81356116bd816117c8565b60008060408385031215611b4657600080fd5b8235611b51816117c8565b946020939093013593505050565b8381526040602080830182905282820184905260009190859060608501845b87811015611bc1578335611b91816117c8565b73ffffffffffffffffffffffffffffffffffffffff16825283830135838301529284019290840190600101611b7e565b5098975050505050505050565b805163ffffffff81168114611be257600080fd5b919050565b8051601781900b8114611be257600080fd5b805167ffffffffffffffff81168114611be257600080fd5b805177ffffffffffffffffffffffffffffffffffffffffffffffff81168114611be257600080fd5b6000806000806000806000806000806000806101808d8f031215611c5c57600080fd5b8c519b50611c6c60208e01611bce565b9a50611c7a60408e01611be7565b9950611c8860608e01611be7565b9850611c9660808e01611be7565b9750611ca460a08e01611bf9565b965060c08d01519550611cb960e08e01611bf9565b9450611cc86101008e01611bf9565b9350611cd76101208e01611c11565b9250611ce66101408e01611c11565b9150611cf56101608e01611bce565b90509295989b509295989b509295989b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561158057611580611d07565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615611d8157611d81611d07565b500290565b80516020808301519190811015611dc5577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b600082611e01577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b8181038181111561158057611580611d07565b600060208284031215611e2b57600080fd5b5051919050565b600082601f830112611e4357600080fd5b6040516060810181811067ffffffffffffffff82111715611e6657611e6661182c565b604052806060840185811115611e7b57600080fd5b845b81811015611e95578035835260209283019201611e7d565b509195945050505050565b60008060808385031215611eb357600080fd5b611ebd8484611e32565b9150606083013567ffffffffffffffff811115611ed957600080fd5b611ee5858286016118d3565b9150509250929050565b600082601f830112611f0057600080fd5b8135602067ffffffffffffffff821115611f1c57611f1c61182c565b8160051b611f2b828201611884565b9283528481018201928281019087851115611f4557600080fd5b83870192505b84831015611f6457823582529183019190830190611f4b565b979650505050505050565b6000806000806000806101008789031215611f8957600080fd5b611f938888611e32565b9550606087013567ffffffffffffffff80821115611fb057600080fd5b611fbc8a838b016118d3565b96506080890135915080821115611fd257600080fd5b611fde8a838b01611eef565b955060a0890135915080821115611ff457600080fd5b6120008a838b01611eef565b945060c0890135935060e089013591508082111561201d57600080fd5b5061202a89828a016118d3565b9150509295509295509295565b60006020828403121561204957600080fd5b61205161185b565b825161205c816117c8565b81529392505050565b80356020831015611580577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff602084900360031b1b1692915050565b83815273ffffffffffffffffffffffffffffffffffffffff83166020820152608081016120f16040830184805173ffffffffffffffffffffffffffffffffffffffff168252602090810151910152565b949350505050565b60006020828403121561210b57600080fd5b815180151581146116bd57600080fdfea164736f6c6343000810000a", -} - -var LLOFeeManagerABI = LLOFeeManagerMetaData.ABI - -var LLOFeeManagerBin = LLOFeeManagerMetaData.Bin - -func DeployLLOFeeManager(auth *bind.TransactOpts, backend bind.ContractBackend, _linkAddress common.Address, _nativeAddress common.Address, _proxyAddress common.Address, _rewardManagerAddress common.Address) (common.Address, *types.Transaction, *LLOFeeManager, error) { - parsed, err := LLOFeeManagerMetaData.GetAbi() - if err != nil { - return common.Address{}, nil, nil, err - } - if parsed == nil { - return common.Address{}, nil, nil, errors.New("GetABI returned nil") - } - - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(LLOFeeManagerBin), backend, _linkAddress, _nativeAddress, _proxyAddress, _rewardManagerAddress) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &LLOFeeManager{LLOFeeManagerCaller: LLOFeeManagerCaller{contract: contract}, LLOFeeManagerTransactor: LLOFeeManagerTransactor{contract: contract}, LLOFeeManagerFilterer: LLOFeeManagerFilterer{contract: contract}}, nil -} - -type LLOFeeManager struct { - address common.Address - abi abi.ABI - LLOFeeManagerCaller - LLOFeeManagerTransactor - LLOFeeManagerFilterer -} - -type LLOFeeManagerCaller struct { - contract *bind.BoundContract -} - -type LLOFeeManagerTransactor struct { - contract *bind.BoundContract -} - -type LLOFeeManagerFilterer struct { - contract *bind.BoundContract -} - -type LLOFeeManagerSession struct { - Contract *LLOFeeManager - CallOpts bind.CallOpts - TransactOpts bind.TransactOpts -} - -type LLOFeeManagerCallerSession struct { - Contract *LLOFeeManagerCaller - CallOpts bind.CallOpts -} - -type LLOFeeManagerTransactorSession struct { - Contract *LLOFeeManagerTransactor - TransactOpts bind.TransactOpts -} - -type LLOFeeManagerRaw struct { - Contract *LLOFeeManager -} - -type LLOFeeManagerCallerRaw struct { - Contract *LLOFeeManagerCaller -} - -type LLOFeeManagerTransactorRaw struct { - Contract *LLOFeeManagerTransactor -} - -func NewLLOFeeManager(address common.Address, backend bind.ContractBackend) (*LLOFeeManager, error) { - abi, err := abi.JSON(strings.NewReader(LLOFeeManagerABI)) - if err != nil { - return nil, err - } - contract, err := bindLLOFeeManager(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &LLOFeeManager{address: address, abi: abi, LLOFeeManagerCaller: LLOFeeManagerCaller{contract: contract}, LLOFeeManagerTransactor: LLOFeeManagerTransactor{contract: contract}, LLOFeeManagerFilterer: LLOFeeManagerFilterer{contract: contract}}, nil -} - -func NewLLOFeeManagerCaller(address common.Address, caller bind.ContractCaller) (*LLOFeeManagerCaller, error) { - contract, err := bindLLOFeeManager(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &LLOFeeManagerCaller{contract: contract}, nil -} - -func NewLLOFeeManagerTransactor(address common.Address, transactor bind.ContractTransactor) (*LLOFeeManagerTransactor, error) { - contract, err := bindLLOFeeManager(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &LLOFeeManagerTransactor{contract: contract}, nil -} - -func NewLLOFeeManagerFilterer(address common.Address, filterer bind.ContractFilterer) (*LLOFeeManagerFilterer, error) { - contract, err := bindLLOFeeManager(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &LLOFeeManagerFilterer{contract: contract}, nil -} - -func bindLLOFeeManager(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := LLOFeeManagerMetaData.GetAbi() - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil -} - -func (_LLOFeeManager *LLOFeeManagerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _LLOFeeManager.Contract.LLOFeeManagerCaller.contract.Call(opts, result, method, params...) -} - -func (_LLOFeeManager *LLOFeeManagerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _LLOFeeManager.Contract.LLOFeeManagerTransactor.contract.Transfer(opts) -} - -func (_LLOFeeManager *LLOFeeManagerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _LLOFeeManager.Contract.LLOFeeManagerTransactor.contract.Transact(opts, method, params...) -} - -func (_LLOFeeManager *LLOFeeManagerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _LLOFeeManager.Contract.contract.Call(opts, result, method, params...) -} - -func (_LLOFeeManager *LLOFeeManagerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _LLOFeeManager.Contract.contract.Transfer(opts) -} - -func (_LLOFeeManager *LLOFeeManagerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _LLOFeeManager.Contract.contract.Transact(opts, method, params...) -} - -func (_LLOFeeManager *LLOFeeManagerCaller) GetFeeAndReward(opts *bind.CallOpts, subscriber common.Address, report []byte, quote IFeeManagerQuote) (CommonAsset, CommonAsset, error) { - var out []interface{} - err := _LLOFeeManager.contract.Call(opts, &out, "getFeeAndReward", subscriber, report, quote) - - if err != nil { - return *new(CommonAsset), *new(CommonAsset), err - } - - out0 := *abi.ConvertType(out[0], new(CommonAsset)).(*CommonAsset) - out1 := *abi.ConvertType(out[1], new(CommonAsset)).(*CommonAsset) - - return out0, out1, err - -} - -func (_LLOFeeManager *LLOFeeManagerSession) GetFeeAndReward(subscriber common.Address, report []byte, quote IFeeManagerQuote) (CommonAsset, CommonAsset, error) { - return _LLOFeeManager.Contract.GetFeeAndReward(&_LLOFeeManager.CallOpts, subscriber, report, quote) -} - -func (_LLOFeeManager *LLOFeeManagerCallerSession) GetFeeAndReward(subscriber common.Address, report []byte, quote IFeeManagerQuote) (CommonAsset, CommonAsset, error) { - return _LLOFeeManager.Contract.GetFeeAndReward(&_LLOFeeManager.CallOpts, subscriber, report, quote) -} - -func (_LLOFeeManager *LLOFeeManagerCaller) LinkAvailableForPayment(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _LLOFeeManager.contract.Call(opts, &out, "linkAvailableForPayment") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -func (_LLOFeeManager *LLOFeeManagerSession) LinkAvailableForPayment() (*big.Int, error) { - return _LLOFeeManager.Contract.LinkAvailableForPayment(&_LLOFeeManager.CallOpts) -} - -func (_LLOFeeManager *LLOFeeManagerCallerSession) LinkAvailableForPayment() (*big.Int, error) { - return _LLOFeeManager.Contract.LinkAvailableForPayment(&_LLOFeeManager.CallOpts) -} - -func (_LLOFeeManager *LLOFeeManagerCaller) NativeSurcharge(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _LLOFeeManager.contract.Call(opts, &out, "nativeSurcharge") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -func (_LLOFeeManager *LLOFeeManagerSession) NativeSurcharge() (*big.Int, error) { - return _LLOFeeManager.Contract.NativeSurcharge(&_LLOFeeManager.CallOpts) -} - -func (_LLOFeeManager *LLOFeeManagerCallerSession) NativeSurcharge() (*big.Int, error) { - return _LLOFeeManager.Contract.NativeSurcharge(&_LLOFeeManager.CallOpts) -} - -func (_LLOFeeManager *LLOFeeManagerCaller) Owner(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _LLOFeeManager.contract.Call(opts, &out, "owner") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -func (_LLOFeeManager *LLOFeeManagerSession) Owner() (common.Address, error) { - return _LLOFeeManager.Contract.Owner(&_LLOFeeManager.CallOpts) -} - -func (_LLOFeeManager *LLOFeeManagerCallerSession) Owner() (common.Address, error) { - return _LLOFeeManager.Contract.Owner(&_LLOFeeManager.CallOpts) -} - -func (_LLOFeeManager *LLOFeeManagerCaller) SubscriberDiscounts(opts *bind.CallOpts, arg0 common.Address, arg1 [32]byte, arg2 common.Address) (*big.Int, error) { - var out []interface{} - err := _LLOFeeManager.contract.Call(opts, &out, "subscriberDiscounts", arg0, arg1, arg2) - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -func (_LLOFeeManager *LLOFeeManagerSession) SubscriberDiscounts(arg0 common.Address, arg1 [32]byte, arg2 common.Address) (*big.Int, error) { - return _LLOFeeManager.Contract.SubscriberDiscounts(&_LLOFeeManager.CallOpts, arg0, arg1, arg2) -} - -func (_LLOFeeManager *LLOFeeManagerCallerSession) SubscriberDiscounts(arg0 common.Address, arg1 [32]byte, arg2 common.Address) (*big.Int, error) { - return _LLOFeeManager.Contract.SubscriberDiscounts(&_LLOFeeManager.CallOpts, arg0, arg1, arg2) -} - -func (_LLOFeeManager *LLOFeeManagerCaller) SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) { - var out []interface{} - err := _LLOFeeManager.contract.Call(opts, &out, "supportsInterface", interfaceId) - - if err != nil { - return *new(bool), err - } - - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) - - return out0, err - -} - -func (_LLOFeeManager *LLOFeeManagerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { - return _LLOFeeManager.Contract.SupportsInterface(&_LLOFeeManager.CallOpts, interfaceId) -} - -func (_LLOFeeManager *LLOFeeManagerCallerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { - return _LLOFeeManager.Contract.SupportsInterface(&_LLOFeeManager.CallOpts, interfaceId) -} - -func (_LLOFeeManager *LLOFeeManagerCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { - var out []interface{} - err := _LLOFeeManager.contract.Call(opts, &out, "typeAndVersion") - - if err != nil { - return *new(string), err - } - - out0 := *abi.ConvertType(out[0], new(string)).(*string) - - return out0, err - -} - -func (_LLOFeeManager *LLOFeeManagerSession) TypeAndVersion() (string, error) { - return _LLOFeeManager.Contract.TypeAndVersion(&_LLOFeeManager.CallOpts) -} - -func (_LLOFeeManager *LLOFeeManagerCallerSession) TypeAndVersion() (string, error) { - return _LLOFeeManager.Contract.TypeAndVersion(&_LLOFeeManager.CallOpts) -} - -func (_LLOFeeManager *LLOFeeManagerTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { - return _LLOFeeManager.contract.Transact(opts, "acceptOwnership") -} - -func (_LLOFeeManager *LLOFeeManagerSession) AcceptOwnership() (*types.Transaction, error) { - return _LLOFeeManager.Contract.AcceptOwnership(&_LLOFeeManager.TransactOpts) -} - -func (_LLOFeeManager *LLOFeeManagerTransactorSession) AcceptOwnership() (*types.Transaction, error) { - return _LLOFeeManager.Contract.AcceptOwnership(&_LLOFeeManager.TransactOpts) -} - -func (_LLOFeeManager *LLOFeeManagerTransactor) ProcessFee(opts *bind.TransactOpts, payload []byte, subscriber common.Address) (*types.Transaction, error) { - return _LLOFeeManager.contract.Transact(opts, "processFee", payload, subscriber) -} - -func (_LLOFeeManager *LLOFeeManagerSession) ProcessFee(payload []byte, subscriber common.Address) (*types.Transaction, error) { - return _LLOFeeManager.Contract.ProcessFee(&_LLOFeeManager.TransactOpts, payload, subscriber) -} - -func (_LLOFeeManager *LLOFeeManagerTransactorSession) ProcessFee(payload []byte, subscriber common.Address) (*types.Transaction, error) { - return _LLOFeeManager.Contract.ProcessFee(&_LLOFeeManager.TransactOpts, payload, subscriber) -} - -func (_LLOFeeManager *LLOFeeManagerTransactor) SetFeeRecipients(opts *bind.TransactOpts, configDigest [32]byte, rewardRecipientAndWeights []CommonAddressAndWeight) (*types.Transaction, error) { - return _LLOFeeManager.contract.Transact(opts, "setFeeRecipients", configDigest, rewardRecipientAndWeights) -} - -func (_LLOFeeManager *LLOFeeManagerSession) SetFeeRecipients(configDigest [32]byte, rewardRecipientAndWeights []CommonAddressAndWeight) (*types.Transaction, error) { - return _LLOFeeManager.Contract.SetFeeRecipients(&_LLOFeeManager.TransactOpts, configDigest, rewardRecipientAndWeights) -} - -func (_LLOFeeManager *LLOFeeManagerTransactorSession) SetFeeRecipients(configDigest [32]byte, rewardRecipientAndWeights []CommonAddressAndWeight) (*types.Transaction, error) { - return _LLOFeeManager.Contract.SetFeeRecipients(&_LLOFeeManager.TransactOpts, configDigest, rewardRecipientAndWeights) -} - -func (_LLOFeeManager *LLOFeeManagerTransactor) SetNativeSurcharge(opts *bind.TransactOpts, surcharge *big.Int) (*types.Transaction, error) { - return _LLOFeeManager.contract.Transact(opts, "setNativeSurcharge", surcharge) -} - -func (_LLOFeeManager *LLOFeeManagerSession) SetNativeSurcharge(surcharge *big.Int) (*types.Transaction, error) { - return _LLOFeeManager.Contract.SetNativeSurcharge(&_LLOFeeManager.TransactOpts, surcharge) -} - -func (_LLOFeeManager *LLOFeeManagerTransactorSession) SetNativeSurcharge(surcharge *big.Int) (*types.Transaction, error) { - return _LLOFeeManager.Contract.SetNativeSurcharge(&_LLOFeeManager.TransactOpts, surcharge) -} - -func (_LLOFeeManager *LLOFeeManagerTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { - return _LLOFeeManager.contract.Transact(opts, "transferOwnership", to) -} - -func (_LLOFeeManager *LLOFeeManagerSession) TransferOwnership(to common.Address) (*types.Transaction, error) { - return _LLOFeeManager.Contract.TransferOwnership(&_LLOFeeManager.TransactOpts, to) -} - -func (_LLOFeeManager *LLOFeeManagerTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { - return _LLOFeeManager.Contract.TransferOwnership(&_LLOFeeManager.TransactOpts, to) -} - -func (_LLOFeeManager *LLOFeeManagerTransactor) UpdateSubscriberDiscount(opts *bind.TransactOpts, subscriber common.Address, feedId [32]byte, token common.Address, discount *big.Int) (*types.Transaction, error) { - return _LLOFeeManager.contract.Transact(opts, "updateSubscriberDiscount", subscriber, feedId, token, discount) -} - -func (_LLOFeeManager *LLOFeeManagerSession) UpdateSubscriberDiscount(subscriber common.Address, feedId [32]byte, token common.Address, discount *big.Int) (*types.Transaction, error) { - return _LLOFeeManager.Contract.UpdateSubscriberDiscount(&_LLOFeeManager.TransactOpts, subscriber, feedId, token, discount) -} - -func (_LLOFeeManager *LLOFeeManagerTransactorSession) UpdateSubscriberDiscount(subscriber common.Address, feedId [32]byte, token common.Address, discount *big.Int) (*types.Transaction, error) { - return _LLOFeeManager.Contract.UpdateSubscriberDiscount(&_LLOFeeManager.TransactOpts, subscriber, feedId, token, discount) -} - -func (_LLOFeeManager *LLOFeeManagerTransactor) Withdraw(opts *bind.TransactOpts, assetAddress common.Address, quantity *big.Int) (*types.Transaction, error) { - return _LLOFeeManager.contract.Transact(opts, "withdraw", assetAddress, quantity) -} - -func (_LLOFeeManager *LLOFeeManagerSession) Withdraw(assetAddress common.Address, quantity *big.Int) (*types.Transaction, error) { - return _LLOFeeManager.Contract.Withdraw(&_LLOFeeManager.TransactOpts, assetAddress, quantity) -} - -func (_LLOFeeManager *LLOFeeManagerTransactorSession) Withdraw(assetAddress common.Address, quantity *big.Int) (*types.Transaction, error) { - return _LLOFeeManager.Contract.Withdraw(&_LLOFeeManager.TransactOpts, assetAddress, quantity) -} - -type LLOFeeManagerInsufficientLinkIterator struct { - Event *LLOFeeManagerInsufficientLink - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *LLOFeeManagerInsufficientLinkIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(LLOFeeManagerInsufficientLink) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - - select { - case log := <-it.logs: - it.Event = new(LLOFeeManagerInsufficientLink) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -func (it *LLOFeeManagerInsufficientLinkIterator) Error() error { - return it.fail -} - -func (it *LLOFeeManagerInsufficientLinkIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type LLOFeeManagerInsufficientLink struct { - ConfigDigest [32]byte - LinkQuantity *big.Int - NativeQuantity *big.Int - Raw types.Log -} - -func (_LLOFeeManager *LLOFeeManagerFilterer) FilterInsufficientLink(opts *bind.FilterOpts, configDigest [][32]byte) (*LLOFeeManagerInsufficientLinkIterator, error) { - - var configDigestRule []interface{} - for _, configDigestItem := range configDigest { - configDigestRule = append(configDigestRule, configDigestItem) - } - - logs, sub, err := _LLOFeeManager.contract.FilterLogs(opts, "InsufficientLink", configDigestRule) - if err != nil { - return nil, err - } - return &LLOFeeManagerInsufficientLinkIterator{contract: _LLOFeeManager.contract, event: "InsufficientLink", logs: logs, sub: sub}, nil -} - -func (_LLOFeeManager *LLOFeeManagerFilterer) WatchInsufficientLink(opts *bind.WatchOpts, sink chan<- *LLOFeeManagerInsufficientLink, configDigest [][32]byte) (event.Subscription, error) { - - var configDigestRule []interface{} - for _, configDigestItem := range configDigest { - configDigestRule = append(configDigestRule, configDigestItem) - } - - logs, sub, err := _LLOFeeManager.contract.WatchLogs(opts, "InsufficientLink", configDigestRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(LLOFeeManagerInsufficientLink) - if err := _LLOFeeManager.contract.UnpackLog(event, "InsufficientLink", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -func (_LLOFeeManager *LLOFeeManagerFilterer) ParseInsufficientLink(log types.Log) (*LLOFeeManagerInsufficientLink, error) { - event := new(LLOFeeManagerInsufficientLink) - if err := _LLOFeeManager.contract.UnpackLog(event, "InsufficientLink", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type LLOFeeManagerNativeSurchargeSetIterator struct { - Event *LLOFeeManagerNativeSurchargeSet - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *LLOFeeManagerNativeSurchargeSetIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(LLOFeeManagerNativeSurchargeSet) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - - select { - case log := <-it.logs: - it.Event = new(LLOFeeManagerNativeSurchargeSet) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -func (it *LLOFeeManagerNativeSurchargeSetIterator) Error() error { - return it.fail -} - -func (it *LLOFeeManagerNativeSurchargeSetIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type LLOFeeManagerNativeSurchargeSet struct { - NewSurcharge *big.Int - Raw types.Log -} - -func (_LLOFeeManager *LLOFeeManagerFilterer) FilterNativeSurchargeSet(opts *bind.FilterOpts) (*LLOFeeManagerNativeSurchargeSetIterator, error) { - - logs, sub, err := _LLOFeeManager.contract.FilterLogs(opts, "NativeSurchargeSet") - if err != nil { - return nil, err - } - return &LLOFeeManagerNativeSurchargeSetIterator{contract: _LLOFeeManager.contract, event: "NativeSurchargeSet", logs: logs, sub: sub}, nil -} - -func (_LLOFeeManager *LLOFeeManagerFilterer) WatchNativeSurchargeSet(opts *bind.WatchOpts, sink chan<- *LLOFeeManagerNativeSurchargeSet) (event.Subscription, error) { - - logs, sub, err := _LLOFeeManager.contract.WatchLogs(opts, "NativeSurchargeSet") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(LLOFeeManagerNativeSurchargeSet) - if err := _LLOFeeManager.contract.UnpackLog(event, "NativeSurchargeSet", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -func (_LLOFeeManager *LLOFeeManagerFilterer) ParseNativeSurchargeSet(log types.Log) (*LLOFeeManagerNativeSurchargeSet, error) { - event := new(LLOFeeManagerNativeSurchargeSet) - if err := _LLOFeeManager.contract.UnpackLog(event, "NativeSurchargeSet", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type LLOFeeManagerOwnershipTransferRequestedIterator struct { - Event *LLOFeeManagerOwnershipTransferRequested - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *LLOFeeManagerOwnershipTransferRequestedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(LLOFeeManagerOwnershipTransferRequested) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - - select { - case log := <-it.logs: - it.Event = new(LLOFeeManagerOwnershipTransferRequested) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -func (it *LLOFeeManagerOwnershipTransferRequestedIterator) Error() error { - return it.fail -} - -func (it *LLOFeeManagerOwnershipTransferRequestedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type LLOFeeManagerOwnershipTransferRequested struct { - From common.Address - To common.Address - Raw types.Log -} - -func (_LLOFeeManager *LLOFeeManagerFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*LLOFeeManagerOwnershipTransferRequestedIterator, error) { - - var fromRule []interface{} - for _, fromItem := range from { - fromRule = append(fromRule, fromItem) - } - var toRule []interface{} - for _, toItem := range to { - toRule = append(toRule, toItem) - } - - logs, sub, err := _LLOFeeManager.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) - if err != nil { - return nil, err - } - return &LLOFeeManagerOwnershipTransferRequestedIterator{contract: _LLOFeeManager.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil -} - -func (_LLOFeeManager *LLOFeeManagerFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *LLOFeeManagerOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { - - var fromRule []interface{} - for _, fromItem := range from { - fromRule = append(fromRule, fromItem) - } - var toRule []interface{} - for _, toItem := range to { - toRule = append(toRule, toItem) - } - - logs, sub, err := _LLOFeeManager.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(LLOFeeManagerOwnershipTransferRequested) - if err := _LLOFeeManager.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -func (_LLOFeeManager *LLOFeeManagerFilterer) ParseOwnershipTransferRequested(log types.Log) (*LLOFeeManagerOwnershipTransferRequested, error) { - event := new(LLOFeeManagerOwnershipTransferRequested) - if err := _LLOFeeManager.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type LLOFeeManagerOwnershipTransferredIterator struct { - Event *LLOFeeManagerOwnershipTransferred - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *LLOFeeManagerOwnershipTransferredIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(LLOFeeManagerOwnershipTransferred) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - - select { - case log := <-it.logs: - it.Event = new(LLOFeeManagerOwnershipTransferred) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -func (it *LLOFeeManagerOwnershipTransferredIterator) Error() error { - return it.fail -} - -func (it *LLOFeeManagerOwnershipTransferredIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type LLOFeeManagerOwnershipTransferred struct { - From common.Address - To common.Address - Raw types.Log -} - -func (_LLOFeeManager *LLOFeeManagerFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*LLOFeeManagerOwnershipTransferredIterator, error) { - - var fromRule []interface{} - for _, fromItem := range from { - fromRule = append(fromRule, fromItem) - } - var toRule []interface{} - for _, toItem := range to { - toRule = append(toRule, toItem) - } - - logs, sub, err := _LLOFeeManager.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) - if err != nil { - return nil, err - } - return &LLOFeeManagerOwnershipTransferredIterator{contract: _LLOFeeManager.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil -} - -func (_LLOFeeManager *LLOFeeManagerFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *LLOFeeManagerOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { - - var fromRule []interface{} - for _, fromItem := range from { - fromRule = append(fromRule, fromItem) - } - var toRule []interface{} - for _, toItem := range to { - toRule = append(toRule, toItem) - } - - logs, sub, err := _LLOFeeManager.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(LLOFeeManagerOwnershipTransferred) - if err := _LLOFeeManager.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -func (_LLOFeeManager *LLOFeeManagerFilterer) ParseOwnershipTransferred(log types.Log) (*LLOFeeManagerOwnershipTransferred, error) { - event := new(LLOFeeManagerOwnershipTransferred) - if err := _LLOFeeManager.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type LLOFeeManagerSubscriberDiscountUpdatedIterator struct { - Event *LLOFeeManagerSubscriberDiscountUpdated - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *LLOFeeManagerSubscriberDiscountUpdatedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(LLOFeeManagerSubscriberDiscountUpdated) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - - select { - case log := <-it.logs: - it.Event = new(LLOFeeManagerSubscriberDiscountUpdated) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -func (it *LLOFeeManagerSubscriberDiscountUpdatedIterator) Error() error { - return it.fail -} - -func (it *LLOFeeManagerSubscriberDiscountUpdatedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type LLOFeeManagerSubscriberDiscountUpdated struct { - Subscriber common.Address - FeedId [32]byte - Token common.Address - Discount *big.Int - Raw types.Log -} - -func (_LLOFeeManager *LLOFeeManagerFilterer) FilterSubscriberDiscountUpdated(opts *bind.FilterOpts, subscriber []common.Address, feedId [][32]byte) (*LLOFeeManagerSubscriberDiscountUpdatedIterator, error) { - - var subscriberRule []interface{} - for _, subscriberItem := range subscriber { - subscriberRule = append(subscriberRule, subscriberItem) - } - var feedIdRule []interface{} - for _, feedIdItem := range feedId { - feedIdRule = append(feedIdRule, feedIdItem) - } - - logs, sub, err := _LLOFeeManager.contract.FilterLogs(opts, "SubscriberDiscountUpdated", subscriberRule, feedIdRule) - if err != nil { - return nil, err - } - return &LLOFeeManagerSubscriberDiscountUpdatedIterator{contract: _LLOFeeManager.contract, event: "SubscriberDiscountUpdated", logs: logs, sub: sub}, nil -} - -func (_LLOFeeManager *LLOFeeManagerFilterer) WatchSubscriberDiscountUpdated(opts *bind.WatchOpts, sink chan<- *LLOFeeManagerSubscriberDiscountUpdated, subscriber []common.Address, feedId [][32]byte) (event.Subscription, error) { - - var subscriberRule []interface{} - for _, subscriberItem := range subscriber { - subscriberRule = append(subscriberRule, subscriberItem) - } - var feedIdRule []interface{} - for _, feedIdItem := range feedId { - feedIdRule = append(feedIdRule, feedIdItem) - } - - logs, sub, err := _LLOFeeManager.contract.WatchLogs(opts, "SubscriberDiscountUpdated", subscriberRule, feedIdRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(LLOFeeManagerSubscriberDiscountUpdated) - if err := _LLOFeeManager.contract.UnpackLog(event, "SubscriberDiscountUpdated", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -func (_LLOFeeManager *LLOFeeManagerFilterer) ParseSubscriberDiscountUpdated(log types.Log) (*LLOFeeManagerSubscriberDiscountUpdated, error) { - event := new(LLOFeeManagerSubscriberDiscountUpdated) - if err := _LLOFeeManager.contract.UnpackLog(event, "SubscriberDiscountUpdated", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type LLOFeeManagerWithdrawIterator struct { - Event *LLOFeeManagerWithdraw - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *LLOFeeManagerWithdrawIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(LLOFeeManagerWithdraw) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - - select { - case log := <-it.logs: - it.Event = new(LLOFeeManagerWithdraw) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -func (it *LLOFeeManagerWithdrawIterator) Error() error { - return it.fail -} - -func (it *LLOFeeManagerWithdrawIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type LLOFeeManagerWithdraw struct { - AdminAddress common.Address - AssetAddress common.Address - Quantity *big.Int - Raw types.Log -} - -func (_LLOFeeManager *LLOFeeManagerFilterer) FilterWithdraw(opts *bind.FilterOpts) (*LLOFeeManagerWithdrawIterator, error) { - - logs, sub, err := _LLOFeeManager.contract.FilterLogs(opts, "Withdraw") - if err != nil { - return nil, err - } - return &LLOFeeManagerWithdrawIterator{contract: _LLOFeeManager.contract, event: "Withdraw", logs: logs, sub: sub}, nil -} - -func (_LLOFeeManager *LLOFeeManagerFilterer) WatchWithdraw(opts *bind.WatchOpts, sink chan<- *LLOFeeManagerWithdraw) (event.Subscription, error) { - - logs, sub, err := _LLOFeeManager.contract.WatchLogs(opts, "Withdraw") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(LLOFeeManagerWithdraw) - if err := _LLOFeeManager.contract.UnpackLog(event, "Withdraw", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -func (_LLOFeeManager *LLOFeeManagerFilterer) ParseWithdraw(log types.Log) (*LLOFeeManagerWithdraw, error) { - event := new(LLOFeeManagerWithdraw) - if err := _LLOFeeManager.contract.UnpackLog(event, "Withdraw", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -func (_LLOFeeManager *LLOFeeManager) ParseLog(log types.Log) (generated.AbigenLog, error) { - switch log.Topics[0] { - case _LLOFeeManager.abi.Events["InsufficientLink"].ID: - return _LLOFeeManager.ParseInsufficientLink(log) - case _LLOFeeManager.abi.Events["NativeSurchargeSet"].ID: - return _LLOFeeManager.ParseNativeSurchargeSet(log) - case _LLOFeeManager.abi.Events["OwnershipTransferRequested"].ID: - return _LLOFeeManager.ParseOwnershipTransferRequested(log) - case _LLOFeeManager.abi.Events["OwnershipTransferred"].ID: - return _LLOFeeManager.ParseOwnershipTransferred(log) - case _LLOFeeManager.abi.Events["SubscriberDiscountUpdated"].ID: - return _LLOFeeManager.ParseSubscriberDiscountUpdated(log) - case _LLOFeeManager.abi.Events["Withdraw"].ID: - return _LLOFeeManager.ParseWithdraw(log) - - default: - return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) - } -} - -func (LLOFeeManagerInsufficientLink) Topic() common.Hash { - return common.HexToHash("0xeb6f22018570d97db6df12dc94f202b4e2b2888a6a5d4bd179422c91b29dcdf7") -} - -func (LLOFeeManagerNativeSurchargeSet) Topic() common.Hash { - return common.HexToHash("0x4fbcc2b7f4cb5518be923bd7c7c887e29e07b001e2a4a0fdd47c494696d8a147") -} - -func (LLOFeeManagerOwnershipTransferRequested) Topic() common.Hash { - return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") -} - -func (LLOFeeManagerOwnershipTransferred) Topic() common.Hash { - return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") -} - -func (LLOFeeManagerSubscriberDiscountUpdated) Topic() common.Hash { - return common.HexToHash("0x41eb9ccd292d5906dc1f0ec108bed3e2b966e3071e033df938f7215f6d30ca84") -} - -func (LLOFeeManagerWithdraw) Topic() common.Hash { - return common.HexToHash("0x9b1bfa7fa9ee420a16e124f794c35ac9f90472acc99140eb2f6447c714cad8eb") -} - -func (_LLOFeeManager *LLOFeeManager) Address() common.Address { - return _LLOFeeManager.address -} - -type LLOFeeManagerInterface interface { - GetFeeAndReward(opts *bind.CallOpts, subscriber common.Address, report []byte, quote IFeeManagerQuote) (CommonAsset, CommonAsset, error) - - LinkAvailableForPayment(opts *bind.CallOpts) (*big.Int, error) - - NativeSurcharge(opts *bind.CallOpts) (*big.Int, error) - - Owner(opts *bind.CallOpts) (common.Address, error) - - SubscriberDiscounts(opts *bind.CallOpts, arg0 common.Address, arg1 [32]byte, arg2 common.Address) (*big.Int, error) - - SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) - - TypeAndVersion(opts *bind.CallOpts) (string, error) - - AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) - - ProcessFee(opts *bind.TransactOpts, payload []byte, subscriber common.Address) (*types.Transaction, error) - - SetFeeRecipients(opts *bind.TransactOpts, configDigest [32]byte, rewardRecipientAndWeights []CommonAddressAndWeight) (*types.Transaction, error) - - SetNativeSurcharge(opts *bind.TransactOpts, surcharge *big.Int) (*types.Transaction, error) - - TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) - - UpdateSubscriberDiscount(opts *bind.TransactOpts, subscriber common.Address, feedId [32]byte, token common.Address, discount *big.Int) (*types.Transaction, error) - - Withdraw(opts *bind.TransactOpts, assetAddress common.Address, quantity *big.Int) (*types.Transaction, error) - - FilterInsufficientLink(opts *bind.FilterOpts, configDigest [][32]byte) (*LLOFeeManagerInsufficientLinkIterator, error) - - WatchInsufficientLink(opts *bind.WatchOpts, sink chan<- *LLOFeeManagerInsufficientLink, configDigest [][32]byte) (event.Subscription, error) - - ParseInsufficientLink(log types.Log) (*LLOFeeManagerInsufficientLink, error) - - FilterNativeSurchargeSet(opts *bind.FilterOpts) (*LLOFeeManagerNativeSurchargeSetIterator, error) - - WatchNativeSurchargeSet(opts *bind.WatchOpts, sink chan<- *LLOFeeManagerNativeSurchargeSet) (event.Subscription, error) - - ParseNativeSurchargeSet(log types.Log) (*LLOFeeManagerNativeSurchargeSet, error) - - FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*LLOFeeManagerOwnershipTransferRequestedIterator, error) - - WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *LLOFeeManagerOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) - - ParseOwnershipTransferRequested(log types.Log) (*LLOFeeManagerOwnershipTransferRequested, error) - - FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*LLOFeeManagerOwnershipTransferredIterator, error) - - WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *LLOFeeManagerOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) - - ParseOwnershipTransferred(log types.Log) (*LLOFeeManagerOwnershipTransferred, error) - - FilterSubscriberDiscountUpdated(opts *bind.FilterOpts, subscriber []common.Address, feedId [][32]byte) (*LLOFeeManagerSubscriberDiscountUpdatedIterator, error) - - WatchSubscriberDiscountUpdated(opts *bind.WatchOpts, sink chan<- *LLOFeeManagerSubscriberDiscountUpdated, subscriber []common.Address, feedId [][32]byte) (event.Subscription, error) - - ParseSubscriberDiscountUpdated(log types.Log) (*LLOFeeManagerSubscriberDiscountUpdated, error) - - FilterWithdraw(opts *bind.FilterOpts) (*LLOFeeManagerWithdrawIterator, error) - - WatchWithdraw(opts *bind.WatchOpts, sink chan<- *LLOFeeManagerWithdraw) (event.Subscription, error) - - ParseWithdraw(log types.Log) (*LLOFeeManagerWithdraw, error) - - ParseLog(log types.Log) (generated.AbigenLog, error) - - Address() common.Address -} diff --git a/core/gethwrappers/llo-feeds/generated/llo_feeds_test/llo_feeds_test.go b/core/gethwrappers/llo-feeds/generated/llo_feeds_test/llo_feeds_test.go deleted file mode 100644 index 51f0f6e462e..00000000000 --- a/core/gethwrappers/llo-feeds/generated/llo_feeds_test/llo_feeds_test.go +++ /dev/null @@ -1,202 +0,0 @@ -// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package llo_feeds_test - -import ( - "errors" - "math/big" - "strings" - - ethereum "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/event" -) - -var ( - _ = errors.New - _ = big.NewInt - _ = strings.NewReader - _ = ethereum.NotFound - _ = bind.Bind - _ = common.Big1 - _ = types.BloomLookup - _ = event.NewSubscription - _ = abi.ConvertType -) - -var LLOExposedVerifierMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_feedId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_chainId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"_configCount\",\"type\":\"uint64\"},{\"internalType\":\"address[]\",\"name\":\"_signers\",\"type\":\"address[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"_offchainTransmitters\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"_f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"_onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"_encodedConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"_encodedConfig\",\"type\":\"bytes\"}],\"name\":\"exposedConfigDigestFromConfigData\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b50610696806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80630ebd702314610030575b600080fd5b61004361003e3660046103f7565b610055565b60405190815260200160405180910390f35b60006100a18c8c8c8c8c8c8c8c8c8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508e92508d91506100b19050565b9c9b505050505050505050505050565b6000808b8b8b8b8b8b8b8b8b8b6040516020016100d79a999897969594939291906105a7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e06000000000000000000000000000000000000000000000000000000000000179150509a9950505050505050505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461018357600080fd5b919050565b803567ffffffffffffffff8116811461018357600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610216576102166101a0565b604052919050565b600067ffffffffffffffff821115610238576102386101a0565b5060051b60200190565b600082601f83011261025357600080fd5b813560206102686102638361021e565b6101cf565b82815260059290921b8401810191818101908684111561028757600080fd5b8286015b848110156102a95761029c8161015f565b835291830191830161028b565b509695505050505050565b600082601f8301126102c557600080fd5b813560206102d56102638361021e565b82815260059290921b840181019181810190868411156102f457600080fd5b8286015b848110156102a957803583529183019183016102f8565b803560ff8116811461018357600080fd5b60008083601f84011261033257600080fd5b50813567ffffffffffffffff81111561034a57600080fd5b60208301915083602082850101111561036257600080fd5b9250929050565b600082601f83011261037a57600080fd5b813567ffffffffffffffff811115610394576103946101a0565b6103c560207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016101cf565b8181528460208386010111156103da57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060008060008060006101408c8e03121561041957600080fd5b8b359a5060208c0135995061043060408d0161015f565b985061043e60608d01610188565b975067ffffffffffffffff8060808e0135111561045a57600080fd5b61046a8e60808f01358f01610242565b97508060a08e0135111561047d57600080fd5b61048d8e60a08f01358f016102b4565b965061049b60c08e0161030f565b95508060e08e013511156104ae57600080fd5b6104be8e60e08f01358f01610320565b90955093506104d06101008e01610188565b9250806101208e013511156104e457600080fd5b506104f68d6101208e01358e01610369565b90509295989b509295989b9093969950565b600081518084526020808501945080840160005b838110156105385781518752958201959082019060010161051c565b509495945050505050565b6000815180845260005b818110156105695760208185018101518683018201520161054d565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b8a815260208082018b905273ffffffffffffffffffffffffffffffffffffffff8a8116604084015267ffffffffffffffff8a1660608401526101406080840181905289519084018190526000926101608501928b820192855b8181101561061e578451831686529483019493830193600101610600565b505050505082810360a08401526106358189610508565b60ff881660c0850152905082810360e08401526106528187610543565b67ffffffffffffffff861661010085015290508281036101208401526106788185610543565b9d9c5050505050505050505050505056fea164736f6c6343000810000a", -} - -var LLOExposedVerifierABI = LLOExposedVerifierMetaData.ABI - -var LLOExposedVerifierBin = LLOExposedVerifierMetaData.Bin - -func DeployLLOExposedVerifier(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *LLOExposedVerifier, error) { - parsed, err := LLOExposedVerifierMetaData.GetAbi() - if err != nil { - return common.Address{}, nil, nil, err - } - if parsed == nil { - return common.Address{}, nil, nil, errors.New("GetABI returned nil") - } - - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(LLOExposedVerifierBin), backend) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &LLOExposedVerifier{LLOExposedVerifierCaller: LLOExposedVerifierCaller{contract: contract}, LLOExposedVerifierTransactor: LLOExposedVerifierTransactor{contract: contract}, LLOExposedVerifierFilterer: LLOExposedVerifierFilterer{contract: contract}}, nil -} - -type LLOExposedVerifier struct { - address common.Address - abi abi.ABI - LLOExposedVerifierCaller - LLOExposedVerifierTransactor - LLOExposedVerifierFilterer -} - -type LLOExposedVerifierCaller struct { - contract *bind.BoundContract -} - -type LLOExposedVerifierTransactor struct { - contract *bind.BoundContract -} - -type LLOExposedVerifierFilterer struct { - contract *bind.BoundContract -} - -type LLOExposedVerifierSession struct { - Contract *LLOExposedVerifier - CallOpts bind.CallOpts - TransactOpts bind.TransactOpts -} - -type LLOExposedVerifierCallerSession struct { - Contract *LLOExposedVerifierCaller - CallOpts bind.CallOpts -} - -type LLOExposedVerifierTransactorSession struct { - Contract *LLOExposedVerifierTransactor - TransactOpts bind.TransactOpts -} - -type LLOExposedVerifierRaw struct { - Contract *LLOExposedVerifier -} - -type LLOExposedVerifierCallerRaw struct { - Contract *LLOExposedVerifierCaller -} - -type LLOExposedVerifierTransactorRaw struct { - Contract *LLOExposedVerifierTransactor -} - -func NewLLOExposedVerifier(address common.Address, backend bind.ContractBackend) (*LLOExposedVerifier, error) { - abi, err := abi.JSON(strings.NewReader(LLOExposedVerifierABI)) - if err != nil { - return nil, err - } - contract, err := bindLLOExposedVerifier(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &LLOExposedVerifier{address: address, abi: abi, LLOExposedVerifierCaller: LLOExposedVerifierCaller{contract: contract}, LLOExposedVerifierTransactor: LLOExposedVerifierTransactor{contract: contract}, LLOExposedVerifierFilterer: LLOExposedVerifierFilterer{contract: contract}}, nil -} - -func NewLLOExposedVerifierCaller(address common.Address, caller bind.ContractCaller) (*LLOExposedVerifierCaller, error) { - contract, err := bindLLOExposedVerifier(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &LLOExposedVerifierCaller{contract: contract}, nil -} - -func NewLLOExposedVerifierTransactor(address common.Address, transactor bind.ContractTransactor) (*LLOExposedVerifierTransactor, error) { - contract, err := bindLLOExposedVerifier(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &LLOExposedVerifierTransactor{contract: contract}, nil -} - -func NewLLOExposedVerifierFilterer(address common.Address, filterer bind.ContractFilterer) (*LLOExposedVerifierFilterer, error) { - contract, err := bindLLOExposedVerifier(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &LLOExposedVerifierFilterer{contract: contract}, nil -} - -func bindLLOExposedVerifier(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := LLOExposedVerifierMetaData.GetAbi() - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil -} - -func (_LLOExposedVerifier *LLOExposedVerifierRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _LLOExposedVerifier.Contract.LLOExposedVerifierCaller.contract.Call(opts, result, method, params...) -} - -func (_LLOExposedVerifier *LLOExposedVerifierRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _LLOExposedVerifier.Contract.LLOExposedVerifierTransactor.contract.Transfer(opts) -} - -func (_LLOExposedVerifier *LLOExposedVerifierRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _LLOExposedVerifier.Contract.LLOExposedVerifierTransactor.contract.Transact(opts, method, params...) -} - -func (_LLOExposedVerifier *LLOExposedVerifierCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _LLOExposedVerifier.Contract.contract.Call(opts, result, method, params...) -} - -func (_LLOExposedVerifier *LLOExposedVerifierTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _LLOExposedVerifier.Contract.contract.Transfer(opts) -} - -func (_LLOExposedVerifier *LLOExposedVerifierTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _LLOExposedVerifier.Contract.contract.Transact(opts, method, params...) -} - -func (_LLOExposedVerifier *LLOExposedVerifierCaller) ExposedConfigDigestFromConfigData(opts *bind.CallOpts, _feedId [32]byte, _chainId *big.Int, _contractAddress common.Address, _configCount uint64, _signers []common.Address, _offchainTransmitters [][32]byte, _f uint8, _onchainConfig []byte, _encodedConfigVersion uint64, _encodedConfig []byte) ([32]byte, error) { - var out []interface{} - err := _LLOExposedVerifier.contract.Call(opts, &out, "exposedConfigDigestFromConfigData", _feedId, _chainId, _contractAddress, _configCount, _signers, _offchainTransmitters, _f, _onchainConfig, _encodedConfigVersion, _encodedConfig) - - if err != nil { - return *new([32]byte), err - } - - out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) - - return out0, err - -} - -func (_LLOExposedVerifier *LLOExposedVerifierSession) ExposedConfigDigestFromConfigData(_feedId [32]byte, _chainId *big.Int, _contractAddress common.Address, _configCount uint64, _signers []common.Address, _offchainTransmitters [][32]byte, _f uint8, _onchainConfig []byte, _encodedConfigVersion uint64, _encodedConfig []byte) ([32]byte, error) { - return _LLOExposedVerifier.Contract.ExposedConfigDigestFromConfigData(&_LLOExposedVerifier.CallOpts, _feedId, _chainId, _contractAddress, _configCount, _signers, _offchainTransmitters, _f, _onchainConfig, _encodedConfigVersion, _encodedConfig) -} - -func (_LLOExposedVerifier *LLOExposedVerifierCallerSession) ExposedConfigDigestFromConfigData(_feedId [32]byte, _chainId *big.Int, _contractAddress common.Address, _configCount uint64, _signers []common.Address, _offchainTransmitters [][32]byte, _f uint8, _onchainConfig []byte, _encodedConfigVersion uint64, _encodedConfig []byte) ([32]byte, error) { - return _LLOExposedVerifier.Contract.ExposedConfigDigestFromConfigData(&_LLOExposedVerifier.CallOpts, _feedId, _chainId, _contractAddress, _configCount, _signers, _offchainTransmitters, _f, _onchainConfig, _encodedConfigVersion, _encodedConfig) -} - -func (_LLOExposedVerifier *LLOExposedVerifier) Address() common.Address { - return _LLOExposedVerifier.address -} - -type LLOExposedVerifierInterface interface { - ExposedConfigDigestFromConfigData(opts *bind.CallOpts, _feedId [32]byte, _chainId *big.Int, _contractAddress common.Address, _configCount uint64, _signers []common.Address, _offchainTransmitters [][32]byte, _f uint8, _onchainConfig []byte, _encodedConfigVersion uint64, _encodedConfig []byte) ([32]byte, error) - - Address() common.Address -} diff --git a/core/gethwrappers/llo-feeds/generated/reward_manager_v0_5_0/reward_manager_v0_5_0.go b/core/gethwrappers/llo-feeds/generated/reward_manager_v0_5_0/reward_manager_v0_5_0.go new file mode 100644 index 00000000000..f7221195282 --- /dev/null +++ b/core/gethwrappers/llo-feeds/generated/reward_manager_v0_5_0/reward_manager_v0_5_0.go @@ -0,0 +1,1420 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package reward_manager_v0_5_0 + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type CommonAddressAndWeight struct { + Addr common.Address + Weight uint64 +} + +type IRewardManagerFeePayment struct { + PoolId [32]byte + Amount *big.Int +} + +var RewardManagerMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"linkAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPoolId\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPoolLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidWeights\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newFeeManagerAddress\",\"type\":\"address\"}],\"name\":\"FeeManagerUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"internalType\":\"uint192\",\"name\":\"amount\",\"type\":\"uint192\"}],\"indexed\":false,\"internalType\":\"structIRewardManager.FeePayment[]\",\"name\":\"payments\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"payer\",\"type\":\"address\"}],\"name\":\"FeePaid\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"indexed\":false,\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"newRewardRecipients\",\"type\":\"tuple[]\"}],\"name\":\"RewardRecipientsUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint192\",\"name\":\"quantity\",\"type\":\"uint192\"}],\"name\":\"RewardsClaimed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"poolIds\",\"type\":\"bytes32[]\"}],\"name\":\"claimRewards\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"startIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"endIndex\",\"type\":\"uint256\"}],\"name\":\"getAvailableRewardPoolIds\",\"outputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_linkAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"internalType\":\"uint192\",\"name\":\"amount\",\"type\":\"uint192\"}],\"internalType\":\"structIRewardManager.FeePayment[]\",\"name\":\"payments\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"payer\",\"type\":\"address\"}],\"name\":\"onFeePaid\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"internalType\":\"address[]\",\"name\":\"recipients\",\"type\":\"address[]\"}],\"name\":\"payRecipients\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_feeManagerAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_registeredPoolIds\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"s_rewardRecipientWeights\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"s_rewardRecipientWeightsSet\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"s_totalRewardRecipientFees\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"s_totalRewardRecipientFeesLastClaimedAmounts\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newFeeManagerAddress\",\"type\":\"address\"}],\"name\":\"setFeeManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"rewardRecipientAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"setRewardRecipients\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"newRewardRecipients\",\"type\":\"tuple[]\"}],\"name\":\"updateRewardRecipients\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60a06040523480156200001157600080fd5b50604051620020c2380380620020c28339810160408190526200003491620001a6565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000fb565b5050506001600160a01b038116620000e95760405163e6c4247b60e01b815260040160405180910390fd5b6001600160a01b0316608052620001d8565b336001600160a01b03821603620001555760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060208284031215620001b957600080fd5b81516001600160a01b0381168114620001d157600080fd5b9392505050565b608051611ec062000202600039600081816103bd01528181610ce30152610f1e0152611ec06000f3fe608060405234801561001057600080fd5b50600436106101515760003560e01c80634d322084116100cd5780638da5cb5b11610081578063cd5f729211610066578063cd5f7292146103a5578063ea4b861b146103b8578063f2fde38b146103df57600080fd5b80638da5cb5b14610374578063b0d9fa191461039257600080fd5b806360122608116100b2578063601226081461031657806379ba5097146103415780638ac85a5c1461034957600080fd5b80634d322084146102e057806359256201146102f357600080fd5b8063276e7660116101245780634722647511610109578063472264751461029a578063472d35b9146102ba5780634944832f146102cd57600080fd5b8063276e76601461022757806339ee81e11461026c57600080fd5b806301ffc9a7146101565780630f3c34d1146101c057806314060f23146101d5578063181f5a77146101e8575b600080fd5b6101ab6101643660046117ac565b7fffffffff00000000000000000000000000000000000000000000000000000000167fb0d9fa19000000000000000000000000000000000000000000000000000000001490565b60405190151581526020015b60405180910390f35b6101d36101ce36600461186c565b6103f2565b005b6101d36101e336600461195e565b610400565b604080518082018252601381527f5265776172644d616e6167657220312e312e3000000000000000000000000000602082015290516101b791906119ce565b6007546102479073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101b7565b61028c61027a366004611a1f565b60026020526000908152604090205481565b6040519081526020016101b7565b6102ad6102a8366004611a61565b6105b6565b6040516101b79190611a94565b6101d36102c8366004611ad8565b610740565b6101d36102db36600461195e565b61080e565b6101d36102ee366004611afa565b610957565b6101ab610301366004611a1f565b60056020526000908152604090205460ff1681565b61028c610324366004611b79565b600360209081526000928352604080842090915290825290205481565b6101d3610a96565b61028c610357366004611b79565b600460209081526000928352604080842090915290825290205481565b60005473ffffffffffffffffffffffffffffffffffffffff16610247565b6101d36103a0366004611ba5565b610b98565b61028c6103b3366004611a1f565b610d4c565b6102477f000000000000000000000000000000000000000000000000000000000000000081565b6101d36103ed366004611ad8565b610d6d565b6103fc3382610d81565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff163314801590610440575060075473ffffffffffffffffffffffffffffffffffffffff163314155b15610477576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008190036104b2576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008381526005602052604090205460ff16156104fb576040517f0afa7ee800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006805460018181019092557ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f01849055600084815260056020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169091179055610577838383670de0b6b3a7640000610f4e565b827f8f668d6090683f98b3373a8b83d214da45737f7486cb7de554cc07b54e61cfe683836040516105a9929190611c11565b60405180910390a2505050565b60065460609060008184116105cb57836105cd565b815b905080851115610609576040517fa22caccc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006106158683611ca8565b67ffffffffffffffff81111561062d5761062d6117ee565b604051908082528060200260200182016040528015610656578160200160208202803683370190505b5090506000865b838110156107335760006006828154811061067a5761067a611cbb565b600091825260208083209091015480835260048252604080842073ffffffffffffffffffffffffffffffffffffffff8f16855290925291205490915015610722576000818152600260209081526040808320546003835281842073ffffffffffffffffffffffffffffffffffffffff8f168552909252909120548114610720578185858060010196508151811061071357610713611cbb565b6020026020010181815250505b505b5061072c81611cea565b905061065d565b5090979650505050505050565b610748611125565b73ffffffffffffffffffffffffffffffffffffffff8116610795576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527fe45f5e140399b0a7e12971ab020724b828fbed8ac408c420884dc7d1bbe506b49060200160405180910390a150565b610816611125565b60408051600180825281830190925260009160208083019080368337019050509050838160008151811061084c5761084c611cbb565b6020026020010181815250506000805b8381101561090957600085858381811061087857610878611cbb565b61088e9260206040909202019081019150611ad8565b600088815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff851684529091529020549091506108f28787858181106108d6576108d6611cbb565b6108ec9260206040909202019081019150611ad8565b86610d81565b5092909201915061090281611cea565b905061085c565b5061091685858584610f4e565b847f8f668d6090683f98b3373a8b83d214da45737f7486cb7de554cc07b54e61cfe68585604051610948929190611c11565b60405180910390a25050505050565b8261097760005473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141580156109c957506000818152600460209081526040808320338452909152902054155b15610a00576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516001808252818301909252600091602080830190803683370190505090508481600081518110610a3657610a36611cbb565b60200260200101818152505060005b83811015610a8e57610a7d858583818110610a6257610a62611cbb565b9050602002016020810190610a779190611ad8565b83610d81565b50610a8781611cea565b9050610a45565b505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610b1c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60075473ffffffffffffffffffffffffffffffffffffffff163314610be9576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b83811015610cc857848482818110610c0757610c07611cbb565b9050604002016020016020810190610c1f9190611d4a565b77ffffffffffffffffffffffffffffffffffffffffffffffff1660026000878785818110610c4f57610c4f611cbb565b6040908102929092013583525060208201929092520160002080549091019055848482818110610c8157610c81611cbb565b9050604002016020016020810190610c999190611d4a565b77ffffffffffffffffffffffffffffffffffffffffffffffff168201915080610cc190611cea565b9050610bed565b50610d0b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168330846111a8565b7fa1cc025ea76bacce5d740ee4bc331899375dc2c5f2ab33933aaacbd9ba001b66848484604051610d3e93929190611d65565b60405180910390a150505050565b60068181548110610d5c57600080fd5b600091825260209091200154905081565b610d75611125565b610d7e8161128a565b50565b60008060005b8351811015610efd576000848281518110610da457610da4611cbb565b6020026020010151905060006002600083815260200190815260200160002054905080600003610dd5575050610eed565b600082815260036020908152604080832073ffffffffffffffffffffffffffffffffffffffff8b16808552908352818420548685526004845282852091855292528220549083039190670de0b6b3a764000090830204905080600003610e3e5750505050610eed565b600084815260036020908152604080832073ffffffffffffffffffffffffffffffffffffffff8d168085529252909120849055885196820196899087908110610e8957610e89611cbb565b60200260200101517f989969655bc1d593922527fe85d71347bb8e12fa423cc71f362dd8ef7cb10ef283604051610ee0919077ffffffffffffffffffffffffffffffffffffffffffffffff91909116815260200190565b60405180910390a3505050505b610ef681611cea565b9050610d87565b508015610f4557610f4573ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016858361137f565b90505b92915050565b610fa98383808060200260200160405190810160405280939291908181526020016000905b82821015610f9f57610f9060408302860136819003810190611dec565b81526020019060010190610f73565b50505050506113da565b15610fe0576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b838110156110e457600085858381811061100057611000611cbb565b90506040020160200160208101906110189190611e47565b67ffffffffffffffff169050600086868481811061103857611038611cbb565b61104e9260206040909202019081019150611ad8565b905073ffffffffffffffffffffffffffffffffffffffff811661109d576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600088815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff90941683529290522081905591909101906110dd81611cea565b9050610fe4565b5081811461111e576040517f84677ce800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146111a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610b13565b565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526112849085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611491565b50505050565b3373ffffffffffffffffffffffffffffffffffffffff821603611309576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610b13565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526113d59084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401611202565b505050565b6000805b82518110156114885760006113f4826001611e62565b90505b835181101561147f5783818151811061141257611412611cbb565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1684838151811061144657611446611cbb565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1603611477575060019392505050565b6001016113f7565b506001016113de565b50600092915050565b60006114f3826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661159d9092919063ffffffff16565b8051909150156113d557808060200190518101906115119190611e75565b6113d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610b13565b60606115ac84846000856115b4565b949350505050565b606082471015611646576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610b13565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161166f9190611e97565b60006040518083038185875af1925050503d80600081146116ac576040519150601f19603f3d011682016040523d82523d6000602084013e6116b1565b606091505b50915091506116c2878383876116cd565b979650505050505050565b6060831561176357825160000361175c5773ffffffffffffffffffffffffffffffffffffffff85163b61175c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610b13565b50816115ac565b6115ac83838151156117785781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b1391906119ce565b6000602082840312156117be57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610f4557600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611864576118646117ee565b604052919050565b6000602080838503121561187f57600080fd5b823567ffffffffffffffff8082111561189757600080fd5b818501915085601f8301126118ab57600080fd5b8135818111156118bd576118bd6117ee565b8060051b91506118ce84830161181d565b81815291830184019184810190888411156118e857600080fd5b938501935b83851015611906578435825293850193908501906118ed565b98975050505050505050565b60008083601f84011261192457600080fd5b50813567ffffffffffffffff81111561193c57600080fd5b6020830191508360208260061b850101111561195757600080fd5b9250929050565b60008060006040848603121561197357600080fd5b83359250602084013567ffffffffffffffff81111561199157600080fd5b61199d86828701611912565b9497909650939450505050565b60005b838110156119c55781810151838201526020016119ad565b50506000910152565b60208152600082518060208401526119ed8160408501602087016119aa565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b600060208284031215611a3157600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611a5c57600080fd5b919050565b600080600060608486031215611a7657600080fd5b611a7f84611a38565b95602085013595506040909401359392505050565b6020808252825182820181905260009190848201906040850190845b81811015611acc57835183529284019291840191600101611ab0565b50909695505050505050565b600060208284031215611aea57600080fd5b611af382611a38565b9392505050565b600080600060408486031215611b0f57600080fd5b83359250602084013567ffffffffffffffff80821115611b2e57600080fd5b818601915086601f830112611b4257600080fd5b813581811115611b5157600080fd5b8760208260051b8501011115611b6657600080fd5b6020830194508093505050509250925092565b60008060408385031215611b8c57600080fd5b82359150611b9c60208401611a38565b90509250929050565b600080600060408486031215611bba57600080fd5b833567ffffffffffffffff811115611bd157600080fd5b611bdd86828701611912565b9094509250611bf0905060208501611a38565b90509250925092565b803567ffffffffffffffff81168114611a5c57600080fd5b6020808252818101839052600090604080840186845b878110156107335773ffffffffffffffffffffffffffffffffffffffff611c4d83611a38565b16835267ffffffffffffffff611c64868401611bf9565b16838601529183019190830190600101611c27565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610f4857610f48611c79565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611d1b57611d1b611c79565b5060010190565b803577ffffffffffffffffffffffffffffffffffffffffffffffff81168114611a5c57600080fd5b600060208284031215611d5c57600080fd5b611af382611d22565b60408082528181018490526000908560608401835b87811015611dc15782358252602077ffffffffffffffffffffffffffffffffffffffffffffffff611dac828601611d22565b16908301529183019190830190600101611d7a565b5080935050505073ffffffffffffffffffffffffffffffffffffffff83166020830152949350505050565b600060408284031215611dfe57600080fd5b6040516040810181811067ffffffffffffffff82111715611e2157611e216117ee565b604052611e2d83611a38565b8152611e3b60208401611bf9565b60208201529392505050565b600060208284031215611e5957600080fd5b611af382611bf9565b80820180821115610f4857610f48611c79565b600060208284031215611e8757600080fd5b81518015158114610f4557600080fd5b60008251611ea98184602087016119aa565b919091019291505056fea164736f6c6343000813000a", +} + +var RewardManagerABI = RewardManagerMetaData.ABI + +var RewardManagerBin = RewardManagerMetaData.Bin + +func DeployRewardManager(auth *bind.TransactOpts, backend bind.ContractBackend, linkAddress common.Address) (common.Address, *types.Transaction, *RewardManager, error) { + parsed, err := RewardManagerMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(RewardManagerBin), backend, linkAddress) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &RewardManager{address: address, abi: *parsed, RewardManagerCaller: RewardManagerCaller{contract: contract}, RewardManagerTransactor: RewardManagerTransactor{contract: contract}, RewardManagerFilterer: RewardManagerFilterer{contract: contract}}, nil +} + +type RewardManager struct { + address common.Address + abi abi.ABI + RewardManagerCaller + RewardManagerTransactor + RewardManagerFilterer +} + +type RewardManagerCaller struct { + contract *bind.BoundContract +} + +type RewardManagerTransactor struct { + contract *bind.BoundContract +} + +type RewardManagerFilterer struct { + contract *bind.BoundContract +} + +type RewardManagerSession struct { + Contract *RewardManager + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type RewardManagerCallerSession struct { + Contract *RewardManagerCaller + CallOpts bind.CallOpts +} + +type RewardManagerTransactorSession struct { + Contract *RewardManagerTransactor + TransactOpts bind.TransactOpts +} + +type RewardManagerRaw struct { + Contract *RewardManager +} + +type RewardManagerCallerRaw struct { + Contract *RewardManagerCaller +} + +type RewardManagerTransactorRaw struct { + Contract *RewardManagerTransactor +} + +func NewRewardManager(address common.Address, backend bind.ContractBackend) (*RewardManager, error) { + abi, err := abi.JSON(strings.NewReader(RewardManagerABI)) + if err != nil { + return nil, err + } + contract, err := bindRewardManager(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &RewardManager{address: address, abi: abi, RewardManagerCaller: RewardManagerCaller{contract: contract}, RewardManagerTransactor: RewardManagerTransactor{contract: contract}, RewardManagerFilterer: RewardManagerFilterer{contract: contract}}, nil +} + +func NewRewardManagerCaller(address common.Address, caller bind.ContractCaller) (*RewardManagerCaller, error) { + contract, err := bindRewardManager(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &RewardManagerCaller{contract: contract}, nil +} + +func NewRewardManagerTransactor(address common.Address, transactor bind.ContractTransactor) (*RewardManagerTransactor, error) { + contract, err := bindRewardManager(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &RewardManagerTransactor{contract: contract}, nil +} + +func NewRewardManagerFilterer(address common.Address, filterer bind.ContractFilterer) (*RewardManagerFilterer, error) { + contract, err := bindRewardManager(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &RewardManagerFilterer{contract: contract}, nil +} + +func bindRewardManager(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := RewardManagerMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_RewardManager *RewardManagerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _RewardManager.Contract.RewardManagerCaller.contract.Call(opts, result, method, params...) +} + +func (_RewardManager *RewardManagerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _RewardManager.Contract.RewardManagerTransactor.contract.Transfer(opts) +} + +func (_RewardManager *RewardManagerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _RewardManager.Contract.RewardManagerTransactor.contract.Transact(opts, method, params...) +} + +func (_RewardManager *RewardManagerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _RewardManager.Contract.contract.Call(opts, result, method, params...) +} + +func (_RewardManager *RewardManagerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _RewardManager.Contract.contract.Transfer(opts) +} + +func (_RewardManager *RewardManagerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _RewardManager.Contract.contract.Transact(opts, method, params...) +} + +func (_RewardManager *RewardManagerCaller) GetAvailableRewardPoolIds(opts *bind.CallOpts, recipient common.Address, startIndex *big.Int, endIndex *big.Int) ([][32]byte, error) { + var out []interface{} + err := _RewardManager.contract.Call(opts, &out, "getAvailableRewardPoolIds", recipient, startIndex, endIndex) + + if err != nil { + return *new([][32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([][32]byte)).(*[][32]byte) + + return out0, err + +} + +func (_RewardManager *RewardManagerSession) GetAvailableRewardPoolIds(recipient common.Address, startIndex *big.Int, endIndex *big.Int) ([][32]byte, error) { + return _RewardManager.Contract.GetAvailableRewardPoolIds(&_RewardManager.CallOpts, recipient, startIndex, endIndex) +} + +func (_RewardManager *RewardManagerCallerSession) GetAvailableRewardPoolIds(recipient common.Address, startIndex *big.Int, endIndex *big.Int) ([][32]byte, error) { + return _RewardManager.Contract.GetAvailableRewardPoolIds(&_RewardManager.CallOpts, recipient, startIndex, endIndex) +} + +func (_RewardManager *RewardManagerCaller) ILinkAddress(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _RewardManager.contract.Call(opts, &out, "i_linkAddress") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_RewardManager *RewardManagerSession) ILinkAddress() (common.Address, error) { + return _RewardManager.Contract.ILinkAddress(&_RewardManager.CallOpts) +} + +func (_RewardManager *RewardManagerCallerSession) ILinkAddress() (common.Address, error) { + return _RewardManager.Contract.ILinkAddress(&_RewardManager.CallOpts) +} + +func (_RewardManager *RewardManagerCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _RewardManager.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_RewardManager *RewardManagerSession) Owner() (common.Address, error) { + return _RewardManager.Contract.Owner(&_RewardManager.CallOpts) +} + +func (_RewardManager *RewardManagerCallerSession) Owner() (common.Address, error) { + return _RewardManager.Contract.Owner(&_RewardManager.CallOpts) +} + +func (_RewardManager *RewardManagerCaller) SFeeManagerAddress(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _RewardManager.contract.Call(opts, &out, "s_feeManagerAddress") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_RewardManager *RewardManagerSession) SFeeManagerAddress() (common.Address, error) { + return _RewardManager.Contract.SFeeManagerAddress(&_RewardManager.CallOpts) +} + +func (_RewardManager *RewardManagerCallerSession) SFeeManagerAddress() (common.Address, error) { + return _RewardManager.Contract.SFeeManagerAddress(&_RewardManager.CallOpts) +} + +func (_RewardManager *RewardManagerCaller) SRegisteredPoolIds(opts *bind.CallOpts, arg0 *big.Int) ([32]byte, error) { + var out []interface{} + err := _RewardManager.contract.Call(opts, &out, "s_registeredPoolIds", arg0) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +func (_RewardManager *RewardManagerSession) SRegisteredPoolIds(arg0 *big.Int) ([32]byte, error) { + return _RewardManager.Contract.SRegisteredPoolIds(&_RewardManager.CallOpts, arg0) +} + +func (_RewardManager *RewardManagerCallerSession) SRegisteredPoolIds(arg0 *big.Int) ([32]byte, error) { + return _RewardManager.Contract.SRegisteredPoolIds(&_RewardManager.CallOpts, arg0) +} + +func (_RewardManager *RewardManagerCaller) SRewardRecipientWeights(opts *bind.CallOpts, arg0 [32]byte, arg1 common.Address) (*big.Int, error) { + var out []interface{} + err := _RewardManager.contract.Call(opts, &out, "s_rewardRecipientWeights", arg0, arg1) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_RewardManager *RewardManagerSession) SRewardRecipientWeights(arg0 [32]byte, arg1 common.Address) (*big.Int, error) { + return _RewardManager.Contract.SRewardRecipientWeights(&_RewardManager.CallOpts, arg0, arg1) +} + +func (_RewardManager *RewardManagerCallerSession) SRewardRecipientWeights(arg0 [32]byte, arg1 common.Address) (*big.Int, error) { + return _RewardManager.Contract.SRewardRecipientWeights(&_RewardManager.CallOpts, arg0, arg1) +} + +func (_RewardManager *RewardManagerCaller) SRewardRecipientWeightsSet(opts *bind.CallOpts, arg0 [32]byte) (bool, error) { + var out []interface{} + err := _RewardManager.contract.Call(opts, &out, "s_rewardRecipientWeightsSet", arg0) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_RewardManager *RewardManagerSession) SRewardRecipientWeightsSet(arg0 [32]byte) (bool, error) { + return _RewardManager.Contract.SRewardRecipientWeightsSet(&_RewardManager.CallOpts, arg0) +} + +func (_RewardManager *RewardManagerCallerSession) SRewardRecipientWeightsSet(arg0 [32]byte) (bool, error) { + return _RewardManager.Contract.SRewardRecipientWeightsSet(&_RewardManager.CallOpts, arg0) +} + +func (_RewardManager *RewardManagerCaller) STotalRewardRecipientFees(opts *bind.CallOpts, arg0 [32]byte) (*big.Int, error) { + var out []interface{} + err := _RewardManager.contract.Call(opts, &out, "s_totalRewardRecipientFees", arg0) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_RewardManager *RewardManagerSession) STotalRewardRecipientFees(arg0 [32]byte) (*big.Int, error) { + return _RewardManager.Contract.STotalRewardRecipientFees(&_RewardManager.CallOpts, arg0) +} + +func (_RewardManager *RewardManagerCallerSession) STotalRewardRecipientFees(arg0 [32]byte) (*big.Int, error) { + return _RewardManager.Contract.STotalRewardRecipientFees(&_RewardManager.CallOpts, arg0) +} + +func (_RewardManager *RewardManagerCaller) STotalRewardRecipientFeesLastClaimedAmounts(opts *bind.CallOpts, arg0 [32]byte, arg1 common.Address) (*big.Int, error) { + var out []interface{} + err := _RewardManager.contract.Call(opts, &out, "s_totalRewardRecipientFeesLastClaimedAmounts", arg0, arg1) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_RewardManager *RewardManagerSession) STotalRewardRecipientFeesLastClaimedAmounts(arg0 [32]byte, arg1 common.Address) (*big.Int, error) { + return _RewardManager.Contract.STotalRewardRecipientFeesLastClaimedAmounts(&_RewardManager.CallOpts, arg0, arg1) +} + +func (_RewardManager *RewardManagerCallerSession) STotalRewardRecipientFeesLastClaimedAmounts(arg0 [32]byte, arg1 common.Address) (*big.Int, error) { + return _RewardManager.Contract.STotalRewardRecipientFeesLastClaimedAmounts(&_RewardManager.CallOpts, arg0, arg1) +} + +func (_RewardManager *RewardManagerCaller) SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) { + var out []interface{} + err := _RewardManager.contract.Call(opts, &out, "supportsInterface", interfaceId) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_RewardManager *RewardManagerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _RewardManager.Contract.SupportsInterface(&_RewardManager.CallOpts, interfaceId) +} + +func (_RewardManager *RewardManagerCallerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _RewardManager.Contract.SupportsInterface(&_RewardManager.CallOpts, interfaceId) +} + +func (_RewardManager *RewardManagerCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _RewardManager.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_RewardManager *RewardManagerSession) TypeAndVersion() (string, error) { + return _RewardManager.Contract.TypeAndVersion(&_RewardManager.CallOpts) +} + +func (_RewardManager *RewardManagerCallerSession) TypeAndVersion() (string, error) { + return _RewardManager.Contract.TypeAndVersion(&_RewardManager.CallOpts) +} + +func (_RewardManager *RewardManagerTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _RewardManager.contract.Transact(opts, "acceptOwnership") +} + +func (_RewardManager *RewardManagerSession) AcceptOwnership() (*types.Transaction, error) { + return _RewardManager.Contract.AcceptOwnership(&_RewardManager.TransactOpts) +} + +func (_RewardManager *RewardManagerTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _RewardManager.Contract.AcceptOwnership(&_RewardManager.TransactOpts) +} + +func (_RewardManager *RewardManagerTransactor) ClaimRewards(opts *bind.TransactOpts, poolIds [][32]byte) (*types.Transaction, error) { + return _RewardManager.contract.Transact(opts, "claimRewards", poolIds) +} + +func (_RewardManager *RewardManagerSession) ClaimRewards(poolIds [][32]byte) (*types.Transaction, error) { + return _RewardManager.Contract.ClaimRewards(&_RewardManager.TransactOpts, poolIds) +} + +func (_RewardManager *RewardManagerTransactorSession) ClaimRewards(poolIds [][32]byte) (*types.Transaction, error) { + return _RewardManager.Contract.ClaimRewards(&_RewardManager.TransactOpts, poolIds) +} + +func (_RewardManager *RewardManagerTransactor) OnFeePaid(opts *bind.TransactOpts, payments []IRewardManagerFeePayment, payer common.Address) (*types.Transaction, error) { + return _RewardManager.contract.Transact(opts, "onFeePaid", payments, payer) +} + +func (_RewardManager *RewardManagerSession) OnFeePaid(payments []IRewardManagerFeePayment, payer common.Address) (*types.Transaction, error) { + return _RewardManager.Contract.OnFeePaid(&_RewardManager.TransactOpts, payments, payer) +} + +func (_RewardManager *RewardManagerTransactorSession) OnFeePaid(payments []IRewardManagerFeePayment, payer common.Address) (*types.Transaction, error) { + return _RewardManager.Contract.OnFeePaid(&_RewardManager.TransactOpts, payments, payer) +} + +func (_RewardManager *RewardManagerTransactor) PayRecipients(opts *bind.TransactOpts, poolId [32]byte, recipients []common.Address) (*types.Transaction, error) { + return _RewardManager.contract.Transact(opts, "payRecipients", poolId, recipients) +} + +func (_RewardManager *RewardManagerSession) PayRecipients(poolId [32]byte, recipients []common.Address) (*types.Transaction, error) { + return _RewardManager.Contract.PayRecipients(&_RewardManager.TransactOpts, poolId, recipients) +} + +func (_RewardManager *RewardManagerTransactorSession) PayRecipients(poolId [32]byte, recipients []common.Address) (*types.Transaction, error) { + return _RewardManager.Contract.PayRecipients(&_RewardManager.TransactOpts, poolId, recipients) +} + +func (_RewardManager *RewardManagerTransactor) SetFeeManager(opts *bind.TransactOpts, newFeeManagerAddress common.Address) (*types.Transaction, error) { + return _RewardManager.contract.Transact(opts, "setFeeManager", newFeeManagerAddress) +} + +func (_RewardManager *RewardManagerSession) SetFeeManager(newFeeManagerAddress common.Address) (*types.Transaction, error) { + return _RewardManager.Contract.SetFeeManager(&_RewardManager.TransactOpts, newFeeManagerAddress) +} + +func (_RewardManager *RewardManagerTransactorSession) SetFeeManager(newFeeManagerAddress common.Address) (*types.Transaction, error) { + return _RewardManager.Contract.SetFeeManager(&_RewardManager.TransactOpts, newFeeManagerAddress) +} + +func (_RewardManager *RewardManagerTransactor) SetRewardRecipients(opts *bind.TransactOpts, poolId [32]byte, rewardRecipientAndWeights []CommonAddressAndWeight) (*types.Transaction, error) { + return _RewardManager.contract.Transact(opts, "setRewardRecipients", poolId, rewardRecipientAndWeights) +} + +func (_RewardManager *RewardManagerSession) SetRewardRecipients(poolId [32]byte, rewardRecipientAndWeights []CommonAddressAndWeight) (*types.Transaction, error) { + return _RewardManager.Contract.SetRewardRecipients(&_RewardManager.TransactOpts, poolId, rewardRecipientAndWeights) +} + +func (_RewardManager *RewardManagerTransactorSession) SetRewardRecipients(poolId [32]byte, rewardRecipientAndWeights []CommonAddressAndWeight) (*types.Transaction, error) { + return _RewardManager.Contract.SetRewardRecipients(&_RewardManager.TransactOpts, poolId, rewardRecipientAndWeights) +} + +func (_RewardManager *RewardManagerTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _RewardManager.contract.Transact(opts, "transferOwnership", to) +} + +func (_RewardManager *RewardManagerSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _RewardManager.Contract.TransferOwnership(&_RewardManager.TransactOpts, to) +} + +func (_RewardManager *RewardManagerTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _RewardManager.Contract.TransferOwnership(&_RewardManager.TransactOpts, to) +} + +func (_RewardManager *RewardManagerTransactor) UpdateRewardRecipients(opts *bind.TransactOpts, poolId [32]byte, newRewardRecipients []CommonAddressAndWeight) (*types.Transaction, error) { + return _RewardManager.contract.Transact(opts, "updateRewardRecipients", poolId, newRewardRecipients) +} + +func (_RewardManager *RewardManagerSession) UpdateRewardRecipients(poolId [32]byte, newRewardRecipients []CommonAddressAndWeight) (*types.Transaction, error) { + return _RewardManager.Contract.UpdateRewardRecipients(&_RewardManager.TransactOpts, poolId, newRewardRecipients) +} + +func (_RewardManager *RewardManagerTransactorSession) UpdateRewardRecipients(poolId [32]byte, newRewardRecipients []CommonAddressAndWeight) (*types.Transaction, error) { + return _RewardManager.Contract.UpdateRewardRecipients(&_RewardManager.TransactOpts, poolId, newRewardRecipients) +} + +type RewardManagerFeeManagerUpdatedIterator struct { + Event *RewardManagerFeeManagerUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *RewardManagerFeeManagerUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(RewardManagerFeeManagerUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(RewardManagerFeeManagerUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *RewardManagerFeeManagerUpdatedIterator) Error() error { + return it.fail +} + +func (it *RewardManagerFeeManagerUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type RewardManagerFeeManagerUpdated struct { + NewFeeManagerAddress common.Address + Raw types.Log +} + +func (_RewardManager *RewardManagerFilterer) FilterFeeManagerUpdated(opts *bind.FilterOpts) (*RewardManagerFeeManagerUpdatedIterator, error) { + + logs, sub, err := _RewardManager.contract.FilterLogs(opts, "FeeManagerUpdated") + if err != nil { + return nil, err + } + return &RewardManagerFeeManagerUpdatedIterator{contract: _RewardManager.contract, event: "FeeManagerUpdated", logs: logs, sub: sub}, nil +} + +func (_RewardManager *RewardManagerFilterer) WatchFeeManagerUpdated(opts *bind.WatchOpts, sink chan<- *RewardManagerFeeManagerUpdated) (event.Subscription, error) { + + logs, sub, err := _RewardManager.contract.WatchLogs(opts, "FeeManagerUpdated") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(RewardManagerFeeManagerUpdated) + if err := _RewardManager.contract.UnpackLog(event, "FeeManagerUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_RewardManager *RewardManagerFilterer) ParseFeeManagerUpdated(log types.Log) (*RewardManagerFeeManagerUpdated, error) { + event := new(RewardManagerFeeManagerUpdated) + if err := _RewardManager.contract.UnpackLog(event, "FeeManagerUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type RewardManagerFeePaidIterator struct { + Event *RewardManagerFeePaid + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *RewardManagerFeePaidIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(RewardManagerFeePaid) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(RewardManagerFeePaid) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *RewardManagerFeePaidIterator) Error() error { + return it.fail +} + +func (it *RewardManagerFeePaidIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type RewardManagerFeePaid struct { + Payments []IRewardManagerFeePayment + Payer common.Address + Raw types.Log +} + +func (_RewardManager *RewardManagerFilterer) FilterFeePaid(opts *bind.FilterOpts) (*RewardManagerFeePaidIterator, error) { + + logs, sub, err := _RewardManager.contract.FilterLogs(opts, "FeePaid") + if err != nil { + return nil, err + } + return &RewardManagerFeePaidIterator{contract: _RewardManager.contract, event: "FeePaid", logs: logs, sub: sub}, nil +} + +func (_RewardManager *RewardManagerFilterer) WatchFeePaid(opts *bind.WatchOpts, sink chan<- *RewardManagerFeePaid) (event.Subscription, error) { + + logs, sub, err := _RewardManager.contract.WatchLogs(opts, "FeePaid") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(RewardManagerFeePaid) + if err := _RewardManager.contract.UnpackLog(event, "FeePaid", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_RewardManager *RewardManagerFilterer) ParseFeePaid(log types.Log) (*RewardManagerFeePaid, error) { + event := new(RewardManagerFeePaid) + if err := _RewardManager.contract.UnpackLog(event, "FeePaid", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type RewardManagerOwnershipTransferRequestedIterator struct { + Event *RewardManagerOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *RewardManagerOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(RewardManagerOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(RewardManagerOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *RewardManagerOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *RewardManagerOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type RewardManagerOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_RewardManager *RewardManagerFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*RewardManagerOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _RewardManager.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &RewardManagerOwnershipTransferRequestedIterator{contract: _RewardManager.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_RewardManager *RewardManagerFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *RewardManagerOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _RewardManager.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(RewardManagerOwnershipTransferRequested) + if err := _RewardManager.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_RewardManager *RewardManagerFilterer) ParseOwnershipTransferRequested(log types.Log) (*RewardManagerOwnershipTransferRequested, error) { + event := new(RewardManagerOwnershipTransferRequested) + if err := _RewardManager.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type RewardManagerOwnershipTransferredIterator struct { + Event *RewardManagerOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *RewardManagerOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(RewardManagerOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(RewardManagerOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *RewardManagerOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *RewardManagerOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type RewardManagerOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_RewardManager *RewardManagerFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*RewardManagerOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _RewardManager.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &RewardManagerOwnershipTransferredIterator{contract: _RewardManager.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_RewardManager *RewardManagerFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *RewardManagerOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _RewardManager.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(RewardManagerOwnershipTransferred) + if err := _RewardManager.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_RewardManager *RewardManagerFilterer) ParseOwnershipTransferred(log types.Log) (*RewardManagerOwnershipTransferred, error) { + event := new(RewardManagerOwnershipTransferred) + if err := _RewardManager.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type RewardManagerRewardRecipientsUpdatedIterator struct { + Event *RewardManagerRewardRecipientsUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *RewardManagerRewardRecipientsUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(RewardManagerRewardRecipientsUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(RewardManagerRewardRecipientsUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *RewardManagerRewardRecipientsUpdatedIterator) Error() error { + return it.fail +} + +func (it *RewardManagerRewardRecipientsUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type RewardManagerRewardRecipientsUpdated struct { + PoolId [32]byte + NewRewardRecipients []CommonAddressAndWeight + Raw types.Log +} + +func (_RewardManager *RewardManagerFilterer) FilterRewardRecipientsUpdated(opts *bind.FilterOpts, poolId [][32]byte) (*RewardManagerRewardRecipientsUpdatedIterator, error) { + + var poolIdRule []interface{} + for _, poolIdItem := range poolId { + poolIdRule = append(poolIdRule, poolIdItem) + } + + logs, sub, err := _RewardManager.contract.FilterLogs(opts, "RewardRecipientsUpdated", poolIdRule) + if err != nil { + return nil, err + } + return &RewardManagerRewardRecipientsUpdatedIterator{contract: _RewardManager.contract, event: "RewardRecipientsUpdated", logs: logs, sub: sub}, nil +} + +func (_RewardManager *RewardManagerFilterer) WatchRewardRecipientsUpdated(opts *bind.WatchOpts, sink chan<- *RewardManagerRewardRecipientsUpdated, poolId [][32]byte) (event.Subscription, error) { + + var poolIdRule []interface{} + for _, poolIdItem := range poolId { + poolIdRule = append(poolIdRule, poolIdItem) + } + + logs, sub, err := _RewardManager.contract.WatchLogs(opts, "RewardRecipientsUpdated", poolIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(RewardManagerRewardRecipientsUpdated) + if err := _RewardManager.contract.UnpackLog(event, "RewardRecipientsUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_RewardManager *RewardManagerFilterer) ParseRewardRecipientsUpdated(log types.Log) (*RewardManagerRewardRecipientsUpdated, error) { + event := new(RewardManagerRewardRecipientsUpdated) + if err := _RewardManager.contract.UnpackLog(event, "RewardRecipientsUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type RewardManagerRewardsClaimedIterator struct { + Event *RewardManagerRewardsClaimed + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *RewardManagerRewardsClaimedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(RewardManagerRewardsClaimed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(RewardManagerRewardsClaimed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *RewardManagerRewardsClaimedIterator) Error() error { + return it.fail +} + +func (it *RewardManagerRewardsClaimedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type RewardManagerRewardsClaimed struct { + PoolId [32]byte + Recipient common.Address + Quantity *big.Int + Raw types.Log +} + +func (_RewardManager *RewardManagerFilterer) FilterRewardsClaimed(opts *bind.FilterOpts, poolId [][32]byte, recipient []common.Address) (*RewardManagerRewardsClaimedIterator, error) { + + var poolIdRule []interface{} + for _, poolIdItem := range poolId { + poolIdRule = append(poolIdRule, poolIdItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _RewardManager.contract.FilterLogs(opts, "RewardsClaimed", poolIdRule, recipientRule) + if err != nil { + return nil, err + } + return &RewardManagerRewardsClaimedIterator{contract: _RewardManager.contract, event: "RewardsClaimed", logs: logs, sub: sub}, nil +} + +func (_RewardManager *RewardManagerFilterer) WatchRewardsClaimed(opts *bind.WatchOpts, sink chan<- *RewardManagerRewardsClaimed, poolId [][32]byte, recipient []common.Address) (event.Subscription, error) { + + var poolIdRule []interface{} + for _, poolIdItem := range poolId { + poolIdRule = append(poolIdRule, poolIdItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _RewardManager.contract.WatchLogs(opts, "RewardsClaimed", poolIdRule, recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(RewardManagerRewardsClaimed) + if err := _RewardManager.contract.UnpackLog(event, "RewardsClaimed", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_RewardManager *RewardManagerFilterer) ParseRewardsClaimed(log types.Log) (*RewardManagerRewardsClaimed, error) { + event := new(RewardManagerRewardsClaimed) + if err := _RewardManager.contract.UnpackLog(event, "RewardsClaimed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_RewardManager *RewardManager) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _RewardManager.abi.Events["FeeManagerUpdated"].ID: + return _RewardManager.ParseFeeManagerUpdated(log) + case _RewardManager.abi.Events["FeePaid"].ID: + return _RewardManager.ParseFeePaid(log) + case _RewardManager.abi.Events["OwnershipTransferRequested"].ID: + return _RewardManager.ParseOwnershipTransferRequested(log) + case _RewardManager.abi.Events["OwnershipTransferred"].ID: + return _RewardManager.ParseOwnershipTransferred(log) + case _RewardManager.abi.Events["RewardRecipientsUpdated"].ID: + return _RewardManager.ParseRewardRecipientsUpdated(log) + case _RewardManager.abi.Events["RewardsClaimed"].ID: + return _RewardManager.ParseRewardsClaimed(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (RewardManagerFeeManagerUpdated) Topic() common.Hash { + return common.HexToHash("0xe45f5e140399b0a7e12971ab020724b828fbed8ac408c420884dc7d1bbe506b4") +} + +func (RewardManagerFeePaid) Topic() common.Hash { + return common.HexToHash("0xa1cc025ea76bacce5d740ee4bc331899375dc2c5f2ab33933aaacbd9ba001b66") +} + +func (RewardManagerOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (RewardManagerOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (RewardManagerRewardRecipientsUpdated) Topic() common.Hash { + return common.HexToHash("0x8f668d6090683f98b3373a8b83d214da45737f7486cb7de554cc07b54e61cfe6") +} + +func (RewardManagerRewardsClaimed) Topic() common.Hash { + return common.HexToHash("0x989969655bc1d593922527fe85d71347bb8e12fa423cc71f362dd8ef7cb10ef2") +} + +func (_RewardManager *RewardManager) Address() common.Address { + return _RewardManager.address +} + +type RewardManagerInterface interface { + GetAvailableRewardPoolIds(opts *bind.CallOpts, recipient common.Address, startIndex *big.Int, endIndex *big.Int) ([][32]byte, error) + + ILinkAddress(opts *bind.CallOpts) (common.Address, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + SFeeManagerAddress(opts *bind.CallOpts) (common.Address, error) + + SRegisteredPoolIds(opts *bind.CallOpts, arg0 *big.Int) ([32]byte, error) + + SRewardRecipientWeights(opts *bind.CallOpts, arg0 [32]byte, arg1 common.Address) (*big.Int, error) + + SRewardRecipientWeightsSet(opts *bind.CallOpts, arg0 [32]byte) (bool, error) + + STotalRewardRecipientFees(opts *bind.CallOpts, arg0 [32]byte) (*big.Int, error) + + STotalRewardRecipientFeesLastClaimedAmounts(opts *bind.CallOpts, arg0 [32]byte, arg1 common.Address) (*big.Int, error) + + SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + ClaimRewards(opts *bind.TransactOpts, poolIds [][32]byte) (*types.Transaction, error) + + OnFeePaid(opts *bind.TransactOpts, payments []IRewardManagerFeePayment, payer common.Address) (*types.Transaction, error) + + PayRecipients(opts *bind.TransactOpts, poolId [32]byte, recipients []common.Address) (*types.Transaction, error) + + SetFeeManager(opts *bind.TransactOpts, newFeeManagerAddress common.Address) (*types.Transaction, error) + + SetRewardRecipients(opts *bind.TransactOpts, poolId [32]byte, rewardRecipientAndWeights []CommonAddressAndWeight) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + UpdateRewardRecipients(opts *bind.TransactOpts, poolId [32]byte, newRewardRecipients []CommonAddressAndWeight) (*types.Transaction, error) + + FilterFeeManagerUpdated(opts *bind.FilterOpts) (*RewardManagerFeeManagerUpdatedIterator, error) + + WatchFeeManagerUpdated(opts *bind.WatchOpts, sink chan<- *RewardManagerFeeManagerUpdated) (event.Subscription, error) + + ParseFeeManagerUpdated(log types.Log) (*RewardManagerFeeManagerUpdated, error) + + FilterFeePaid(opts *bind.FilterOpts) (*RewardManagerFeePaidIterator, error) + + WatchFeePaid(opts *bind.WatchOpts, sink chan<- *RewardManagerFeePaid) (event.Subscription, error) + + ParseFeePaid(log types.Log) (*RewardManagerFeePaid, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*RewardManagerOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *RewardManagerOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*RewardManagerOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*RewardManagerOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *RewardManagerOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*RewardManagerOwnershipTransferred, error) + + FilterRewardRecipientsUpdated(opts *bind.FilterOpts, poolId [][32]byte) (*RewardManagerRewardRecipientsUpdatedIterator, error) + + WatchRewardRecipientsUpdated(opts *bind.WatchOpts, sink chan<- *RewardManagerRewardRecipientsUpdated, poolId [][32]byte) (event.Subscription, error) + + ParseRewardRecipientsUpdated(log types.Log) (*RewardManagerRewardRecipientsUpdated, error) + + FilterRewardsClaimed(opts *bind.FilterOpts, poolId [][32]byte, recipient []common.Address) (*RewardManagerRewardsClaimedIterator, error) + + WatchRewardsClaimed(opts *bind.WatchOpts, sink chan<- *RewardManagerRewardsClaimed, poolId [][32]byte, recipient []common.Address) (event.Subscription, error) + + ParseRewardsClaimed(log types.Log) (*RewardManagerRewardsClaimed, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/llo-feeds/generated/verifier_proxy_v0_5_0/verifier_proxy_v0_5_0.go b/core/gethwrappers/llo-feeds/generated/verifier_proxy_v0_5_0/verifier_proxy_v0_5_0.go new file mode 100644 index 00000000000..606c30017dd --- /dev/null +++ b/core/gethwrappers/llo-feeds/generated/verifier_proxy_v0_5_0/verifier_proxy_v0_5_0.go @@ -0,0 +1,1387 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package verifier_proxy_v0_5_0 + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type CommonAddressAndWeight struct { + Addr common.Address + Weight uint64 +} + +var VerifierProxyMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"contractAccessControllerInterface\",\"name\":\"accessController\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AccessForbidden\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BadVerification\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"verifier\",\"type\":\"address\"}],\"name\":\"ConfigDigestAlreadySet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FeeManagerInvalid\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"verifier\",\"type\":\"address\"}],\"name\":\"VerifierAlreadyInitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerifierInvalid\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"VerifierNotFound\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldAccessController\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAccessController\",\"type\":\"address\"}],\"name\":\"AccessControllerSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldFeeManager\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newFeeManager\",\"type\":\"address\"}],\"name\":\"FeeManagerSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"verifierAddress\",\"type\":\"address\"}],\"name\":\"VerifierInitialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"oldConfigDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"newConfigDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"verifierAddress\",\"type\":\"address\"}],\"name\":\"VerifierSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"verifierAddress\",\"type\":\"address\"}],\"name\":\"VerifierUnset\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"getVerifier\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"verifierAddress\",\"type\":\"address\"}],\"name\":\"initializeVerifier\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_accessController\",\"outputs\":[{\"internalType\":\"contractAccessControllerInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_feeManager\",\"outputs\":[{\"internalType\":\"contractIVerifierFeeManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractAccessControllerInterface\",\"name\":\"accessController\",\"type\":\"address\"}],\"name\":\"setAccessController\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIVerifierFeeManager\",\"name\":\"feeManager\",\"type\":\"address\"}],\"name\":\"setFeeManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"currentConfigDigest\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"newConfigDigest\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"addressesAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"setVerifier\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"unsetVerifier\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"parameterPayload\",\"type\":\"bytes\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes[]\",\"name\":\"payloads\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"parameterPayload\",\"type\":\"bytes\"}],\"name\":\"verifyBulk\",\"outputs\":[{\"internalType\":\"bytes[]\",\"name\":\"verifiedReports\",\"type\":\"bytes[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}]", + Bin: "0x60806040523480156200001157600080fd5b5060405162001d3638038062001d36833981016040819052620000349162000193565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000e8565b5050600480546001600160a01b0319166001600160a01b03939093169290921790915550620001c5565b336001600160a01b03821603620001425760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060208284031215620001a657600080fd5b81516001600160a01b0381168114620001be57600080fd5b9392505050565b611b6180620001d56000396000f3fe6080604052600436106100dd5760003560e01c806394ba28461161007f578063f08391d811610059578063f08391d8146102be578063f2fde38b146102de578063f7e83aee146102fe578063f873a61c1461031157600080fd5b806394ba28461461022e578063b011b2471461025b578063eeb7b2481461027b57600080fd5b80636e914094116100bb5780636e914094146101ae57806379ba5097146101ce5780638c2a4d53146101e35780638da5cb5b1461020357600080fd5b8063181f5a77146100e257806338416b5b1461013a578063472d35b91461018c575b600080fd5b3480156100ee57600080fd5b5060408051808201909152601381527f566572696669657250726f787920322e302e300000000000000000000000000060208201525b60405161013191906113c3565b60405180910390f35b34801561014657600080fd5b506005546101679073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610131565b34801561019857600080fd5b506101ac6101a73660046113ff565b610331565b005b3480156101ba57600080fd5b506101ac6101c936600461141c565b6105a9565b3480156101da57600080fd5b506101ac61069a565b3480156101ef57600080fd5b506101ac6101fe3660046113ff565b610797565b34801561020f57600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff16610167565b34801561023a57600080fd5b506004546101679073ffffffffffffffffffffffffffffffffffffffff1681565b34801561026757600080fd5b506101ac610276366004611435565b6109c8565b34801561028757600080fd5b5061016761029636600461141c565b60009081526003602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b3480156102ca57600080fd5b506101ac6102d93660046113ff565b610bee565b3480156102ea57600080fd5b506101ac6102f93660046113ff565b610c75565b61012461030c366004611501565b610c89565b61032461031f36600461156d565b610e43565b60405161013191906115ee565b6103396110a7565b73ffffffffffffffffffffffffffffffffffffffff8116610386576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527fdba45fe000000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa158015610410573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610434919061166e565b15806104eb57506040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f6c2f1a1700000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa1580156104c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104e9919061166e565b155b15610522576040517f8238941900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6005805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f04628abcaa6b1674651352125cb94b65b289145bc2bc4d67720bb7d966372f0391015b60405180910390a15050565b6105b16110a7565b60008181526003602052604090205473ffffffffffffffffffffffffffffffffffffffff1680610615576040517fb151802b000000000000000000000000000000000000000000000000000000008152600481018390526024015b60405180910390fd5b6000828152600360205260409081902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055517f11dc15c4b8ac2b183166cc8427e5385a5ece8308217a4217338c6a7614845c4c9061059d908490849091825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b60015473ffffffffffffffffffffffffffffffffffffffff16331461071b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161060c565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b61079f6110a7565b8073ffffffffffffffffffffffffffffffffffffffff81166107ed576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f3d3ac1b500000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa158015610877573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061089b919061166e565b6108d1576040517f75b0527a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821660009081526002602052604090205460ff1615610949576040517f4e01ccfd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8316600482015260240161060c565b73ffffffffffffffffffffffffffffffffffffffff821660008181526002602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905590519182527f1f2cd7c97f4d801b5efe26cc409617c1fd6c5ef786e79aacb90af40923e4e8e9910161059d565b600083815260036020526040902054839073ffffffffffffffffffffffffffffffffffffffff168015610a46576040517f375d1fe60000000000000000000000000000000000000000000000000000000081526004810183905273ffffffffffffffffffffffffffffffffffffffff8216602482015260440161060c565b3360009081526002602052604090205460ff16610a8f576040517fef67f5d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600085815260036020526040902080547fffffffffffffffffffffffff000000000000000000000000000000000000000016331790558215610ba75760055473ffffffffffffffffffffffffffffffffffffffff16610b1a576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6005546040517ff65df96200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063f65df96290610b7490889088908890600401611690565b600060405180830381600087803b158015610b8e57600080fd5b505af1158015610ba2573d6000803e3d6000fd5b505050505b6040805187815260208101879052338183015290517fbeb513e532542a562ac35699e7cd9ae7d198dcd3eee15bada6c857d28ceaddcf9181900360600190a1505050505050565b610bf66110a7565b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f953e92b1a6442e9c3242531154a3f6f6eb00b4e9c719ba8118fa6235e4ce89b6910161059d565b610c7d6110a7565b610c868161112a565b50565b60045460609073ffffffffffffffffffffffffffffffffffffffff168015801590610d4957506040517f6b14daf800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821690636b14daf890610d069033906000903690600401611762565b602060405180830381865afa158015610d23573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d47919061166e565b155b15610d80576040517fef67f5d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60055473ffffffffffffffffffffffffffffffffffffffff168015610e2e576040517fdba45fe000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82169063dba45fe0903490610dfb908b908b908b908b90339060040161179b565b6000604051808303818588803b158015610e1457600080fd5b505af1158015610e28573d6000803e3d6000fd5b50505050505b610e38878761121f565b979650505050505050565b60045460609073ffffffffffffffffffffffffffffffffffffffff168015801590610f0357506040517f6b14daf800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821690636b14daf890610ec09033906000903690600401611762565b602060405180830381865afa158015610edd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f01919061166e565b155b15610f3a576040517fef67f5d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60055473ffffffffffffffffffffffffffffffffffffffff168015610fe8576040517f6c2f1a1700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821690636c2f1a17903490610fb5908b908b908b908b9033906004016117eb565b6000604051808303818588803b158015610fce57600080fd5b505af1158015610fe2573d6000803e3d6000fd5b50505050505b8567ffffffffffffffff811115611001576110016118fc565b60405190808252806020026020018201604052801561103457816020015b606081526020019060019003908161101f5790505b50925060005b8681101561109c5761106e8888838181106110575761105761192b565b9050602002810190611069919061195a565b61121f565b8482815181106110805761108061192b565b602002602001018190525080611095906119bf565b905061103a565b505050949350505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611128576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161060c565b565b3373ffffffffffffffffffffffffffffffffffffffff8216036111a9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161060c565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6060600061122d8385611a1e565b60008181526003602052604090205490915073ffffffffffffffffffffffffffffffffffffffff168061128f576040517fb151802b0000000000000000000000000000000000000000000000000000000081526004810183905260240161060c565b6040517f3d3ac1b500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821690633d3ac1b5906112e590889088903390600401611a5a565b6000604051808303816000875af1158015611304573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261134a9190810190611a94565b925050505b92915050565b60005b83811015611370578181015183820152602001611358565b50506000910152565b60008151808452611391816020860160208601611355565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006113d66020830184611379565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff81168114610c8657600080fd5b60006020828403121561141157600080fd5b81356113d6816113dd565b60006020828403121561142e57600080fd5b5035919050565b6000806000806060858703121561144b57600080fd5b8435935060208501359250604085013567ffffffffffffffff8082111561147157600080fd5b818701915087601f83011261148557600080fd5b81358181111561149457600080fd5b8860208260061b85010111156114a957600080fd5b95989497505060200194505050565b60008083601f8401126114ca57600080fd5b50813567ffffffffffffffff8111156114e257600080fd5b6020830191508360208285010111156114fa57600080fd5b9250929050565b6000806000806040858703121561151757600080fd5b843567ffffffffffffffff8082111561152f57600080fd5b61153b888389016114b8565b9096509450602087013591508082111561155457600080fd5b50611561878288016114b8565b95989497509550505050565b6000806000806040858703121561158357600080fd5b843567ffffffffffffffff8082111561159b57600080fd5b818701915087601f8301126115af57600080fd5b8135818111156115be57600080fd5b8860208260051b85010111156115d357600080fd5b60209283019650945090860135908082111561155457600080fd5b6000602080830181845280855180835260408601915060408160051b870101925083870160005b82811015611661577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc088860301845261164f858351611379565b94509285019290850190600101611615565b5092979650505050505050565b60006020828403121561168057600080fd5b815180151581146113d657600080fd5b838152604060208083018290528282018490526000919085906060850184805b8881101561170a5784356116c3816113dd565b73ffffffffffffffffffffffffffffffffffffffff1683528484013567ffffffffffffffff81168082146116f5578384fd5b848601525093850193918501916001016116b0565b50909998505050505050505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff84168152604060208201526000611792604083018486611719565b95945050505050565b6060815260006117af606083018789611719565b82810360208401526117c2818688611719565b91505073ffffffffffffffffffffffffffffffffffffffff831660408301529695505050505050565b6060808252810185905260006080600587901b8301810190830188835b898110156118b7577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8086850301835281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18c360301811261186957600080fd5b8b01602081810191359067ffffffffffffffff82111561188857600080fd5b81360383131561189757600080fd5b6118a2878385611719565b96509485019493909301925050600101611808565b50505082810360208401526118cd818688611719565b9150506118f2604083018473ffffffffffffffffffffffffffffffffffffffff169052565b9695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261198f57600080fd5b83018035915067ffffffffffffffff8211156119aa57600080fd5b6020019150368190038213156114fa57600080fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611a17577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b8035602083101561134f577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff602084900360031b1b1692915050565b604081526000611a6e604083018587611719565b905073ffffffffffffffffffffffffffffffffffffffff83166020830152949350505050565b600060208284031215611aa657600080fd5b815167ffffffffffffffff80821115611abe57600080fd5b818401915084601f830112611ad257600080fd5b815181811115611ae457611ae46118fc565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715611b2a57611b2a6118fc565b81604052828152876020848701011115611b4357600080fd5b610e3883602083016020880161135556fea164736f6c6343000813000a", +} + +var VerifierProxyABI = VerifierProxyMetaData.ABI + +var VerifierProxyBin = VerifierProxyMetaData.Bin + +func DeployVerifierProxy(auth *bind.TransactOpts, backend bind.ContractBackend, accessController common.Address) (common.Address, *types.Transaction, *VerifierProxy, error) { + parsed, err := VerifierProxyMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(VerifierProxyBin), backend, accessController) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &VerifierProxy{address: address, abi: *parsed, VerifierProxyCaller: VerifierProxyCaller{contract: contract}, VerifierProxyTransactor: VerifierProxyTransactor{contract: contract}, VerifierProxyFilterer: VerifierProxyFilterer{contract: contract}}, nil +} + +type VerifierProxy struct { + address common.Address + abi abi.ABI + VerifierProxyCaller + VerifierProxyTransactor + VerifierProxyFilterer +} + +type VerifierProxyCaller struct { + contract *bind.BoundContract +} + +type VerifierProxyTransactor struct { + contract *bind.BoundContract +} + +type VerifierProxyFilterer struct { + contract *bind.BoundContract +} + +type VerifierProxySession struct { + Contract *VerifierProxy + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type VerifierProxyCallerSession struct { + Contract *VerifierProxyCaller + CallOpts bind.CallOpts +} + +type VerifierProxyTransactorSession struct { + Contract *VerifierProxyTransactor + TransactOpts bind.TransactOpts +} + +type VerifierProxyRaw struct { + Contract *VerifierProxy +} + +type VerifierProxyCallerRaw struct { + Contract *VerifierProxyCaller +} + +type VerifierProxyTransactorRaw struct { + Contract *VerifierProxyTransactor +} + +func NewVerifierProxy(address common.Address, backend bind.ContractBackend) (*VerifierProxy, error) { + abi, err := abi.JSON(strings.NewReader(VerifierProxyABI)) + if err != nil { + return nil, err + } + contract, err := bindVerifierProxy(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &VerifierProxy{address: address, abi: abi, VerifierProxyCaller: VerifierProxyCaller{contract: contract}, VerifierProxyTransactor: VerifierProxyTransactor{contract: contract}, VerifierProxyFilterer: VerifierProxyFilterer{contract: contract}}, nil +} + +func NewVerifierProxyCaller(address common.Address, caller bind.ContractCaller) (*VerifierProxyCaller, error) { + contract, err := bindVerifierProxy(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &VerifierProxyCaller{contract: contract}, nil +} + +func NewVerifierProxyTransactor(address common.Address, transactor bind.ContractTransactor) (*VerifierProxyTransactor, error) { + contract, err := bindVerifierProxy(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &VerifierProxyTransactor{contract: contract}, nil +} + +func NewVerifierProxyFilterer(address common.Address, filterer bind.ContractFilterer) (*VerifierProxyFilterer, error) { + contract, err := bindVerifierProxy(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &VerifierProxyFilterer{contract: contract}, nil +} + +func bindVerifierProxy(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := VerifierProxyMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_VerifierProxy *VerifierProxyRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _VerifierProxy.Contract.VerifierProxyCaller.contract.Call(opts, result, method, params...) +} + +func (_VerifierProxy *VerifierProxyRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _VerifierProxy.Contract.VerifierProxyTransactor.contract.Transfer(opts) +} + +func (_VerifierProxy *VerifierProxyRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _VerifierProxy.Contract.VerifierProxyTransactor.contract.Transact(opts, method, params...) +} + +func (_VerifierProxy *VerifierProxyCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _VerifierProxy.Contract.contract.Call(opts, result, method, params...) +} + +func (_VerifierProxy *VerifierProxyTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _VerifierProxy.Contract.contract.Transfer(opts) +} + +func (_VerifierProxy *VerifierProxyTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _VerifierProxy.Contract.contract.Transact(opts, method, params...) +} + +func (_VerifierProxy *VerifierProxyCaller) GetVerifier(opts *bind.CallOpts, configDigest [32]byte) (common.Address, error) { + var out []interface{} + err := _VerifierProxy.contract.Call(opts, &out, "getVerifier", configDigest) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_VerifierProxy *VerifierProxySession) GetVerifier(configDigest [32]byte) (common.Address, error) { + return _VerifierProxy.Contract.GetVerifier(&_VerifierProxy.CallOpts, configDigest) +} + +func (_VerifierProxy *VerifierProxyCallerSession) GetVerifier(configDigest [32]byte) (common.Address, error) { + return _VerifierProxy.Contract.GetVerifier(&_VerifierProxy.CallOpts, configDigest) +} + +func (_VerifierProxy *VerifierProxyCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _VerifierProxy.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_VerifierProxy *VerifierProxySession) Owner() (common.Address, error) { + return _VerifierProxy.Contract.Owner(&_VerifierProxy.CallOpts) +} + +func (_VerifierProxy *VerifierProxyCallerSession) Owner() (common.Address, error) { + return _VerifierProxy.Contract.Owner(&_VerifierProxy.CallOpts) +} + +func (_VerifierProxy *VerifierProxyCaller) SAccessController(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _VerifierProxy.contract.Call(opts, &out, "s_accessController") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_VerifierProxy *VerifierProxySession) SAccessController() (common.Address, error) { + return _VerifierProxy.Contract.SAccessController(&_VerifierProxy.CallOpts) +} + +func (_VerifierProxy *VerifierProxyCallerSession) SAccessController() (common.Address, error) { + return _VerifierProxy.Contract.SAccessController(&_VerifierProxy.CallOpts) +} + +func (_VerifierProxy *VerifierProxyCaller) SFeeManager(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _VerifierProxy.contract.Call(opts, &out, "s_feeManager") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_VerifierProxy *VerifierProxySession) SFeeManager() (common.Address, error) { + return _VerifierProxy.Contract.SFeeManager(&_VerifierProxy.CallOpts) +} + +func (_VerifierProxy *VerifierProxyCallerSession) SFeeManager() (common.Address, error) { + return _VerifierProxy.Contract.SFeeManager(&_VerifierProxy.CallOpts) +} + +func (_VerifierProxy *VerifierProxyCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _VerifierProxy.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_VerifierProxy *VerifierProxySession) TypeAndVersion() (string, error) { + return _VerifierProxy.Contract.TypeAndVersion(&_VerifierProxy.CallOpts) +} + +func (_VerifierProxy *VerifierProxyCallerSession) TypeAndVersion() (string, error) { + return _VerifierProxy.Contract.TypeAndVersion(&_VerifierProxy.CallOpts) +} + +func (_VerifierProxy *VerifierProxyTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _VerifierProxy.contract.Transact(opts, "acceptOwnership") +} + +func (_VerifierProxy *VerifierProxySession) AcceptOwnership() (*types.Transaction, error) { + return _VerifierProxy.Contract.AcceptOwnership(&_VerifierProxy.TransactOpts) +} + +func (_VerifierProxy *VerifierProxyTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _VerifierProxy.Contract.AcceptOwnership(&_VerifierProxy.TransactOpts) +} + +func (_VerifierProxy *VerifierProxyTransactor) InitializeVerifier(opts *bind.TransactOpts, verifierAddress common.Address) (*types.Transaction, error) { + return _VerifierProxy.contract.Transact(opts, "initializeVerifier", verifierAddress) +} + +func (_VerifierProxy *VerifierProxySession) InitializeVerifier(verifierAddress common.Address) (*types.Transaction, error) { + return _VerifierProxy.Contract.InitializeVerifier(&_VerifierProxy.TransactOpts, verifierAddress) +} + +func (_VerifierProxy *VerifierProxyTransactorSession) InitializeVerifier(verifierAddress common.Address) (*types.Transaction, error) { + return _VerifierProxy.Contract.InitializeVerifier(&_VerifierProxy.TransactOpts, verifierAddress) +} + +func (_VerifierProxy *VerifierProxyTransactor) SetAccessController(opts *bind.TransactOpts, accessController common.Address) (*types.Transaction, error) { + return _VerifierProxy.contract.Transact(opts, "setAccessController", accessController) +} + +func (_VerifierProxy *VerifierProxySession) SetAccessController(accessController common.Address) (*types.Transaction, error) { + return _VerifierProxy.Contract.SetAccessController(&_VerifierProxy.TransactOpts, accessController) +} + +func (_VerifierProxy *VerifierProxyTransactorSession) SetAccessController(accessController common.Address) (*types.Transaction, error) { + return _VerifierProxy.Contract.SetAccessController(&_VerifierProxy.TransactOpts, accessController) +} + +func (_VerifierProxy *VerifierProxyTransactor) SetFeeManager(opts *bind.TransactOpts, feeManager common.Address) (*types.Transaction, error) { + return _VerifierProxy.contract.Transact(opts, "setFeeManager", feeManager) +} + +func (_VerifierProxy *VerifierProxySession) SetFeeManager(feeManager common.Address) (*types.Transaction, error) { + return _VerifierProxy.Contract.SetFeeManager(&_VerifierProxy.TransactOpts, feeManager) +} + +func (_VerifierProxy *VerifierProxyTransactorSession) SetFeeManager(feeManager common.Address) (*types.Transaction, error) { + return _VerifierProxy.Contract.SetFeeManager(&_VerifierProxy.TransactOpts, feeManager) +} + +func (_VerifierProxy *VerifierProxyTransactor) SetVerifier(opts *bind.TransactOpts, currentConfigDigest [32]byte, newConfigDigest [32]byte, addressesAndWeights []CommonAddressAndWeight) (*types.Transaction, error) { + return _VerifierProxy.contract.Transact(opts, "setVerifier", currentConfigDigest, newConfigDigest, addressesAndWeights) +} + +func (_VerifierProxy *VerifierProxySession) SetVerifier(currentConfigDigest [32]byte, newConfigDigest [32]byte, addressesAndWeights []CommonAddressAndWeight) (*types.Transaction, error) { + return _VerifierProxy.Contract.SetVerifier(&_VerifierProxy.TransactOpts, currentConfigDigest, newConfigDigest, addressesAndWeights) +} + +func (_VerifierProxy *VerifierProxyTransactorSession) SetVerifier(currentConfigDigest [32]byte, newConfigDigest [32]byte, addressesAndWeights []CommonAddressAndWeight) (*types.Transaction, error) { + return _VerifierProxy.Contract.SetVerifier(&_VerifierProxy.TransactOpts, currentConfigDigest, newConfigDigest, addressesAndWeights) +} + +func (_VerifierProxy *VerifierProxyTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _VerifierProxy.contract.Transact(opts, "transferOwnership", to) +} + +func (_VerifierProxy *VerifierProxySession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _VerifierProxy.Contract.TransferOwnership(&_VerifierProxy.TransactOpts, to) +} + +func (_VerifierProxy *VerifierProxyTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _VerifierProxy.Contract.TransferOwnership(&_VerifierProxy.TransactOpts, to) +} + +func (_VerifierProxy *VerifierProxyTransactor) UnsetVerifier(opts *bind.TransactOpts, configDigest [32]byte) (*types.Transaction, error) { + return _VerifierProxy.contract.Transact(opts, "unsetVerifier", configDigest) +} + +func (_VerifierProxy *VerifierProxySession) UnsetVerifier(configDigest [32]byte) (*types.Transaction, error) { + return _VerifierProxy.Contract.UnsetVerifier(&_VerifierProxy.TransactOpts, configDigest) +} + +func (_VerifierProxy *VerifierProxyTransactorSession) UnsetVerifier(configDigest [32]byte) (*types.Transaction, error) { + return _VerifierProxy.Contract.UnsetVerifier(&_VerifierProxy.TransactOpts, configDigest) +} + +func (_VerifierProxy *VerifierProxyTransactor) Verify(opts *bind.TransactOpts, payload []byte, parameterPayload []byte) (*types.Transaction, error) { + return _VerifierProxy.contract.Transact(opts, "verify", payload, parameterPayload) +} + +func (_VerifierProxy *VerifierProxySession) Verify(payload []byte, parameterPayload []byte) (*types.Transaction, error) { + return _VerifierProxy.Contract.Verify(&_VerifierProxy.TransactOpts, payload, parameterPayload) +} + +func (_VerifierProxy *VerifierProxyTransactorSession) Verify(payload []byte, parameterPayload []byte) (*types.Transaction, error) { + return _VerifierProxy.Contract.Verify(&_VerifierProxy.TransactOpts, payload, parameterPayload) +} + +func (_VerifierProxy *VerifierProxyTransactor) VerifyBulk(opts *bind.TransactOpts, payloads [][]byte, parameterPayload []byte) (*types.Transaction, error) { + return _VerifierProxy.contract.Transact(opts, "verifyBulk", payloads, parameterPayload) +} + +func (_VerifierProxy *VerifierProxySession) VerifyBulk(payloads [][]byte, parameterPayload []byte) (*types.Transaction, error) { + return _VerifierProxy.Contract.VerifyBulk(&_VerifierProxy.TransactOpts, payloads, parameterPayload) +} + +func (_VerifierProxy *VerifierProxyTransactorSession) VerifyBulk(payloads [][]byte, parameterPayload []byte) (*types.Transaction, error) { + return _VerifierProxy.Contract.VerifyBulk(&_VerifierProxy.TransactOpts, payloads, parameterPayload) +} + +type VerifierProxyAccessControllerSetIterator struct { + Event *VerifierProxyAccessControllerSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VerifierProxyAccessControllerSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VerifierProxyAccessControllerSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VerifierProxyAccessControllerSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VerifierProxyAccessControllerSetIterator) Error() error { + return it.fail +} + +func (it *VerifierProxyAccessControllerSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VerifierProxyAccessControllerSet struct { + OldAccessController common.Address + NewAccessController common.Address + Raw types.Log +} + +func (_VerifierProxy *VerifierProxyFilterer) FilterAccessControllerSet(opts *bind.FilterOpts) (*VerifierProxyAccessControllerSetIterator, error) { + + logs, sub, err := _VerifierProxy.contract.FilterLogs(opts, "AccessControllerSet") + if err != nil { + return nil, err + } + return &VerifierProxyAccessControllerSetIterator{contract: _VerifierProxy.contract, event: "AccessControllerSet", logs: logs, sub: sub}, nil +} + +func (_VerifierProxy *VerifierProxyFilterer) WatchAccessControllerSet(opts *bind.WatchOpts, sink chan<- *VerifierProxyAccessControllerSet) (event.Subscription, error) { + + logs, sub, err := _VerifierProxy.contract.WatchLogs(opts, "AccessControllerSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VerifierProxyAccessControllerSet) + if err := _VerifierProxy.contract.UnpackLog(event, "AccessControllerSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VerifierProxy *VerifierProxyFilterer) ParseAccessControllerSet(log types.Log) (*VerifierProxyAccessControllerSet, error) { + event := new(VerifierProxyAccessControllerSet) + if err := _VerifierProxy.contract.UnpackLog(event, "AccessControllerSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VerifierProxyFeeManagerSetIterator struct { + Event *VerifierProxyFeeManagerSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VerifierProxyFeeManagerSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VerifierProxyFeeManagerSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VerifierProxyFeeManagerSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VerifierProxyFeeManagerSetIterator) Error() error { + return it.fail +} + +func (it *VerifierProxyFeeManagerSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VerifierProxyFeeManagerSet struct { + OldFeeManager common.Address + NewFeeManager common.Address + Raw types.Log +} + +func (_VerifierProxy *VerifierProxyFilterer) FilterFeeManagerSet(opts *bind.FilterOpts) (*VerifierProxyFeeManagerSetIterator, error) { + + logs, sub, err := _VerifierProxy.contract.FilterLogs(opts, "FeeManagerSet") + if err != nil { + return nil, err + } + return &VerifierProxyFeeManagerSetIterator{contract: _VerifierProxy.contract, event: "FeeManagerSet", logs: logs, sub: sub}, nil +} + +func (_VerifierProxy *VerifierProxyFilterer) WatchFeeManagerSet(opts *bind.WatchOpts, sink chan<- *VerifierProxyFeeManagerSet) (event.Subscription, error) { + + logs, sub, err := _VerifierProxy.contract.WatchLogs(opts, "FeeManagerSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VerifierProxyFeeManagerSet) + if err := _VerifierProxy.contract.UnpackLog(event, "FeeManagerSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VerifierProxy *VerifierProxyFilterer) ParseFeeManagerSet(log types.Log) (*VerifierProxyFeeManagerSet, error) { + event := new(VerifierProxyFeeManagerSet) + if err := _VerifierProxy.contract.UnpackLog(event, "FeeManagerSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VerifierProxyOwnershipTransferRequestedIterator struct { + Event *VerifierProxyOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VerifierProxyOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VerifierProxyOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VerifierProxyOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VerifierProxyOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *VerifierProxyOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VerifierProxyOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_VerifierProxy *VerifierProxyFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VerifierProxyOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _VerifierProxy.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &VerifierProxyOwnershipTransferRequestedIterator{contract: _VerifierProxy.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_VerifierProxy *VerifierProxyFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *VerifierProxyOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _VerifierProxy.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VerifierProxyOwnershipTransferRequested) + if err := _VerifierProxy.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VerifierProxy *VerifierProxyFilterer) ParseOwnershipTransferRequested(log types.Log) (*VerifierProxyOwnershipTransferRequested, error) { + event := new(VerifierProxyOwnershipTransferRequested) + if err := _VerifierProxy.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VerifierProxyOwnershipTransferredIterator struct { + Event *VerifierProxyOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VerifierProxyOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VerifierProxyOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VerifierProxyOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VerifierProxyOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *VerifierProxyOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VerifierProxyOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_VerifierProxy *VerifierProxyFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VerifierProxyOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _VerifierProxy.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &VerifierProxyOwnershipTransferredIterator{contract: _VerifierProxy.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_VerifierProxy *VerifierProxyFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *VerifierProxyOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _VerifierProxy.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VerifierProxyOwnershipTransferred) + if err := _VerifierProxy.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VerifierProxy *VerifierProxyFilterer) ParseOwnershipTransferred(log types.Log) (*VerifierProxyOwnershipTransferred, error) { + event := new(VerifierProxyOwnershipTransferred) + if err := _VerifierProxy.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VerifierProxyVerifierInitializedIterator struct { + Event *VerifierProxyVerifierInitialized + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VerifierProxyVerifierInitializedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VerifierProxyVerifierInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VerifierProxyVerifierInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VerifierProxyVerifierInitializedIterator) Error() error { + return it.fail +} + +func (it *VerifierProxyVerifierInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VerifierProxyVerifierInitialized struct { + VerifierAddress common.Address + Raw types.Log +} + +func (_VerifierProxy *VerifierProxyFilterer) FilterVerifierInitialized(opts *bind.FilterOpts) (*VerifierProxyVerifierInitializedIterator, error) { + + logs, sub, err := _VerifierProxy.contract.FilterLogs(opts, "VerifierInitialized") + if err != nil { + return nil, err + } + return &VerifierProxyVerifierInitializedIterator{contract: _VerifierProxy.contract, event: "VerifierInitialized", logs: logs, sub: sub}, nil +} + +func (_VerifierProxy *VerifierProxyFilterer) WatchVerifierInitialized(opts *bind.WatchOpts, sink chan<- *VerifierProxyVerifierInitialized) (event.Subscription, error) { + + logs, sub, err := _VerifierProxy.contract.WatchLogs(opts, "VerifierInitialized") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VerifierProxyVerifierInitialized) + if err := _VerifierProxy.contract.UnpackLog(event, "VerifierInitialized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VerifierProxy *VerifierProxyFilterer) ParseVerifierInitialized(log types.Log) (*VerifierProxyVerifierInitialized, error) { + event := new(VerifierProxyVerifierInitialized) + if err := _VerifierProxy.contract.UnpackLog(event, "VerifierInitialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VerifierProxyVerifierSetIterator struct { + Event *VerifierProxyVerifierSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VerifierProxyVerifierSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VerifierProxyVerifierSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VerifierProxyVerifierSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VerifierProxyVerifierSetIterator) Error() error { + return it.fail +} + +func (it *VerifierProxyVerifierSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VerifierProxyVerifierSet struct { + OldConfigDigest [32]byte + NewConfigDigest [32]byte + VerifierAddress common.Address + Raw types.Log +} + +func (_VerifierProxy *VerifierProxyFilterer) FilterVerifierSet(opts *bind.FilterOpts) (*VerifierProxyVerifierSetIterator, error) { + + logs, sub, err := _VerifierProxy.contract.FilterLogs(opts, "VerifierSet") + if err != nil { + return nil, err + } + return &VerifierProxyVerifierSetIterator{contract: _VerifierProxy.contract, event: "VerifierSet", logs: logs, sub: sub}, nil +} + +func (_VerifierProxy *VerifierProxyFilterer) WatchVerifierSet(opts *bind.WatchOpts, sink chan<- *VerifierProxyVerifierSet) (event.Subscription, error) { + + logs, sub, err := _VerifierProxy.contract.WatchLogs(opts, "VerifierSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VerifierProxyVerifierSet) + if err := _VerifierProxy.contract.UnpackLog(event, "VerifierSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VerifierProxy *VerifierProxyFilterer) ParseVerifierSet(log types.Log) (*VerifierProxyVerifierSet, error) { + event := new(VerifierProxyVerifierSet) + if err := _VerifierProxy.contract.UnpackLog(event, "VerifierSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VerifierProxyVerifierUnsetIterator struct { + Event *VerifierProxyVerifierUnset + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VerifierProxyVerifierUnsetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VerifierProxyVerifierUnset) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VerifierProxyVerifierUnset) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VerifierProxyVerifierUnsetIterator) Error() error { + return it.fail +} + +func (it *VerifierProxyVerifierUnsetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VerifierProxyVerifierUnset struct { + ConfigDigest [32]byte + VerifierAddress common.Address + Raw types.Log +} + +func (_VerifierProxy *VerifierProxyFilterer) FilterVerifierUnset(opts *bind.FilterOpts) (*VerifierProxyVerifierUnsetIterator, error) { + + logs, sub, err := _VerifierProxy.contract.FilterLogs(opts, "VerifierUnset") + if err != nil { + return nil, err + } + return &VerifierProxyVerifierUnsetIterator{contract: _VerifierProxy.contract, event: "VerifierUnset", logs: logs, sub: sub}, nil +} + +func (_VerifierProxy *VerifierProxyFilterer) WatchVerifierUnset(opts *bind.WatchOpts, sink chan<- *VerifierProxyVerifierUnset) (event.Subscription, error) { + + logs, sub, err := _VerifierProxy.contract.WatchLogs(opts, "VerifierUnset") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VerifierProxyVerifierUnset) + if err := _VerifierProxy.contract.UnpackLog(event, "VerifierUnset", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VerifierProxy *VerifierProxyFilterer) ParseVerifierUnset(log types.Log) (*VerifierProxyVerifierUnset, error) { + event := new(VerifierProxyVerifierUnset) + if err := _VerifierProxy.contract.UnpackLog(event, "VerifierUnset", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_VerifierProxy *VerifierProxy) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _VerifierProxy.abi.Events["AccessControllerSet"].ID: + return _VerifierProxy.ParseAccessControllerSet(log) + case _VerifierProxy.abi.Events["FeeManagerSet"].ID: + return _VerifierProxy.ParseFeeManagerSet(log) + case _VerifierProxy.abi.Events["OwnershipTransferRequested"].ID: + return _VerifierProxy.ParseOwnershipTransferRequested(log) + case _VerifierProxy.abi.Events["OwnershipTransferred"].ID: + return _VerifierProxy.ParseOwnershipTransferred(log) + case _VerifierProxy.abi.Events["VerifierInitialized"].ID: + return _VerifierProxy.ParseVerifierInitialized(log) + case _VerifierProxy.abi.Events["VerifierSet"].ID: + return _VerifierProxy.ParseVerifierSet(log) + case _VerifierProxy.abi.Events["VerifierUnset"].ID: + return _VerifierProxy.ParseVerifierUnset(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (VerifierProxyAccessControllerSet) Topic() common.Hash { + return common.HexToHash("0x953e92b1a6442e9c3242531154a3f6f6eb00b4e9c719ba8118fa6235e4ce89b6") +} + +func (VerifierProxyFeeManagerSet) Topic() common.Hash { + return common.HexToHash("0x04628abcaa6b1674651352125cb94b65b289145bc2bc4d67720bb7d966372f03") +} + +func (VerifierProxyOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (VerifierProxyOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (VerifierProxyVerifierInitialized) Topic() common.Hash { + return common.HexToHash("0x1f2cd7c97f4d801b5efe26cc409617c1fd6c5ef786e79aacb90af40923e4e8e9") +} + +func (VerifierProxyVerifierSet) Topic() common.Hash { + return common.HexToHash("0xbeb513e532542a562ac35699e7cd9ae7d198dcd3eee15bada6c857d28ceaddcf") +} + +func (VerifierProxyVerifierUnset) Topic() common.Hash { + return common.HexToHash("0x11dc15c4b8ac2b183166cc8427e5385a5ece8308217a4217338c6a7614845c4c") +} + +func (_VerifierProxy *VerifierProxy) Address() common.Address { + return _VerifierProxy.address +} + +type VerifierProxyInterface interface { + GetVerifier(opts *bind.CallOpts, configDigest [32]byte) (common.Address, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + SAccessController(opts *bind.CallOpts) (common.Address, error) + + SFeeManager(opts *bind.CallOpts) (common.Address, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + InitializeVerifier(opts *bind.TransactOpts, verifierAddress common.Address) (*types.Transaction, error) + + SetAccessController(opts *bind.TransactOpts, accessController common.Address) (*types.Transaction, error) + + SetFeeManager(opts *bind.TransactOpts, feeManager common.Address) (*types.Transaction, error) + + SetVerifier(opts *bind.TransactOpts, currentConfigDigest [32]byte, newConfigDigest [32]byte, addressesAndWeights []CommonAddressAndWeight) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + UnsetVerifier(opts *bind.TransactOpts, configDigest [32]byte) (*types.Transaction, error) + + Verify(opts *bind.TransactOpts, payload []byte, parameterPayload []byte) (*types.Transaction, error) + + VerifyBulk(opts *bind.TransactOpts, payloads [][]byte, parameterPayload []byte) (*types.Transaction, error) + + FilterAccessControllerSet(opts *bind.FilterOpts) (*VerifierProxyAccessControllerSetIterator, error) + + WatchAccessControllerSet(opts *bind.WatchOpts, sink chan<- *VerifierProxyAccessControllerSet) (event.Subscription, error) + + ParseAccessControllerSet(log types.Log) (*VerifierProxyAccessControllerSet, error) + + FilterFeeManagerSet(opts *bind.FilterOpts) (*VerifierProxyFeeManagerSetIterator, error) + + WatchFeeManagerSet(opts *bind.WatchOpts, sink chan<- *VerifierProxyFeeManagerSet) (event.Subscription, error) + + ParseFeeManagerSet(log types.Log) (*VerifierProxyFeeManagerSet, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VerifierProxyOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *VerifierProxyOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*VerifierProxyOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VerifierProxyOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *VerifierProxyOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*VerifierProxyOwnershipTransferred, error) + + FilterVerifierInitialized(opts *bind.FilterOpts) (*VerifierProxyVerifierInitializedIterator, error) + + WatchVerifierInitialized(opts *bind.WatchOpts, sink chan<- *VerifierProxyVerifierInitialized) (event.Subscription, error) + + ParseVerifierInitialized(log types.Log) (*VerifierProxyVerifierInitialized, error) + + FilterVerifierSet(opts *bind.FilterOpts) (*VerifierProxyVerifierSetIterator, error) + + WatchVerifierSet(opts *bind.WatchOpts, sink chan<- *VerifierProxyVerifierSet) (event.Subscription, error) + + ParseVerifierSet(log types.Log) (*VerifierProxyVerifierSet, error) + + FilterVerifierUnset(opts *bind.FilterOpts) (*VerifierProxyVerifierUnsetIterator, error) + + WatchVerifierUnset(opts *bind.WatchOpts, sink chan<- *VerifierProxyVerifierUnset) (event.Subscription, error) + + ParseVerifierUnset(log types.Log) (*VerifierProxyVerifierUnset, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/llo-feeds/generated/verifier_v0_5_0/verifier_v0_5_0.go b/core/gethwrappers/llo-feeds/generated/verifier_v0_5_0/verifier_v0_5_0.go new file mode 100644 index 00000000000..f6e45d02762 --- /dev/null +++ b/core/gethwrappers/llo-feeds/generated/verifier_v0_5_0/verifier_v0_5_0.go @@ -0,0 +1,1385 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package verifier_v0_5_0 + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type CommonAddressAndWeight struct { + Addr common.Address + Weight uint64 +} + +var VerifierMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"verifierProxyAddr\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AccessForbidden\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BadVerification\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ConfigDigestAlreadySet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DigestEmpty\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"DigestInactive\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"DigestNotSet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"numSigners\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxSigners\",\"type\":\"uint256\"}],\"name\":\"ExcessSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FaultToleranceMustBePositive\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"numSigners\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expectedNumSigners\",\"type\":\"uint256\"}],\"name\":\"IncorrectSignatureCount\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"numSigners\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minSigners\",\"type\":\"uint256\"}],\"name\":\"InsufficientSigners\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"rsLength\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"ssLength\",\"type\":\"uint256\"}],\"name\":\"MismatchedSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"ConfigActivated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"ConfigDeactivated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"prevSigners\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"newSigners\",\"type\":\"address[]\"}],\"name\":\"ConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"}],\"name\":\"ReportVerified\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"activateConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"deactivateConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"recipientAddressesAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isVerifier\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"address[]\",\"name\":\"prevSigners\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"newSigners\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"}],\"name\":\"updateConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"signedReport\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"verifierResponse\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60a06040523480156200001157600080fd5b5060405162001e7038038062001e708339810160408190526200003491620001a6565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000fb565b5050506001600160a01b038116620000e95760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b0316608052620001d8565b336001600160a01b03821603620001555760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060208284031215620001b957600080fd5b81516001600160a01b0381168114620001d157600080fd5b9392505050565b608051611c75620001fb600039600081816107c20152610e110152611c756000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c80633d3ac1b5116100815780638da5cb5b1161005b5780638da5cb5b146101e3578063e84f128e1461020b578063f2fde38b1461024657600080fd5b80633d3ac1b5146101b557806341e3df58146101c857806379ba5097146101db57600080fd5b80630e112e54116100b25780630e112e541461014d5780630f672ef414610160578063181f5a771461017357600080fd5b806301ffc9a7146100ce5780630d1d79af14610138575b600080fd5b6101236100dc366004611333565b7fffffffff00000000000000000000000000000000000000000000000000000000167f3d3ac1b5000000000000000000000000000000000000000000000000000000001490565b60405190151581526020015b60405180910390f35b61014b61014636600461137c565b610259565b005b61014b61015b3660046113f7565b610351565b61014b61016e36600461137c565b6106bc565b60408051808201909152600e81527f566572696669657220322e302e3000000000000000000000000000000000000060208201525b60405161012f91906114e4565b6101a86101c336600461151b565b6107a8565b61014b6101d636600461168a565b6108cc565b61014b61098e565b60005460405173ffffffffffffffffffffffffffffffffffffffff909116815260200161012f565b61023161021936600461137c565b60009081526002602052604090205463ffffffff1690565b60405163ffffffff909116815260200161012f565b61014b6102543660046117a3565b610a8b565b610261610a9f565b6000818152600260205260409020816102a6576040517fe332262700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805465010000000000900460ff166000036102f5576040517f74eb4b93000000000000000000000000000000000000000000000000000000008152600481018390526024015b60405180910390fd5b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff1664010000000017815560405182907fa543797a0501218bba8a3daf75a71c8df8d1a7f791f4e44d40e43b6450183cea90600090a25050565b8160ff82166000819003610391576040517f0743bae600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601f8211156103d6576040517f61750f4000000000000000000000000000000000000000000000000000000000815260048101839052601f60248201526044016102ec565b6103e18160036117ed565b821161043957816103f38260036117ed565b6103fe90600161180a565b6040517f9dd9e6d8000000000000000000000000000000000000000000000000000000008152600481019290925260248201526044016102ec565b610441610a9f565b6000888152600260205260408120805490916501000000000090910460ff16900361049b576040517f74eb4b93000000000000000000000000000000000000000000000000000000008152600481018a90526024016102ec565b80546601000000000000900460ff1687146104e2576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8781101561061c5760008260010160008b8b858181106105075761050761184c565b905060200201602081019061051c91906117a3565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160002054610100900460ff16600181111561055c5761055c61181d565b03610593576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8160010160008a8a848181106105ab576105ab61184c565b90506020020160208101906105c091906117a3565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690556106158161187b565b90506104e5565b5061067389878787600060405190808252806020026020018201604052801561066b57816020015b60408051808201909152600080825260208201528152602001906001900390816106445790505b506001610b22565b887fb0b75a854fab801413da6202fc07e875c54eaf371a1e3909fb2645364ba58616898989896040516106a99493929190611907565b60405180910390a2505050505050505050565b6106c4610a9f565b600081815260026020526040902081610709576040517fe332262700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805465010000000000900460ff16600003610753576040517f74eb4b93000000000000000000000000000000000000000000000000000000008152600481018390526024016102ec565b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff16815560405182907f5bfaab86edc1b932e3c334327a591c9ded067cb521abae19b95ca927d607657990600090a25050565b60603373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610819576040517fef67f5d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080808061082b888a018a611a2d565b84516000818152600260205260409020959a50939850919650945092509061085582868684610ec2565b8551602087012061086a818988888887610fc2565b61087387611b08565b60405173ffffffffffffffffffffffffffffffffffffffff8c1681527f58ca9502e98a536e06e72d680fcc251e5d10b72291a281665a2c2dc0ac30fcc59060200160405180910390a250949a9950505050505050505050565b8260ff8316600081900361090c576040517f0743bae600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601f821115610951576040517f61750f4000000000000000000000000000000000000000000000000000000000815260048101839052601f60248201526044016102ec565b61095c8160036117ed565b821161096e57816103f38260036117ed565b610976610a9f565b61098587878787876000610b22565b50505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610a0f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016102ec565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610a93610a9f565b610a9c8161123e565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314610b20576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016102ec565b565b6000868152600260205260409020805465010000000000900460ff1615801590610b4a575081155b15610b81576040517f961dba8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805460ff8681166601000000000000027fffffffffffffffffffffffffffffffffffffffffffffffffff00ff00ffffffff91871665010000000000027fffffffffffffffffffffffffffffffffffffffffffffffffffff00ff0000000090931663ffffffff43161792909217161764010000000017815560005b60ff8116861115610dce57600087878360ff16818110610c1d57610c1d61184c565b9050602002016020810190610c3291906117a3565b905073ffffffffffffffffffffffffffffffffffffffff8116610c81576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008073ffffffffffffffffffffffffffffffffffffffff831660009081526001868101602052604090912054610100900460ff1690811115610cc657610cc661181d565b1480159150610d01576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201825260ff85811682526001602080840182815273ffffffffffffffffffffffffffffffffffffffff881660009081528a84019092529490208351815493167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008416811782559451939490939284927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000090911690911790610100908490811115610db357610db361181d565b0217905550905050505080610dc790611b4d565b9050610bfb565b5081610985576040517fb011b24700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063b011b24790610e4b906000908b908890600401611b6c565b600060405180830381600087803b158015610e6557600080fd5b505af1158015610e79573d6000803e3d6000fd5b50505050867f5b1f376eb2bda670fa39339616d0a73f45b61bec8faeba8ca834f2ebb49676e0878787604051610eb193929190611bec565b60405180910390a250505050505050565b8054600090610ede9065010000000000900460ff166001611c13565b8254909150640100000000900460ff16610f27576040517fd990d621000000000000000000000000000000000000000000000000000000008152600481018690526024016102ec565b8060ff16845114610f735783516040517f5348a282000000000000000000000000000000000000000000000000000000008152600481019190915260ff821660248201526044016102ec565b8251845114610fbb57835183516040517ff0d31408000000000000000000000000000000000000000000000000000000008152600481019290925260248201526044016102ec565b5050505050565b60008686604051602001610fd7929190611c2c565b604051602081830303815290604052805190602001209050600061100b604080518082019091526000808252602082015290565b8651600090815b818110156111d65760018689836020811061102f5761102f61184c565b61103c91901a601b611c13565b8c848151811061104e5761104e61184c565b60200260200101518c85815181106110685761106861184c565b6020026020010151604051600081526020016040526040516110a6949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa1580156110c8573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff811660009081526001808d01602090815291859020848601909552845460ff80821686529399509395509085019261010090049091169081111561114d5761114d61181d565b600181111561115e5761115e61181d565b905250935060018460200151600181111561117b5761117b61181d565b146111b2576040517f4df18f0700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b836000015160080260ff166001901b85019450806111cf9061187b565b9050611012565b50837e01010101010101010101010101010101010101010101010101010101010101851614611231576040517f4df18f0700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050505050505050565b3373ffffffffffffffffffffffffffffffffffffffff8216036112bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016102ec565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60006020828403121561134557600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461137557600080fd5b9392505050565b60006020828403121561138e57600080fd5b5035919050565b60008083601f8401126113a757600080fd5b50813567ffffffffffffffff8111156113bf57600080fd5b6020830191508360208260051b85010111156113da57600080fd5b9250929050565b803560ff811681146113f257600080fd5b919050565b6000806000806000806080878903121561141057600080fd5b86359550602087013567ffffffffffffffff8082111561142f57600080fd5b61143b8a838b01611395565b9097509550604089013591508082111561145457600080fd5b5061146189828a01611395565b90945092506114749050606088016113e1565b90509295509295509295565b6000815180845260005b818110156114a65760208185018101518683018201520161148a565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6020815260006113756020830184611480565b803573ffffffffffffffffffffffffffffffffffffffff811681146113f257600080fd5b60008060006040848603121561153057600080fd5b833567ffffffffffffffff8082111561154857600080fd5b818601915086601f83011261155c57600080fd5b81358181111561156b57600080fd5b87602082850101111561157d57600080fd5b60209283019550935061159391860190506114f7565b90509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156115ee576115ee61159c565b60405290565b6040516060810167ffffffffffffffff811182821017156115ee576115ee61159c565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561165e5761165e61159c565b604052919050565b600067ffffffffffffffff8211156116805761168061159c565b5060051b60200190565b6000806000806000608086880312156116a257600080fd5b8535945060208087013567ffffffffffffffff808211156116c257600080fd5b6116ce8a838b01611395565b9097509550604091506116e28983016113e1565b94506060890135818111156116f657600080fd5b8901601f81018b1361170757600080fd5b803561171a61171582611666565b611617565b81815260069190911b8201850190858101908d83111561173957600080fd5b928601925b8284101561178f5785848f0312156117565760008081fd5b61175e6115cb565b611767856114f7565b815287850135868116811461177c5760008081fd5b818901528252928501929086019061173e565b809750505050505050509295509295909350565b6000602082840312156117b557600080fd5b611375826114f7565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082028115828204841417611804576118046117be565b92915050565b80820180821115611804576118046117be565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036118ac576118ac6117be565b5060010190565b8183526000602080850194508260005b858110156118fc5773ffffffffffffffffffffffffffffffffffffffff6118e9836114f7565b16875295820195908201906001016118c3565b509495945050505050565b60408152600061191b6040830186886118b3565b828103602084015261192e8185876118b3565b979650505050505050565b600082601f83011261194a57600080fd5b813567ffffffffffffffff8111156119645761196461159c565b61199560207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611617565b8181528460208386010111156119aa57600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f8301126119d857600080fd5b813560206119e861171583611666565b82815260059290921b84018101918181019086841115611a0757600080fd5b8286015b84811015611a225780358352918301918301611a0b565b509695505050505050565b600080600080600060e08688031215611a4557600080fd5b86601f870112611a5457600080fd5b611a5c6115f4565b806060880189811115611a6e57600080fd5b885b81811015611a88578035845260209384019301611a70565b5090965035905067ffffffffffffffff80821115611aa557600080fd5b611ab189838a01611939565b95506080880135915080821115611ac757600080fd5b611ad389838a016119c7565b945060a0880135915080821115611ae957600080fd5b50611af6888289016119c7565b9598949750929560c001359392505050565b80516020808301519190811015611b47577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b600060ff821660ff8103611b6357611b636117be565b60010192915050565b600060608201858352602085818501526040606081860152828651808552608087019150838801945060005b81811015611bdd578551805173ffffffffffffffffffffffffffffffffffffffff16845285015167ffffffffffffffff16858401529484019491830191600101611b98565b50909998505050505050505050565b604081526000611c006040830185876118b3565b905060ff83166020830152949350505050565b60ff8181168382160190811115611804576118046117be565b828152600060208083018460005b6003811015611c5757815183529183019190830190600101611c3a565b50505050608082019050939250505056fea164736f6c6343000813000a", +} + +var VerifierABI = VerifierMetaData.ABI + +var VerifierBin = VerifierMetaData.Bin + +func DeployVerifier(auth *bind.TransactOpts, backend bind.ContractBackend, verifierProxyAddr common.Address) (common.Address, *types.Transaction, *Verifier, error) { + parsed, err := VerifierMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(VerifierBin), backend, verifierProxyAddr) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &Verifier{address: address, abi: *parsed, VerifierCaller: VerifierCaller{contract: contract}, VerifierTransactor: VerifierTransactor{contract: contract}, VerifierFilterer: VerifierFilterer{contract: contract}}, nil +} + +type Verifier struct { + address common.Address + abi abi.ABI + VerifierCaller + VerifierTransactor + VerifierFilterer +} + +type VerifierCaller struct { + contract *bind.BoundContract +} + +type VerifierTransactor struct { + contract *bind.BoundContract +} + +type VerifierFilterer struct { + contract *bind.BoundContract +} + +type VerifierSession struct { + Contract *Verifier + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type VerifierCallerSession struct { + Contract *VerifierCaller + CallOpts bind.CallOpts +} + +type VerifierTransactorSession struct { + Contract *VerifierTransactor + TransactOpts bind.TransactOpts +} + +type VerifierRaw struct { + Contract *Verifier +} + +type VerifierCallerRaw struct { + Contract *VerifierCaller +} + +type VerifierTransactorRaw struct { + Contract *VerifierTransactor +} + +func NewVerifier(address common.Address, backend bind.ContractBackend) (*Verifier, error) { + abi, err := abi.JSON(strings.NewReader(VerifierABI)) + if err != nil { + return nil, err + } + contract, err := bindVerifier(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &Verifier{address: address, abi: abi, VerifierCaller: VerifierCaller{contract: contract}, VerifierTransactor: VerifierTransactor{contract: contract}, VerifierFilterer: VerifierFilterer{contract: contract}}, nil +} + +func NewVerifierCaller(address common.Address, caller bind.ContractCaller) (*VerifierCaller, error) { + contract, err := bindVerifier(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &VerifierCaller{contract: contract}, nil +} + +func NewVerifierTransactor(address common.Address, transactor bind.ContractTransactor) (*VerifierTransactor, error) { + contract, err := bindVerifier(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &VerifierTransactor{contract: contract}, nil +} + +func NewVerifierFilterer(address common.Address, filterer bind.ContractFilterer) (*VerifierFilterer, error) { + contract, err := bindVerifier(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &VerifierFilterer{contract: contract}, nil +} + +func bindVerifier(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := VerifierMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_Verifier *VerifierRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Verifier.Contract.VerifierCaller.contract.Call(opts, result, method, params...) +} + +func (_Verifier *VerifierRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Verifier.Contract.VerifierTransactor.contract.Transfer(opts) +} + +func (_Verifier *VerifierRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Verifier.Contract.VerifierTransactor.contract.Transact(opts, method, params...) +} + +func (_Verifier *VerifierCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Verifier.Contract.contract.Call(opts, result, method, params...) +} + +func (_Verifier *VerifierTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Verifier.Contract.contract.Transfer(opts) +} + +func (_Verifier *VerifierTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Verifier.Contract.contract.Transact(opts, method, params...) +} + +func (_Verifier *VerifierCaller) LatestConfigDetails(opts *bind.CallOpts, configDigest [32]byte) (uint32, error) { + var out []interface{} + err := _Verifier.contract.Call(opts, &out, "latestConfigDetails", configDigest) + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + +} + +func (_Verifier *VerifierSession) LatestConfigDetails(configDigest [32]byte) (uint32, error) { + return _Verifier.Contract.LatestConfigDetails(&_Verifier.CallOpts, configDigest) +} + +func (_Verifier *VerifierCallerSession) LatestConfigDetails(configDigest [32]byte) (uint32, error) { + return _Verifier.Contract.LatestConfigDetails(&_Verifier.CallOpts, configDigest) +} + +func (_Verifier *VerifierCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _Verifier.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_Verifier *VerifierSession) Owner() (common.Address, error) { + return _Verifier.Contract.Owner(&_Verifier.CallOpts) +} + +func (_Verifier *VerifierCallerSession) Owner() (common.Address, error) { + return _Verifier.Contract.Owner(&_Verifier.CallOpts) +} + +func (_Verifier *VerifierCaller) SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) { + var out []interface{} + err := _Verifier.contract.Call(opts, &out, "supportsInterface", interfaceId) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_Verifier *VerifierSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _Verifier.Contract.SupportsInterface(&_Verifier.CallOpts, interfaceId) +} + +func (_Verifier *VerifierCallerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _Verifier.Contract.SupportsInterface(&_Verifier.CallOpts, interfaceId) +} + +func (_Verifier *VerifierCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _Verifier.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_Verifier *VerifierSession) TypeAndVersion() (string, error) { + return _Verifier.Contract.TypeAndVersion(&_Verifier.CallOpts) +} + +func (_Verifier *VerifierCallerSession) TypeAndVersion() (string, error) { + return _Verifier.Contract.TypeAndVersion(&_Verifier.CallOpts) +} + +func (_Verifier *VerifierTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Verifier.contract.Transact(opts, "acceptOwnership") +} + +func (_Verifier *VerifierSession) AcceptOwnership() (*types.Transaction, error) { + return _Verifier.Contract.AcceptOwnership(&_Verifier.TransactOpts) +} + +func (_Verifier *VerifierTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _Verifier.Contract.AcceptOwnership(&_Verifier.TransactOpts) +} + +func (_Verifier *VerifierTransactor) ActivateConfig(opts *bind.TransactOpts, configDigest [32]byte) (*types.Transaction, error) { + return _Verifier.contract.Transact(opts, "activateConfig", configDigest) +} + +func (_Verifier *VerifierSession) ActivateConfig(configDigest [32]byte) (*types.Transaction, error) { + return _Verifier.Contract.ActivateConfig(&_Verifier.TransactOpts, configDigest) +} + +func (_Verifier *VerifierTransactorSession) ActivateConfig(configDigest [32]byte) (*types.Transaction, error) { + return _Verifier.Contract.ActivateConfig(&_Verifier.TransactOpts, configDigest) +} + +func (_Verifier *VerifierTransactor) DeactivateConfig(opts *bind.TransactOpts, configDigest [32]byte) (*types.Transaction, error) { + return _Verifier.contract.Transact(opts, "deactivateConfig", configDigest) +} + +func (_Verifier *VerifierSession) DeactivateConfig(configDigest [32]byte) (*types.Transaction, error) { + return _Verifier.Contract.DeactivateConfig(&_Verifier.TransactOpts, configDigest) +} + +func (_Verifier *VerifierTransactorSession) DeactivateConfig(configDigest [32]byte) (*types.Transaction, error) { + return _Verifier.Contract.DeactivateConfig(&_Verifier.TransactOpts, configDigest) +} + +func (_Verifier *VerifierTransactor) SetConfig(opts *bind.TransactOpts, configDigest [32]byte, signers []common.Address, f uint8, recipientAddressesAndWeights []CommonAddressAndWeight) (*types.Transaction, error) { + return _Verifier.contract.Transact(opts, "setConfig", configDigest, signers, f, recipientAddressesAndWeights) +} + +func (_Verifier *VerifierSession) SetConfig(configDigest [32]byte, signers []common.Address, f uint8, recipientAddressesAndWeights []CommonAddressAndWeight) (*types.Transaction, error) { + return _Verifier.Contract.SetConfig(&_Verifier.TransactOpts, configDigest, signers, f, recipientAddressesAndWeights) +} + +func (_Verifier *VerifierTransactorSession) SetConfig(configDigest [32]byte, signers []common.Address, f uint8, recipientAddressesAndWeights []CommonAddressAndWeight) (*types.Transaction, error) { + return _Verifier.Contract.SetConfig(&_Verifier.TransactOpts, configDigest, signers, f, recipientAddressesAndWeights) +} + +func (_Verifier *VerifierTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _Verifier.contract.Transact(opts, "transferOwnership", to) +} + +func (_Verifier *VerifierSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _Verifier.Contract.TransferOwnership(&_Verifier.TransactOpts, to) +} + +func (_Verifier *VerifierTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _Verifier.Contract.TransferOwnership(&_Verifier.TransactOpts, to) +} + +func (_Verifier *VerifierTransactor) UpdateConfig(opts *bind.TransactOpts, configDigest [32]byte, prevSigners []common.Address, newSigners []common.Address, f uint8) (*types.Transaction, error) { + return _Verifier.contract.Transact(opts, "updateConfig", configDigest, prevSigners, newSigners, f) +} + +func (_Verifier *VerifierSession) UpdateConfig(configDigest [32]byte, prevSigners []common.Address, newSigners []common.Address, f uint8) (*types.Transaction, error) { + return _Verifier.Contract.UpdateConfig(&_Verifier.TransactOpts, configDigest, prevSigners, newSigners, f) +} + +func (_Verifier *VerifierTransactorSession) UpdateConfig(configDigest [32]byte, prevSigners []common.Address, newSigners []common.Address, f uint8) (*types.Transaction, error) { + return _Verifier.Contract.UpdateConfig(&_Verifier.TransactOpts, configDigest, prevSigners, newSigners, f) +} + +func (_Verifier *VerifierTransactor) Verify(opts *bind.TransactOpts, signedReport []byte, sender common.Address) (*types.Transaction, error) { + return _Verifier.contract.Transact(opts, "verify", signedReport, sender) +} + +func (_Verifier *VerifierSession) Verify(signedReport []byte, sender common.Address) (*types.Transaction, error) { + return _Verifier.Contract.Verify(&_Verifier.TransactOpts, signedReport, sender) +} + +func (_Verifier *VerifierTransactorSession) Verify(signedReport []byte, sender common.Address) (*types.Transaction, error) { + return _Verifier.Contract.Verify(&_Verifier.TransactOpts, signedReport, sender) +} + +type VerifierConfigActivatedIterator struct { + Event *VerifierConfigActivated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VerifierConfigActivatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VerifierConfigActivated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VerifierConfigActivated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VerifierConfigActivatedIterator) Error() error { + return it.fail +} + +func (it *VerifierConfigActivatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VerifierConfigActivated struct { + ConfigDigest [32]byte + Raw types.Log +} + +func (_Verifier *VerifierFilterer) FilterConfigActivated(opts *bind.FilterOpts, configDigest [][32]byte) (*VerifierConfigActivatedIterator, error) { + + var configDigestRule []interface{} + for _, configDigestItem := range configDigest { + configDigestRule = append(configDigestRule, configDigestItem) + } + + logs, sub, err := _Verifier.contract.FilterLogs(opts, "ConfigActivated", configDigestRule) + if err != nil { + return nil, err + } + return &VerifierConfigActivatedIterator{contract: _Verifier.contract, event: "ConfigActivated", logs: logs, sub: sub}, nil +} + +func (_Verifier *VerifierFilterer) WatchConfigActivated(opts *bind.WatchOpts, sink chan<- *VerifierConfigActivated, configDigest [][32]byte) (event.Subscription, error) { + + var configDigestRule []interface{} + for _, configDigestItem := range configDigest { + configDigestRule = append(configDigestRule, configDigestItem) + } + + logs, sub, err := _Verifier.contract.WatchLogs(opts, "ConfigActivated", configDigestRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VerifierConfigActivated) + if err := _Verifier.contract.UnpackLog(event, "ConfigActivated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_Verifier *VerifierFilterer) ParseConfigActivated(log types.Log) (*VerifierConfigActivated, error) { + event := new(VerifierConfigActivated) + if err := _Verifier.contract.UnpackLog(event, "ConfigActivated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VerifierConfigDeactivatedIterator struct { + Event *VerifierConfigDeactivated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VerifierConfigDeactivatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VerifierConfigDeactivated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VerifierConfigDeactivated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VerifierConfigDeactivatedIterator) Error() error { + return it.fail +} + +func (it *VerifierConfigDeactivatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VerifierConfigDeactivated struct { + ConfigDigest [32]byte + Raw types.Log +} + +func (_Verifier *VerifierFilterer) FilterConfigDeactivated(opts *bind.FilterOpts, configDigest [][32]byte) (*VerifierConfigDeactivatedIterator, error) { + + var configDigestRule []interface{} + for _, configDigestItem := range configDigest { + configDigestRule = append(configDigestRule, configDigestItem) + } + + logs, sub, err := _Verifier.contract.FilterLogs(opts, "ConfigDeactivated", configDigestRule) + if err != nil { + return nil, err + } + return &VerifierConfigDeactivatedIterator{contract: _Verifier.contract, event: "ConfigDeactivated", logs: logs, sub: sub}, nil +} + +func (_Verifier *VerifierFilterer) WatchConfigDeactivated(opts *bind.WatchOpts, sink chan<- *VerifierConfigDeactivated, configDigest [][32]byte) (event.Subscription, error) { + + var configDigestRule []interface{} + for _, configDigestItem := range configDigest { + configDigestRule = append(configDigestRule, configDigestItem) + } + + logs, sub, err := _Verifier.contract.WatchLogs(opts, "ConfigDeactivated", configDigestRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VerifierConfigDeactivated) + if err := _Verifier.contract.UnpackLog(event, "ConfigDeactivated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_Verifier *VerifierFilterer) ParseConfigDeactivated(log types.Log) (*VerifierConfigDeactivated, error) { + event := new(VerifierConfigDeactivated) + if err := _Verifier.contract.UnpackLog(event, "ConfigDeactivated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VerifierConfigSetIterator struct { + Event *VerifierConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VerifierConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VerifierConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VerifierConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VerifierConfigSetIterator) Error() error { + return it.fail +} + +func (it *VerifierConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VerifierConfigSet struct { + ConfigDigest [32]byte + Signers []common.Address + F uint8 + Raw types.Log +} + +func (_Verifier *VerifierFilterer) FilterConfigSet(opts *bind.FilterOpts, configDigest [][32]byte) (*VerifierConfigSetIterator, error) { + + var configDigestRule []interface{} + for _, configDigestItem := range configDigest { + configDigestRule = append(configDigestRule, configDigestItem) + } + + logs, sub, err := _Verifier.contract.FilterLogs(opts, "ConfigSet", configDigestRule) + if err != nil { + return nil, err + } + return &VerifierConfigSetIterator{contract: _Verifier.contract, event: "ConfigSet", logs: logs, sub: sub}, nil +} + +func (_Verifier *VerifierFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *VerifierConfigSet, configDigest [][32]byte) (event.Subscription, error) { + + var configDigestRule []interface{} + for _, configDigestItem := range configDigest { + configDigestRule = append(configDigestRule, configDigestItem) + } + + logs, sub, err := _Verifier.contract.WatchLogs(opts, "ConfigSet", configDigestRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VerifierConfigSet) + if err := _Verifier.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_Verifier *VerifierFilterer) ParseConfigSet(log types.Log) (*VerifierConfigSet, error) { + event := new(VerifierConfigSet) + if err := _Verifier.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VerifierConfigUpdatedIterator struct { + Event *VerifierConfigUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VerifierConfigUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VerifierConfigUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VerifierConfigUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VerifierConfigUpdatedIterator) Error() error { + return it.fail +} + +func (it *VerifierConfigUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VerifierConfigUpdated struct { + ConfigDigest [32]byte + PrevSigners []common.Address + NewSigners []common.Address + Raw types.Log +} + +func (_Verifier *VerifierFilterer) FilterConfigUpdated(opts *bind.FilterOpts, configDigest [][32]byte) (*VerifierConfigUpdatedIterator, error) { + + var configDigestRule []interface{} + for _, configDigestItem := range configDigest { + configDigestRule = append(configDigestRule, configDigestItem) + } + + logs, sub, err := _Verifier.contract.FilterLogs(opts, "ConfigUpdated", configDigestRule) + if err != nil { + return nil, err + } + return &VerifierConfigUpdatedIterator{contract: _Verifier.contract, event: "ConfigUpdated", logs: logs, sub: sub}, nil +} + +func (_Verifier *VerifierFilterer) WatchConfigUpdated(opts *bind.WatchOpts, sink chan<- *VerifierConfigUpdated, configDigest [][32]byte) (event.Subscription, error) { + + var configDigestRule []interface{} + for _, configDigestItem := range configDigest { + configDigestRule = append(configDigestRule, configDigestItem) + } + + logs, sub, err := _Verifier.contract.WatchLogs(opts, "ConfigUpdated", configDigestRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VerifierConfigUpdated) + if err := _Verifier.contract.UnpackLog(event, "ConfigUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_Verifier *VerifierFilterer) ParseConfigUpdated(log types.Log) (*VerifierConfigUpdated, error) { + event := new(VerifierConfigUpdated) + if err := _Verifier.contract.UnpackLog(event, "ConfigUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VerifierOwnershipTransferRequestedIterator struct { + Event *VerifierOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VerifierOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VerifierOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VerifierOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VerifierOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *VerifierOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VerifierOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_Verifier *VerifierFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VerifierOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _Verifier.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &VerifierOwnershipTransferRequestedIterator{contract: _Verifier.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_Verifier *VerifierFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *VerifierOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _Verifier.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VerifierOwnershipTransferRequested) + if err := _Verifier.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_Verifier *VerifierFilterer) ParseOwnershipTransferRequested(log types.Log) (*VerifierOwnershipTransferRequested, error) { + event := new(VerifierOwnershipTransferRequested) + if err := _Verifier.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VerifierOwnershipTransferredIterator struct { + Event *VerifierOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VerifierOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VerifierOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VerifierOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VerifierOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *VerifierOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VerifierOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_Verifier *VerifierFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VerifierOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _Verifier.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &VerifierOwnershipTransferredIterator{contract: _Verifier.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_Verifier *VerifierFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *VerifierOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _Verifier.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VerifierOwnershipTransferred) + if err := _Verifier.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_Verifier *VerifierFilterer) ParseOwnershipTransferred(log types.Log) (*VerifierOwnershipTransferred, error) { + event := new(VerifierOwnershipTransferred) + if err := _Verifier.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VerifierReportVerifiedIterator struct { + Event *VerifierReportVerified + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VerifierReportVerifiedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VerifierReportVerified) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VerifierReportVerified) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VerifierReportVerifiedIterator) Error() error { + return it.fail +} + +func (it *VerifierReportVerifiedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VerifierReportVerified struct { + FeedId [32]byte + Requester common.Address + Raw types.Log +} + +func (_Verifier *VerifierFilterer) FilterReportVerified(opts *bind.FilterOpts, feedId [][32]byte) (*VerifierReportVerifiedIterator, error) { + + var feedIdRule []interface{} + for _, feedIdItem := range feedId { + feedIdRule = append(feedIdRule, feedIdItem) + } + + logs, sub, err := _Verifier.contract.FilterLogs(opts, "ReportVerified", feedIdRule) + if err != nil { + return nil, err + } + return &VerifierReportVerifiedIterator{contract: _Verifier.contract, event: "ReportVerified", logs: logs, sub: sub}, nil +} + +func (_Verifier *VerifierFilterer) WatchReportVerified(opts *bind.WatchOpts, sink chan<- *VerifierReportVerified, feedId [][32]byte) (event.Subscription, error) { + + var feedIdRule []interface{} + for _, feedIdItem := range feedId { + feedIdRule = append(feedIdRule, feedIdItem) + } + + logs, sub, err := _Verifier.contract.WatchLogs(opts, "ReportVerified", feedIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VerifierReportVerified) + if err := _Verifier.contract.UnpackLog(event, "ReportVerified", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_Verifier *VerifierFilterer) ParseReportVerified(log types.Log) (*VerifierReportVerified, error) { + event := new(VerifierReportVerified) + if err := _Verifier.contract.UnpackLog(event, "ReportVerified", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_Verifier *Verifier) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _Verifier.abi.Events["ConfigActivated"].ID: + return _Verifier.ParseConfigActivated(log) + case _Verifier.abi.Events["ConfigDeactivated"].ID: + return _Verifier.ParseConfigDeactivated(log) + case _Verifier.abi.Events["ConfigSet"].ID: + return _Verifier.ParseConfigSet(log) + case _Verifier.abi.Events["ConfigUpdated"].ID: + return _Verifier.ParseConfigUpdated(log) + case _Verifier.abi.Events["OwnershipTransferRequested"].ID: + return _Verifier.ParseOwnershipTransferRequested(log) + case _Verifier.abi.Events["OwnershipTransferred"].ID: + return _Verifier.ParseOwnershipTransferred(log) + case _Verifier.abi.Events["ReportVerified"].ID: + return _Verifier.ParseReportVerified(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (VerifierConfigActivated) Topic() common.Hash { + return common.HexToHash("0xa543797a0501218bba8a3daf75a71c8df8d1a7f791f4e44d40e43b6450183cea") +} + +func (VerifierConfigDeactivated) Topic() common.Hash { + return common.HexToHash("0x5bfaab86edc1b932e3c334327a591c9ded067cb521abae19b95ca927d6076579") +} + +func (VerifierConfigSet) Topic() common.Hash { + return common.HexToHash("0x5b1f376eb2bda670fa39339616d0a73f45b61bec8faeba8ca834f2ebb49676e0") +} + +func (VerifierConfigUpdated) Topic() common.Hash { + return common.HexToHash("0xb0b75a854fab801413da6202fc07e875c54eaf371a1e3909fb2645364ba58616") +} + +func (VerifierOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (VerifierOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (VerifierReportVerified) Topic() common.Hash { + return common.HexToHash("0x58ca9502e98a536e06e72d680fcc251e5d10b72291a281665a2c2dc0ac30fcc5") +} + +func (_Verifier *Verifier) Address() common.Address { + return _Verifier.address +} + +type VerifierInterface interface { + LatestConfigDetails(opts *bind.CallOpts, configDigest [32]byte) (uint32, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + ActivateConfig(opts *bind.TransactOpts, configDigest [32]byte) (*types.Transaction, error) + + DeactivateConfig(opts *bind.TransactOpts, configDigest [32]byte) (*types.Transaction, error) + + SetConfig(opts *bind.TransactOpts, configDigest [32]byte, signers []common.Address, f uint8, recipientAddressesAndWeights []CommonAddressAndWeight) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + UpdateConfig(opts *bind.TransactOpts, configDigest [32]byte, prevSigners []common.Address, newSigners []common.Address, f uint8) (*types.Transaction, error) + + Verify(opts *bind.TransactOpts, signedReport []byte, sender common.Address) (*types.Transaction, error) + + FilterConfigActivated(opts *bind.FilterOpts, configDigest [][32]byte) (*VerifierConfigActivatedIterator, error) + + WatchConfigActivated(opts *bind.WatchOpts, sink chan<- *VerifierConfigActivated, configDigest [][32]byte) (event.Subscription, error) + + ParseConfigActivated(log types.Log) (*VerifierConfigActivated, error) + + FilterConfigDeactivated(opts *bind.FilterOpts, configDigest [][32]byte) (*VerifierConfigDeactivatedIterator, error) + + WatchConfigDeactivated(opts *bind.WatchOpts, sink chan<- *VerifierConfigDeactivated, configDigest [][32]byte) (event.Subscription, error) + + ParseConfigDeactivated(log types.Log) (*VerifierConfigDeactivated, error) + + FilterConfigSet(opts *bind.FilterOpts, configDigest [][32]byte) (*VerifierConfigSetIterator, error) + + WatchConfigSet(opts *bind.WatchOpts, sink chan<- *VerifierConfigSet, configDigest [][32]byte) (event.Subscription, error) + + ParseConfigSet(log types.Log) (*VerifierConfigSet, error) + + FilterConfigUpdated(opts *bind.FilterOpts, configDigest [][32]byte) (*VerifierConfigUpdatedIterator, error) + + WatchConfigUpdated(opts *bind.WatchOpts, sink chan<- *VerifierConfigUpdated, configDigest [][32]byte) (event.Subscription, error) + + ParseConfigUpdated(log types.Log) (*VerifierConfigUpdated, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VerifierOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *VerifierOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*VerifierOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VerifierOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *VerifierOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*VerifierOwnershipTransferred, error) + + FilterReportVerified(opts *bind.FilterOpts, feedId [][32]byte) (*VerifierReportVerifiedIterator, error) + + WatchReportVerified(opts *bind.WatchOpts, sink chan<- *VerifierReportVerified, feedId [][32]byte) (event.Subscription, error) + + ParseReportVerified(log types.Log) (*VerifierReportVerified, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/llo-feeds/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/llo-feeds/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 96b09fbf67d..cac8bd7b013 100644 --- a/core/gethwrappers/llo-feeds/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/llo-feeds/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -1,21 +1,28 @@ GETH_VERSION: 1.14.11 -channel_config_store: ../../../contracts/solc/v0.8.19/ChannelConfigStore/ChannelConfigStore.abi ../../../contracts/solc/v0.8.19/ChannelConfigStore/ChannelConfigStore.bin 3fafe83ea21d50488f5533962f62683988ffa6fd1476dccbbb9040be2369cb37 +channel_config_store: ../../../contracts/solc/v0.8.19/llo-feeds/v0.5.0/configuration/ChannelConfigStore/ChannelConfigStore.abi ../../../contracts/solc/v0.8.19/llo-feeds/v0.5.0/configuration/ChannelConfigStore/ChannelConfigStore.bin 3fafe83ea21d50488f5533962f62683988ffa6fd1476dccbbb9040be2369cb37 +channel_config_store_v0_5_0: ../../../contracts/solc/v0.8.19/llo-feeds/v0.5.0/configuration/ChannelConfigStore/ChannelConfigStore.abi ../../../contracts/solc/v0.8.19/llo-feeds/v0.5.0/configuration/ChannelConfigStore/ChannelConfigStore.bin 3fafe83ea21d50488f5533962f62683988ffa6fd1476dccbbb9040be2369cb37 channel_config_verifier_proxy: ../../../contracts/solc/v0.8.19/ChannelVerifierProxy/ChannelVerifierProxy.abi ../../../contracts/solc/v0.8.19/ChannelVerifierProxy/ChannelVerifierProxy.bin 655658e5f61dfadfe3268de04f948b7e690ad03ca45676e645d6cd6018154661 channel_verifier: ../../../contracts/solc/v0.8.19/ChannelVerifier/ChannelVerifier.abi ../../../contracts/solc/v0.8.19/ChannelVerifier/ChannelVerifier.bin e6020553bd8e3e6b250fcaffe7efd22aea955c8c1a0eb05d282fdeb0ab6550b7 -configurator: ../../../contracts/solc/v0.8.19/Configurator/Configurator.abi ../../../contracts/solc/v0.8.19/Configurator/Configurator.bin ee5ed0cd4f42636b6e008a12a8952c0efe3381094974e97269928eb13329c636 -destination_fee_manager: ../../../contracts/solc/v0.8.19/DestinationFeeManager/DestinationFeeManager.abi ../../../contracts/solc/v0.8.19/DestinationFeeManager/DestinationFeeManager.bin a56ae53e35e6610269f086b1e915ca1e80f5d0bf5695d09156e82fccfc2d77b3 -destination_reward_manager: ../../../contracts/solc/v0.8.19/DestinationRewardManager/DestinationRewardManager.abi ../../../contracts/solc/v0.8.19/DestinationRewardManager/DestinationRewardManager.bin 77874e97a54ecbd9c61132964da5b053f0b584dc7b774d75dd51baedd2bc7c40 -destination_verifier: ../../../contracts/solc/v0.8.19/DestinationVerifier/DestinationVerifier.abi ../../../contracts/solc/v0.8.19/DestinationVerifier/DestinationVerifier.bin 369323ce520923b9eb31ed90885f5ebd0f46b6799288fbf4da5d6ede7d697aef -destination_verifier_proxy: ../../../contracts/solc/v0.8.19/DestinationVerifierProxy/DestinationVerifierProxy.abi ../../../contracts/solc/v0.8.19/DestinationVerifierProxy/DestinationVerifierProxy.bin 4e255301cf6657777e7292eccea3e4c0ce65281404341e9248e095703a9fe392 -errored_verifier: ../../../contracts/solc/v0.8.19/ErroredVerifier/ErroredVerifier.abi ../../../contracts/solc/v0.8.19/ErroredVerifier/ErroredVerifier.bin ad8ac8d6b99890081725e2304d79d1ba7dd5212b89d130aa9689f4269eed4691 +configurator: ../../../contracts/solc/v0.8.19/llo-feeds/v0.5.0/configuration/Configurator/Configurator.abi ../../../contracts/solc/v0.8.19/llo-feeds/v0.5.0/configuration/Configurator/Configurator.bin ee5ed0cd4f42636b6e008a12a8952c0efe3381094974e97269928eb13329c636 +configurator_v0_5_0: ../../../contracts/solc/v0.8.19/llo-feeds/v0.5.0/configuration/Configurator/Configurator.abi ../../../contracts/solc/v0.8.19/llo-feeds/v0.5.0/configuration/Configurator/Configurator.bin ee5ed0cd4f42636b6e008a12a8952c0efe3381094974e97269928eb13329c636 +destination_fee_manager: ../../../contracts/solc/v0.8.19/llo-feeds/v0.4.0/DestinationFeeManager/DestinationFeeManager.abi ../../../contracts/solc/v0.8.19/llo-feeds/v0.4.0/DestinationFeeManager/DestinationFeeManager.bin a56ae53e35e6610269f086b1e915ca1e80f5d0bf5695d09156e82fccfc2d77b3 +destination_reward_manager: ../../../contracts/solc/v0.8.19/llo-feeds/v0.4.0/DestinationRewardManager/DestinationRewardManager.abi ../../../contracts/solc/v0.8.19/llo-feeds/v0.4.0/DestinationRewardManager/DestinationRewardManager.bin 77874e97a54ecbd9c61132964da5b053f0b584dc7b774d75dd51baedd2bc7c40 +destination_verifier: ../../../contracts/solc/v0.8.19/llo-feeds/v0.4.0/DestinationVerifier/DestinationVerifier.abi ../../../contracts/solc/v0.8.19/llo-feeds/v0.4.0/DestinationVerifier/DestinationVerifier.bin 369323ce520923b9eb31ed90885f5ebd0f46b6799288fbf4da5d6ede7d697aef +destination_verifier_proxy: ../../../contracts/solc/v0.8.19/llo-feeds/v0.4.0/DestinationVerifierProxy/DestinationVerifierProxy.abi ../../../contracts/solc/v0.8.19/llo-feeds/v0.4.0/DestinationVerifierProxy/DestinationVerifierProxy.bin 4e255301cf6657777e7292eccea3e4c0ce65281404341e9248e095703a9fe392 +errored_verifier: ../../../contracts/solc/v0.8.19/llo-feeds/v0.3.0/test/mocks/ErroredVerifier/ErroredVerifier.abi ../../../contracts/solc/v0.8.19/llo-feeds/v0.3.0/test/mocks/ErroredVerifier/ErroredVerifier.bin ad8ac8d6b99890081725e2304d79d1ba7dd5212b89d130aa9689f4269eed4691 exposed_channel_verifier: ../../../contracts/solc/v0.8.19/ExposedChannelVerifier/ExposedChannelVerifier.abi ../../../contracts/solc/v0.8.19/ExposedChannelVerifier/ExposedChannelVerifier.bin c21cde078900241c06de69e2bc5d906c5ef558b52db66caa68bed065940a2253 -exposed_configurator: ../../../contracts/solc/v0.8.19/ExposedConfigurator/ExposedConfigurator.abi ../../../contracts/solc/v0.8.19/ExposedConfigurator/ExposedConfigurator.bin f43362e7ef7588ecbd4d7ebd45b750cc4308e89c3d9e54fba1383e792213bbef -exposed_verifier: ../../../contracts/solc/v0.8.19/ExposedVerifier/ExposedVerifier.abi ../../../contracts/solc/v0.8.19/ExposedVerifier/ExposedVerifier.bin 00816ab345f768e522c79abadeadf9155c2c688067e18f8f73e5d6ab71037663 -fee_manager: ../../../contracts/solc/v0.8.19/FeeManager/FeeManager.abi ../../../contracts/solc/v0.8.19/FeeManager/FeeManager.bin edc85f34294ae7c90d45c4c71eb5c105c60a4842dfbbf700c692870ffcc403a1 +exposed_configurator: ../../../contracts/solc/v0.8.19/llo-feeds/v0.5.0/configuration/test/mocks/ExposedConfigurator/ExposedConfigurator.abi ../../../contracts/solc/v0.8.19/llo-feeds/v0.5.0/configuration/test/mocks/ExposedConfigurator/ExposedConfigurator.bin f43362e7ef7588ecbd4d7ebd45b750cc4308e89c3d9e54fba1383e792213bbef +exposed_configurator_v0_5_0: ../../../contracts/solc/v0.8.19/llo-feeds/v0.5.0/configuration/test/mocks/ExposedConfigurator/ExposedConfigurator.abi ../../../contracts/solc/v0.8.19/llo-feeds/v0.5.0/configuration/test/mocks/ExposedConfigurator/ExposedConfigurator.bin f43362e7ef7588ecbd4d7ebd45b750cc4308e89c3d9e54fba1383e792213bbef +exposed_verifier: ../../../contracts/solc/v0.8.19/llo-feeds/v0.3.0/test/mocks/ExposedVerifier/ExposedVerifier.abi ../../../contracts/solc/v0.8.19/llo-feeds/v0.3.0/test/mocks/ExposedVerifier/ExposedVerifier.bin 00816ab345f768e522c79abadeadf9155c2c688067e18f8f73e5d6ab71037663 +fee_manager: ../../../contracts/solc/v0.8.19/llo-feeds/v0.3.0/FeeManager/FeeManager.abi ../../../contracts/solc/v0.8.19/llo-feeds/v0.3.0/FeeManager/FeeManager.bin edc85f34294ae7c90d45c4c71eb5c105c60a4842dfbbf700c692870ffcc403a1 +fee_manager_v0_5_0: ../../../contracts/solc/v0.8.19/llo-feeds/v0.5.0/FeeManager/FeeManager.abi ../../../contracts/solc/v0.8.19/llo-feeds/v0.5.0/FeeManager/FeeManager.bin b5dfb3ac5e985d6412faf0fd21e2f5b0a759c983b3f0516f9c26cc9e4bbaed01 llo_feeds: ../../../contracts/solc/v0.8.19/FeeManager.abi ../../../contracts/solc/v0.8.19/FeeManager.bin cb71e018f67e49d7bc0e194c822204dfd59f79ff42e4fc8fd8ab63f3acd71361 llo_feeds_test: ../../../contracts/solc/v0.8.19/ExposedVerifier.abi ../../../contracts/solc/v0.8.19/ExposedVerifier.bin 6932cea8f2738e874d3ec9e1a4231d2421704030c071d9e15dd2f7f08482c246 -reward_manager: ../../../contracts/solc/v0.8.19/RewardManager/RewardManager.abi ../../../contracts/solc/v0.8.19/RewardManager/RewardManager.bin 7996cbc89a7f9af85b1ca4079ecf782d7138626b3f4bdb3bfa996248c9ccb9f4 +reward_manager: ../../../contracts/solc/v0.8.19/llo-feeds/v0.3.0/RewardManager/RewardManager.abi ../../../contracts/solc/v0.8.19/llo-feeds/v0.3.0/RewardManager/RewardManager.bin 7996cbc89a7f9af85b1ca4079ecf782d7138626b3f4bdb3bfa996248c9ccb9f4 +reward_manager_v0_5_0: ../../../contracts/solc/v0.8.19/llo-feeds/v0.5.0/RewardManager/RewardManager.abi ../../../contracts/solc/v0.8.19/llo-feeds/v0.5.0/RewardManager/RewardManager.bin 7996cbc89a7f9af85b1ca4079ecf782d7138626b3f4bdb3bfa996248c9ccb9f4 stream_config_store: ../../../contracts/solc/v0.8.19/StreamConfigStore/StreamConfigStore.abi ../../../contracts/solc/v0.8.19/StreamConfigStore/StreamConfigStore.bin 45ae1b0a45a90b3dee076023052aef73c212c8ef8825b829397f751f6b0a1598 -verifier: ../../../contracts/solc/v0.8.19/Verifier/Verifier.abi ../../../contracts/solc/v0.8.19/Verifier/Verifier.bin 413406be1578e9fb73e664ceb1967e6aedf5cf7c4701a2b81fe7c42b03f13573 -verifier_proxy: ../../../contracts/solc/v0.8.19/VerifierProxy/VerifierProxy.abi ../../../contracts/solc/v0.8.19/VerifierProxy/VerifierProxy.bin aca18e93b0129114f20c4c0fbaeb61c86bc0ca0724bc438ec7ae11c158038ea7 +verifier: ../../../contracts/solc/v0.8.19/llo-feeds/v0.3.0/Verifier/Verifier.abi ../../../contracts/solc/v0.8.19/llo-feeds/v0.3.0/Verifier/Verifier.bin 413406be1578e9fb73e664ceb1967e6aedf5cf7c4701a2b81fe7c42b03f13573 +verifier_proxy: ../../../contracts/solc/v0.8.19/llo-feeds/v0.3.0/VerifierProxy/VerifierProxy.abi ../../../contracts/solc/v0.8.19/llo-feeds/v0.3.0/VerifierProxy/VerifierProxy.bin aca18e93b0129114f20c4c0fbaeb61c86bc0ca0724bc438ec7ae11c158038ea7 +verifier_proxy_v0_5_0: ../../../contracts/solc/v0.8.19/llo-feeds/v0.5.0/VerifierProxy/VerifierProxy.abi ../../../contracts/solc/v0.8.19/llo-feeds/v0.5.0/VerifierProxy/VerifierProxy.bin aca18e93b0129114f20c4c0fbaeb61c86bc0ca0724bc438ec7ae11c158038ea7 +verifier_v0_5_0: ../../../contracts/solc/v0.8.19/llo-feeds/v0.5.0/Verifier/Verifier.abi ../../../contracts/solc/v0.8.19/llo-feeds/v0.5.0/Verifier/Verifier.bin 18d894dbbec00fc9d42dc8e61ee3c428e94d3c375552f1c5d1b39cfa5c9535ad werc20_mock: ../../../contracts/solc/v0.8.19/WERC20Mock.abi ../../../contracts/solc/v0.8.19/WERC20Mock.bin ff2ca3928b2aa9c412c892cb8226c4d754c73eeb291bb7481c32c48791b2aa94 diff --git a/core/gethwrappers/llo-feeds/go_generate.go b/core/gethwrappers/llo-feeds/go_generate.go index 5bc29f36dea..9a0fd295b98 100644 --- a/core/gethwrappers/llo-feeds/go_generate.go +++ b/core/gethwrappers/llo-feeds/go_generate.go @@ -2,19 +2,26 @@ // golang packages, using abigen. package gethwrappers -// Chainlink LLO -//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/Verifier/Verifier.abi ../../../contracts/solc/v0.8.19/Verifier/Verifier.bin Verifier verifier -//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/VerifierProxy/VerifierProxy.abi ../../../contracts/solc/v0.8.19/VerifierProxy/VerifierProxy.bin VerifierProxy verifier_proxy -//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/ErroredVerifier/ErroredVerifier.abi ../../../contracts/solc/v0.8.19/ErroredVerifier/ErroredVerifier.bin ErroredVerifier errored_verifier -//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/ExposedVerifier/ExposedVerifier.abi ../../../contracts/solc/v0.8.19/ExposedVerifier/ExposedVerifier.bin ExposedVerifier exposed_verifier -//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/RewardManager/RewardManager.abi ../../../contracts/solc/v0.8.19/RewardManager/RewardManager.bin RewardManager reward_manager -//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/FeeManager/FeeManager.abi ../../../contracts/solc/v0.8.19/FeeManager/FeeManager.bin FeeManager fee_manager -//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/ChannelConfigStore/ChannelConfigStore.abi ../../../contracts/solc/v0.8.19/ChannelConfigStore/ChannelConfigStore.bin ChannelConfigStore channel_config_store +// Chainlink LLO V0.3.0 +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/llo-feeds/v0.3.0/Verifier/Verifier.abi ../../../contracts/solc/v0.8.19/llo-feeds/v0.3.0/Verifier/Verifier.bin Verifier verifier +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/llo-feeds/v0.3.0/VerifierProxy/VerifierProxy.abi ../../../contracts/solc/v0.8.19/llo-feeds/v0.3.0/VerifierProxy/VerifierProxy.bin VerifierProxy verifier_proxy +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/llo-feeds/v0.3.0/RewardManager/RewardManager.abi ../../../contracts/solc/v0.8.19/llo-feeds/v0.3.0/RewardManager/RewardManager.bin RewardManager reward_manager +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/llo-feeds/v0.3.0/FeeManager/FeeManager.abi ../../../contracts/solc/v0.8.19/llo-feeds/v0.3.0/FeeManager/FeeManager.bin FeeManager fee_manager +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/llo-feeds/v0.3.0/test/mocks/ErroredVerifier/ErroredVerifier.abi ../../../contracts/solc/v0.8.19/llo-feeds/v0.3.0/test/mocks/ErroredVerifier/ErroredVerifier.bin ErroredVerifier errored_verifier +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/llo-feeds/v0.3.0/test/mocks/ExposedVerifier/ExposedVerifier.abi ../../../contracts/solc/v0.8.19/llo-feeds/v0.3.0/test/mocks/ExposedVerifier/ExposedVerifier.bin ExposedVerifier exposed_verifier -//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/DestinationVerifier/DestinationVerifier.abi ../../../contracts/solc/v0.8.19/DestinationVerifier/DestinationVerifier.bin DestinationVerifier destination_verifier -//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/DestinationVerifierProxy/DestinationVerifierProxy.abi ../../../contracts/solc/v0.8.19/DestinationVerifierProxy/DestinationVerifierProxy.bin DestinationVerifierProxy destination_verifier_proxy -//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/DestinationFeeManager/DestinationFeeManager.abi ../../../contracts/solc/v0.8.19/DestinationFeeManager/DestinationFeeManager.bin DestinationFeeManager destination_fee_manager -//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/DestinationRewardManager/DestinationRewardManager.abi ../../../contracts/solc/v0.8.19/DestinationRewardManager/DestinationRewardManager.bin DestinationRewardManager destination_reward_manager -//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/Configurator/Configurator.abi ../../../contracts/solc/v0.8.19/Configurator/Configurator.bin Configurator configurator +// Chainlink LLO V0.4.0 +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/llo-feeds/v0.4.0/DestinationVerifier/DestinationVerifier.abi ../../../contracts/solc/v0.8.19/llo-feeds/v0.4.0/DestinationVerifier/DestinationVerifier.bin DestinationVerifier destination_verifier +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/llo-feeds/v0.4.0/DestinationVerifierProxy/DestinationVerifierProxy.abi ../../../contracts/solc/v0.8.19/llo-feeds/v0.4.0/DestinationVerifierProxy/DestinationVerifierProxy.bin DestinationVerifierProxy destination_verifier_proxy +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/llo-feeds/v0.4.0/DestinationFeeManager/DestinationFeeManager.abi ../../../contracts/solc/v0.8.19/llo-feeds/v0.4.0/DestinationFeeManager/DestinationFeeManager.bin DestinationFeeManager destination_fee_manager +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/llo-feeds/v0.4.0/DestinationRewardManager/DestinationRewardManager.abi ../../../contracts/solc/v0.8.19/llo-feeds/v0.4.0/DestinationRewardManager/DestinationRewardManager.bin DestinationRewardManager destination_reward_manager -//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/ExposedConfigurator/ExposedConfigurator.abi ../../../contracts/solc/v0.8.19/ExposedConfigurator/ExposedConfigurator.bin ExposedConfigurator exposed_configurator +// Chainlink LLO V0.5.0 +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/llo-feeds/v0.5.0/Verifier/Verifier.abi ../../../contracts/solc/v0.8.19/llo-feeds/v0.5.0/Verifier/Verifier.bin Verifier verifier_v0_5_0 +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/llo-feeds/v0.5.0/VerifierProxy/VerifierProxy.abi ../../../contracts/solc/v0.8.19/llo-feeds/v0.5.0/VerifierProxy/VerifierProxy.bin VerifierProxy verifier_proxy_v0_5_0 +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/llo-feeds/v0.5.0/FeeManager/FeeManager.abi ../../../contracts/solc/v0.8.19/llo-feeds/v0.5.0/FeeManager/FeeManager.bin FeeManager fee_manager_v0_5_0 +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/llo-feeds/v0.5.0/RewardManager/RewardManager.abi ../../../contracts/solc/v0.8.19/llo-feeds/v0.5.0/RewardManager/RewardManager.bin RewardManager reward_manager_v0_5_0 + +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/llo-feeds/v0.5.0/configuration/ChannelConfigStore/ChannelConfigStore.abi ../../../contracts/solc/v0.8.19/llo-feeds/v0.5.0/configuration/ChannelConfigStore/ChannelConfigStore.bin ChannelConfigStore channel_config_store +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/llo-feeds/v0.5.0/configuration/Configurator/Configurator.abi ../../../contracts/solc/v0.8.19/llo-feeds/v0.5.0/configuration/Configurator/Configurator.bin Configurator configurator +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/llo-feeds/v0.5.0/configuration/test/mocks/ExposedConfigurator/ExposedConfigurator.abi ../../../contracts/solc/v0.8.19/llo-feeds/v0.5.0/configuration/test/mocks/ExposedConfigurator/ExposedConfigurator.bin ExposedConfigurator exposed_configurator