From 2cd4bc5508e240e2a989b4a20bb2370bf5016525 Mon Sep 17 00:00:00 2001 From: Justin Kaseman Date: Wed, 21 Feb 2024 00:28:56 -0500 Subject: [PATCH] (feat): FUN-1234 Functions USD denominated premium fees (#12104) --- .../gas-snapshots/functions.gas-snapshot | 154 +++++++++--------- .../functions/dev/v1_X/FunctionsBilling.sol | 118 ++++++++++---- .../dev/v1_X/FunctionsCoordinator.sol | 36 +++- .../dev/v1_X/interfaces/IFunctionsBilling.sol | 20 ++- .../tests/v1_X/FunctionsBilling.t.sol | 131 ++++++++++----- .../tests/v1_X/FunctionsCoordinator.t.sol | 7 +- .../tests/v1_X/FunctionsRouter.t.sol | 30 +++- .../tests/v1_X/FunctionsSubscriptions.t.sol | 12 +- .../src/v0.8/functions/tests/v1_X/Setup.t.sol | 92 ++++++++--- .../FunctionsCoordinatorHarness.sol | 22 ++- .../FunctionsCoordinatorTestHelper.sol | 24 +-- .../test/v0.8/functions/v1/RouterBase.test.ts | 3 + contracts/test/v0.8/functions/v1/utils.ts | 31 +++- .../functions_coordinator.go | 98 ++++++++--- ...rapper-dependency-versions-do-not-edit.txt | 2 +- .../v1/internal/testutils.go | 13 +- 16 files changed, 546 insertions(+), 247 deletions(-) diff --git a/contracts/gas-snapshots/functions.gas-snapshot b/contracts/gas-snapshots/functions.gas-snapshot index 279aa389e4f..fb24f678bc2 100644 --- a/contracts/gas-snapshots/functions.gas-snapshot +++ b/contracts/gas-snapshots/functions.gas-snapshot @@ -1,66 +1,68 @@ -ChainSpecificUtil__getCurrentTxL1GasFees_Arbitrum:test__getCurrentTxL1GasFees_SuccessWhenArbitrumGoerli() (gas: 14860808) -ChainSpecificUtil__getCurrentTxL1GasFees_Arbitrum:test__getCurrentTxL1GasFees_SuccessWhenArbitrumMainnet() (gas: 14860786) -ChainSpecificUtil__getCurrentTxL1GasFees_Arbitrum:test__getCurrentTxL1GasFees_SuccessWhenArbitrumSepolia() (gas: 14860802) -ChainSpecificUtil__getCurrentTxL1GasFees_Base:test__getCurrentTxL1GasFees_SuccessWhenBaseGoerli() (gas: 14872224) -ChainSpecificUtil__getCurrentTxL1GasFees_Base:test__getCurrentTxL1GasFees_SuccessWhenBaseMainnet() (gas: 14872201) -ChainSpecificUtil__getCurrentTxL1GasFees_Base:test__getCurrentTxL1GasFees_SuccessWhenBaseSepolia() (gas: 14872173) -ChainSpecificUtil__getCurrentTxL1GasFees_Optimism:test__getCurrentTxL1GasFees_SuccessWhenOptimismGoerli() (gas: 14872124) -ChainSpecificUtil__getCurrentTxL1GasFees_Optimism:test__getCurrentTxL1GasFees_SuccessWhenOptimismMainnet() (gas: 14872113) -ChainSpecificUtil__getCurrentTxL1GasFees_Optimism:test__getCurrentTxL1GasFees_SuccessWhenOptimismSepolia() (gas: 14872157) -FunctionsBilling_Constructor:test_Constructor_Success() (gas: 14812) -FunctionsBilling_DeleteCommitment:test_DeleteCommitment_RevertIfNotRouter() (gas: 13282) -FunctionsBilling_DeleteCommitment:test_DeleteCommitment_Success() (gas: 15897) -FunctionsBilling_EstimateCost:test_EstimateCost_RevertsIfGasPriceAboveCeiling() (gas: 32414) -FunctionsBilling_EstimateCost:test_EstimateCost_Success() (gas: 53763) -FunctionsBilling_EstimateCost:test_EstimateCost_SuccessLowGasPrice() (gas: 53866) -FunctionsBilling_GetAdminFee:test_GetAdminFee_Success() (gas: 18226) -FunctionsBilling_GetConfig:test_GetConfig_Success() (gas: 23693) -FunctionsBilling_GetDONFee:test_GetDONFee_Success() (gas: 15792) -FunctionsBilling_GetWeiPerUnitLink:test_GetWeiPerUnitLink_Success() (gas: 31773) -FunctionsBilling_OracleWithdraw:test_OracleWithdraw_RevertIfInsufficientBalance() (gas: 70128) -FunctionsBilling_OracleWithdraw:test_OracleWithdraw_RevertWithNoBalance() (gas: 106285) -FunctionsBilling_OracleWithdraw:test_OracleWithdraw_SuccessTransmitterWithBalanceNoAmountGiven() (gas: 140164) -FunctionsBilling_OracleWithdraw:test_OracleWithdraw_SuccessTransmitterWithBalanceValidAmountGiven() (gas: 142492) -FunctionsBilling_OracleWithdrawAll:test_OracleWithdrawAll_RevertIfNotOwner() (gas: 13296) -FunctionsBilling_OracleWithdrawAll:test_OracleWithdrawAll_SuccessPaysTransmittersWithBalance() (gas: 147278) -FunctionsBilling_UpdateConfig:test_UpdateConfig_RevertIfNotOwner() (gas: 18974) -FunctionsBilling_UpdateConfig:test_UpdateConfig_Success() (gas: 38273) +ChainSpecificUtil__getCurrentTxL1GasFees_Arbitrum:test__getCurrentTxL1GasFees_SuccessWhenArbitrumGoerli() (gas: 15924776) +ChainSpecificUtil__getCurrentTxL1GasFees_Arbitrum:test__getCurrentTxL1GasFees_SuccessWhenArbitrumMainnet() (gas: 15924754) +ChainSpecificUtil__getCurrentTxL1GasFees_Arbitrum:test__getCurrentTxL1GasFees_SuccessWhenArbitrumSepolia() (gas: 15924770) +ChainSpecificUtil__getCurrentTxL1GasFees_Base:test__getCurrentTxL1GasFees_SuccessWhenBaseGoerli() (gas: 15936218) +ChainSpecificUtil__getCurrentTxL1GasFees_Base:test__getCurrentTxL1GasFees_SuccessWhenBaseMainnet() (gas: 15936195) +ChainSpecificUtil__getCurrentTxL1GasFees_Base:test__getCurrentTxL1GasFees_SuccessWhenBaseSepolia() (gas: 15936167) +ChainSpecificUtil__getCurrentTxL1GasFees_Optimism:test__getCurrentTxL1GasFees_SuccessWhenOptimismGoerli() (gas: 15936118) +ChainSpecificUtil__getCurrentTxL1GasFees_Optimism:test__getCurrentTxL1GasFees_SuccessWhenOptimismMainnet() (gas: 15936107) +ChainSpecificUtil__getCurrentTxL1GasFees_Optimism:test__getCurrentTxL1GasFees_SuccessWhenOptimismSepolia() (gas: 15936151) +FunctionsBilling_Constructor:test_Constructor_Success() (gas: 14823) +FunctionsBilling_DeleteCommitment:test_DeleteCommitment_RevertIfNotRouter() (gas: 13260) +FunctionsBilling_DeleteCommitment:test_DeleteCommitment_Success() (gas: 15875) +FunctionsBilling_EstimateCost:test_EstimateCost_RevertsIfGasPriceAboveCeiling() (gas: 32436) +FunctionsBilling_EstimateCost:test_EstimateCost_Success() (gas: 88199) +FunctionsBilling_EstimateCost:test_EstimateCost_SuccessLowGasPrice() (gas: 88302) +FunctionsBilling_GetAdminFeeJuels:test_GetAdminFeeJuels_Success() (gas: 18334) +FunctionsBilling_GetConfig:test_GetConfig_Success() (gas: 27553) +FunctionsBilling_GetDONFeeJuels:test_GetDONFeeJuels_Success() (gas: 40831) +FunctionsBilling_GetOperationFee:test_GetOperationFeeJuels_Success() (gas: 40211) +FunctionsBilling_GetWeiPerUnitLink:test_GetWeiPerUnitLink_Success() (gas: 29414) +FunctionsBilling_OracleWithdraw:test_OracleWithdraw_RevertIfInsufficientBalance() (gas: 70107) +FunctionsBilling_OracleWithdraw:test_OracleWithdraw_RevertWithNoBalance() (gas: 106264) +FunctionsBilling_OracleWithdraw:test_OracleWithdraw_SuccessCoordinatorOwner() (gas: 129542) +FunctionsBilling_OracleWithdraw:test_OracleWithdraw_SuccessTransmitterWithBalanceNoAmountGiven() (gas: 169241) +FunctionsBilling_OracleWithdraw:test_OracleWithdraw_SuccessTransmitterWithBalanceValidAmountGiven() (gas: 142476) +FunctionsBilling_OracleWithdrawAll:test_OracleWithdrawAll_RevertIfNotOwner() (gas: 13297) +FunctionsBilling_OracleWithdrawAll:test_OracleWithdrawAll_SuccessPaysTransmittersWithBalance() (gas: 217168) +FunctionsBilling_UpdateConfig:test_UpdateConfig_RevertIfNotOwner() (gas: 21521) +FunctionsBilling_UpdateConfig:test_UpdateConfig_Success() (gas: 49192) FunctionsBilling__DisperseFeePool:test__DisperseFeePool_RevertIfNotSet() (gas: 8810) -FunctionsBilling__FulfillAndBill:test__FulfillAndBill_RevertIfInvalidCommitment() (gas: 13302) -FunctionsBilling__FulfillAndBill:test__FulfillAndBill_Success() (gas: 180763) -FunctionsBilling__StartBilling:test__FulfillAndBill_HasUniqueGlobalRequestId() (gas: 398400) +FunctionsBilling__FulfillAndBill:test__FulfillAndBill_RevertIfInvalidCommitment() (gas: 13375) +FunctionsBilling__FulfillAndBill:test__FulfillAndBill_Success() (gas: 185974) +FunctionsBilling__StartBilling:test__FulfillAndBill_HasUniqueGlobalRequestId() (gas: 523657) FunctionsClient_Constructor:test_Constructor_Success() (gas: 7573) -FunctionsClient_HandleOracleFulfillment:test_HandleOracleFulfillment_RevertIfNotRouter() (gas: 14623) -FunctionsClient_HandleOracleFulfillment:test_HandleOracleFulfillment_Success() (gas: 22923) +FunctionsClient_HandleOracleFulfillment:test_HandleOracleFulfillment_RevertIfNotRouter() (gas: 14617) +FunctionsClient_HandleOracleFulfillment:test_HandleOracleFulfillment_Success() (gas: 22917) FunctionsClient__SendRequest:test__SendRequest_RevertIfInvalidCallbackGasLimit() (gas: 55059) -FunctionsCoordinator_Constructor:test_Constructor_Success() (gas: 12006) -FunctionsCoordinator_GetDONPublicKey:test_GetDONPublicKey_RevertIfEmpty() (gas: 15356) -FunctionsCoordinator_GetDONPublicKey:test_GetDONPublicKey_Success() (gas: 106528) -FunctionsCoordinator_GetThresholdPublicKey:test_GetThresholdPublicKey_RevertIfEmpty() (gas: 15313) -FunctionsCoordinator_GetThresholdPublicKey:test_GetThresholdPublicKey_Success() (gas: 656362) -FunctionsCoordinator_SetDONPublicKey:test_SetDONPublicKey_RevertNotOwner() (gas: 20364) -FunctionsCoordinator_SetDONPublicKey:test_SetDONPublicKey_Success() (gas: 101307) +FunctionsCoordinator_Constructor:test_Constructor_Success() (gas: 12007) +FunctionsCoordinator_GetDONPublicKey:test_GetDONPublicKey_RevertIfEmpty() (gas: 15378) +FunctionsCoordinator_GetDONPublicKey:test_GetDONPublicKey_Success() (gas: 106551) +FunctionsCoordinator_GetThresholdPublicKey:test_GetThresholdPublicKey_RevertIfEmpty() (gas: 15356) +FunctionsCoordinator_GetThresholdPublicKey:test_GetThresholdPublicKey_Success() (gas: 656405) +FunctionsCoordinator_SetDONPublicKey:test_SetDONPublicKey_RevertNotOwner() (gas: 20365) +FunctionsCoordinator_SetDONPublicKey:test_SetDONPublicKey_Success() (gas: 101330) FunctionsCoordinator_SetThresholdPublicKey:test_SetThresholdPublicKey_RevertNotOwner() (gas: 13892) -FunctionsCoordinator_SetThresholdPublicKey:test_SetThresholdPublicKey_Success() (gas: 651054) -FunctionsCoordinator_StartRequest:test_StartRequest_RevertIfNotRouter() (gas: 22703) -FunctionsCoordinator_StartRequest:test_StartRequest_Success() (gas: 108804) -FunctionsCoordinator__IsTransmitter:test__IsTransmitter_SuccessFound() (gas: 18957) -FunctionsCoordinator__IsTransmitter:test__IsTransmitter_SuccessNotFound() (gas: 19690) +FunctionsCoordinator_SetThresholdPublicKey:test_SetThresholdPublicKey_Success() (gas: 651097) +FunctionsCoordinator_StartRequest:test_StartRequest_RevertIfNotRouter() (gas: 22770) +FunctionsCoordinator_StartRequest:test_StartRequest_Success() (gas: 150311) +FunctionsCoordinator__IsTransmitter:test__IsTransmitter_SuccessFound() (gas: 12275) +FunctionsCoordinator__IsTransmitter:test__IsTransmitter_SuccessNotFound() (gas: 20107) FunctionsRequest_DEFAULT_BUFFER_SIZE:test_DEFAULT_BUFFER_SIZE() (gas: 246) FunctionsRequest_EncodeCBOR:test_EncodeCBOR_Success() (gas: 223) FunctionsRequest_REQUEST_DATA_VERSION:test_REQUEST_DATA_VERSION() (gas: 225) FunctionsRouter_Constructor:test_Constructor_Success() (gas: 12007) -FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedCostExceedsCommitment() (gas: 169829) -FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedInsufficientGas() (gas: 160160) +FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedCostExceedsCommitment() (gas: 173026) +FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedInsufficientGas() (gas: 163498) FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedInvalidCommitment() (gas: 38115) FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedInvalidRequestId() (gas: 35238) -FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedSubscriptionBalanceInvariant() (gas: 178305) +FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedSubscriptionBalanceInvariant() (gas: 181502) FunctionsRouter_Fulfill:test_Fulfill_RevertIfNotCommittedCoordinator() (gas: 28086) -FunctionsRouter_Fulfill:test_Fulfill_RevertIfPaused() (gas: 153867) -FunctionsRouter_Fulfill:test_Fulfill_SuccessClientNoLongerExists() (gas: 321317) -FunctionsRouter_Fulfill:test_Fulfill_SuccessFulfilled() (gas: 334938) -FunctionsRouter_Fulfill:test_Fulfill_SuccessUserCallbackReverts() (gas: 2510364) -FunctionsRouter_Fulfill:test_Fulfill_SuccessUserCallbackRunsOutOfGas() (gas: 540803) +FunctionsRouter_Fulfill:test_Fulfill_RevertIfPaused() (gas: 157064) +FunctionsRouter_Fulfill:test_Fulfill_SuccessClientNoLongerExists() (gas: 335516) +FunctionsRouter_Fulfill:test_Fulfill_SuccessFulfilled() (gas: 349140) +FunctionsRouter_Fulfill:test_Fulfill_SuccessUserCallbackReverts() (gas: 2628028) +FunctionsRouter_Fulfill:test_Fulfill_SuccessUserCallbackRunsOutOfGas() (gas: 658982) FunctionsRouter_GetAdminFee:test_GetAdminFee_Success() (gas: 17983) FunctionsRouter_GetAllowListId:test_GetAllowListId_Success() (gas: 12904) FunctionsRouter_GetConfig:test_GetConfig_Success() (gas: 37159) @@ -71,7 +73,7 @@ FunctionsRouter_GetProposedContractById:test_GetProposedContractById_SuccessIfRo FunctionsRouter_GetProposedContractSet:test_GetProposedContractSet_Success() (gas: 25936) FunctionsRouter_IsValidCallbackGasLimit:test_IsValidCallbackGasLimit_RevertGasLimitTooBig() (gas: 28103) FunctionsRouter_IsValidCallbackGasLimit:test_IsValidCallbackGasLimit_RevertInvalidConfig() (gas: 41093) -FunctionsRouter_IsValidCallbackGasLimit:test_IsValidCallbackGasLimit_Success() (gas: 24626) +FunctionsRouter_IsValidCallbackGasLimit:test_IsValidCallbackGasLimit_Success() (gas: 24620) FunctionsRouter_Pause:test_Pause_RevertIfNotOwner() (gas: 13338) FunctionsRouter_Pause:test_Pause_Success() (gas: 20344) FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfEmptyAddress() (gas: 14791) @@ -81,15 +83,15 @@ FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfNotNe FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfNotOwner() (gas: 23392) FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_Success() (gas: 118479) FunctionsRouter_SendRequest:test_SendRequest_RevertIfConsumerNotAllowed() (gas: 59391) -FunctionsRouter_SendRequest:test_SendRequest_RevertIfDuplicateRequestId() (gas: 193436) +FunctionsRouter_SendRequest:test_SendRequest_RevertIfDuplicateRequestId() (gas: 217981) FunctionsRouter_SendRequest:test_SendRequest_RevertIfEmptyData() (gas: 29426) FunctionsRouter_SendRequest:test_SendRequest_RevertIfIncorrectDonId() (gas: 57904) -FunctionsRouter_SendRequest:test_SendRequest_RevertIfInsufficientSubscriptionBalance() (gas: 187020) +FunctionsRouter_SendRequest:test_SendRequest_RevertIfInsufficientSubscriptionBalance() (gas: 208541) FunctionsRouter_SendRequest:test_SendRequest_RevertIfInvalidCallbackGasLimit() (gas: 50947) FunctionsRouter_SendRequest:test_SendRequest_RevertIfInvalidDonId() (gas: 25082) FunctionsRouter_SendRequest:test_SendRequest_RevertIfNoSubscription() (gas: 29132) FunctionsRouter_SendRequest:test_SendRequest_RevertIfPaused() (gas: 34291) -FunctionsRouter_SendRequest:test_SendRequest_Success() (gas: 286199) +FunctionsRouter_SendRequest:test_SendRequest_Success() (gas: 317671) FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfConsumerNotAllowed() (gas: 65887) FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfEmptyData() (gas: 36012) FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfIncorrectDonId() (gas: 29896) @@ -97,8 +99,8 @@ FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfInvalid FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfInvalidDonId() (gas: 27503) FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfNoSubscription() (gas: 35717) FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfPaused() (gas: 40810) -FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_Success() (gas: 292746) -FunctionsRouter_SendRequestToProposed:test_SendRequest_RevertIfInsufficientSubscriptionBalance() (gas: 193512) +FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_Success() (gas: 324108) +FunctionsRouter_SendRequestToProposed:test_SendRequest_RevertIfInsufficientSubscriptionBalance() (gas: 214989) FunctionsRouter_SetAllowListId:test_SetAllowListId_Success() (gas: 30688) FunctionsRouter_SetAllowListId:test_UpdateConfig_RevertIfNotOwner() (gas: 13403) FunctionsRouter_Unpause:test_Unpause_RevertIfNotOwner() (gas: 13293) @@ -111,7 +113,7 @@ FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOw FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfPaused() (gas: 61031) FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfSenderBecomesBlocked() (gas: 139404) FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfSenderIsNotNewOwner() (gas: 62781) -FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_Success() (gas: 215285) +FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_Success() (gas: 239409) FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfMaximumConsumers() (gas: 138025) FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfMaximumConsumersAfterConfigUpdate() (gas: 164969) FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfNoSubscription() (gas: 12946) @@ -123,7 +125,7 @@ FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNoSubs FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNotAllowedSender() (gas: 102524) FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNotSubscriptionOwner() (gas: 89309) FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfPaused() (gas: 20148) -FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfPendingRequests() (gas: 194369) +FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfPendingRequests() (gas: 218493) FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_SuccessForfeitAllBalanceAsDeposit() (gas: 114541) FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_SuccessForfeitSomeBalanceAsDeposit() (gas: 125867) FunctionsSubscriptions_CancelSubscription_ReceiveDeposit:test_CancelSubscription_SuccessRecieveDeposit() (gas: 75017) @@ -156,16 +158,16 @@ FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_Reve FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_Success() (gas: 54867) FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_SuccessDeletesSubscription() (gas: 49607) FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_SuccessSubOwnerRefunded() (gas: 50896) -FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_SuccessWhenRequestInFlight() (gas: 164812) +FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_SuccessWhenRequestInFlight() (gas: 186697) FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_RevertIfAmountMoreThanBalance() (gas: 17924) FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_RevertIfBalanceInvariant() (gas: 210) FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_RevertIfNotOwner() (gas: 15555) -FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessIfNoAmount() (gas: 37396) -FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessIfRecipientAddressZero() (gas: 52130) -FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessPaysRecipient() (gas: 54413) -FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessSetsBalanceToZero() (gas: 37790) +FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessIfNoAmount() (gas: 30996) +FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessIfRecipientAddressZero() (gas: 28809) +FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessPaysRecipient() (gas: 31092) +FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessSetsBalanceToZero() (gas: 31569) FunctionsSubscriptions_PendingRequestExists:test_PendingRequestExists_SuccessFalseIfNoPendingRequests() (gas: 14981) -FunctionsSubscriptions_PendingRequestExists:test_PendingRequestExists_SuccessTrueIfPendingRequests() (gas: 176478) +FunctionsSubscriptions_PendingRequestExists:test_PendingRequestExists_SuccessTrueIfPendingRequests() (gas: 200618) FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfEmptyNewOwner() (gas: 27655) FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfInvalidNewOwner() (gas: 57797) FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfNoSubscription() (gas: 15001) @@ -181,7 +183,7 @@ FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfNoSubscription FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfNotAllowedSender() (gas: 102439) FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfNotSubscriptionOwner() (gas: 87245) FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfPaused() (gas: 18049) -FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfPendingRequests() (gas: 191894) +FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfPendingRequests() (gas: 216026) FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_Success() (gas: 42023) FunctionsSubscriptions_SetFlags:test_SetFlags_RevertIfNoSubscription() (gas: 12891) FunctionsSubscriptions_SetFlags:test_SetFlags_RevertIfNotOwner() (gas: 15684) @@ -189,7 +191,7 @@ FunctionsSubscriptions_SetFlags:test_SetFlags_Success() (gas: 35594) FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_RevertIfPaused() (gas: 25955) FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_RevertIfTimeoutNotExceeded() (gas: 25261) FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_RevertInvalidRequest() (gas: 28242) -FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_Success() (gas: 57754) +FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_Success() (gas: 57732) FunctionsSubscriptions_createSubscription:test_CreateSubscription_RevertIfNotAllowedSender() (gas: 26434) FunctionsSubscriptions_createSubscription:test_CreateSubscription_RevertIfPaused() (gas: 15759) FunctionsSubscriptions_createSubscription:test_CreateSubscription_Success() (gas: 152708) @@ -206,12 +208,12 @@ FunctionsTermsOfServiceAllowList_BlockSender:test_BlockSender_Success() (gas: 96 FunctionsTermsOfServiceAllowList_Constructor:test_Constructor_Success() (gas: 12253) FunctionsTermsOfServiceAllowList_GetAllAllowedSenders:test_GetAllAllowedSenders_Success() (gas: 19199) FunctionsTermsOfServiceAllowList_GetAllowedSendersCount:test_GetAllowedSendersCount_Success() (gas: 12995) -FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_RevertIfAllowedSendersIsEmpty() (gas: 12239111) +FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_RevertIfAllowedSendersIsEmpty() (gas: 13158901) FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_RevertIfEndIsAfterLastAllowedSender() (gas: 16571) FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_RevertIfStartIsAfterEnd() (gas: 13301) FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_Success() (gas: 20448) FunctionsTermsOfServiceAllowList_GetBlockedSendersCount:test_GetBlockedSendersCount_Success() (gas: 12931) -FunctionsTermsOfServiceAllowList_GetBlockedSendersInRange:test_GetBlockedSendersInRange_RevertIfAllowedSendersIsEmpty() (gas: 12239115) +FunctionsTermsOfServiceAllowList_GetBlockedSendersInRange:test_GetBlockedSendersInRange_RevertIfAllowedSendersIsEmpty() (gas: 13158905) FunctionsTermsOfServiceAllowList_GetBlockedSendersInRange:test_GetBlockedSendersInRange_RevertIfEndIsAfterLastAllowedSender() (gas: 16549) FunctionsTermsOfServiceAllowList_GetBlockedSendersInRange:test_GetBlockedSendersInRange_RevertIfStartIsAfterEnd() (gas: 13367) FunctionsTermsOfServiceAllowList_GetBlockedSendersInRange:test_GetBlockedSendersInRange_Success() (gas: 18493) @@ -228,10 +230,10 @@ FunctionsTermsOfServiceAllowList_UpdateConfig:test_UpdateConfig_Success() (gas: Gas_AcceptTermsOfService:test_AcceptTermsOfService_Gas() (gas: 84702) Gas_AddConsumer:test_AddConsumer_Gas() (gas: 79131) Gas_CreateSubscription:test_CreateSubscription_Gas() (gas: 73419) -Gas_FulfillRequest_DuplicateRequestID:test_FulfillRequest_DuplicateRequestID_MaximumGas() (gas: 20695) -Gas_FulfillRequest_DuplicateRequestID:test_FulfillRequest_DuplicateRequestID_MinimumGas() (gas: 20135) -Gas_FulfillRequest_Success:test_FulfillRequest_Success_MaximumGas() (gas: 498083) -Gas_FulfillRequest_Success:test_FulfillRequest_Success_MinimumGas() (gas: 199286) +Gas_FulfillRequest_DuplicateRequestID:test_FulfillRequest_DuplicateRequestID_MaximumGas() (gas: 20717) +Gas_FulfillRequest_DuplicateRequestID:test_FulfillRequest_DuplicateRequestID_MinimumGas() (gas: 20157) +Gas_FulfillRequest_Success:test_FulfillRequest_Success_MaximumGas() (gas: 501825) +Gas_FulfillRequest_Success:test_FulfillRequest_Success_MinimumGas() (gas: 203029) Gas_FundSubscription:test_FundSubscription_Gas() (gas: 38546) -Gas_SendRequest:test_SendRequest_MaximumGas() (gas: 979631) -Gas_SendRequest:test_SendRequest_MinimumGas() (gas: 157578) \ No newline at end of file +Gas_SendRequest:test_SendRequest_MaximumGas() (gas: 1003809) +Gas_SendRequest:test_SendRequest_MinimumGas() (gas: 181701) \ No newline at end of file diff --git a/contracts/src/v0.8/functions/dev/v1_X/FunctionsBilling.sol b/contracts/src/v0.8/functions/dev/v1_X/FunctionsBilling.sol index 3abfd893186..b6b65c4e556 100644 --- a/contracts/src/v0.8/functions/dev/v1_X/FunctionsBilling.sol +++ b/contracts/src/v0.8/functions/dev/v1_X/FunctionsBilling.sol @@ -26,7 +26,9 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { uint96 juelsPerGas, uint256 l1FeeShareWei, uint96 callbackCostJuels, - uint96 totalCostJuels + uint72 donFeeJuels, + uint72 adminFeeJuels, + uint72 operationFeeJuels ); // ================================================================ @@ -47,6 +49,7 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { error UnauthorizedSender(); error MustBeSubOwner(address owner); error InvalidLinkWeiPrice(int256 linkWei); + error InvalidUsdLinkPrice(int256 usdLink); error PaymentTooLarge(); error NoTransmittersSet(); error InvalidCalldata(); @@ -61,12 +64,19 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { uint96 internal s_feePool; AggregatorV3Interface private s_linkToNativeFeed; + AggregatorV3Interface private s_linkToUsdFeed; // ================================================================ // | Initialization | // ================================================================ - constructor(address router, FunctionsBillingConfig memory config, address linkToNativeFeed) Routable(router) { + constructor( + address router, + FunctionsBillingConfig memory config, + address linkToNativeFeed, + address linkToUsdFeed + ) Routable(router) { s_linkToNativeFeed = AggregatorV3Interface(linkToNativeFeed); + s_linkToUsdFeed = AggregatorV3Interface(linkToUsdFeed); updateConfig(config); } @@ -95,22 +105,28 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { // ================================================================ /// @inheritdoc IFunctionsBilling - function getDONFee(bytes memory /* requestData */) public view override returns (uint72) { - return s_config.donFee; + function getDONFeeJuels(bytes memory /* requestData */) public view override returns (uint72) { + // s_config.donFee is in cents of USD. Get Juel amount then convert to dollars. + return SafeCast.toUint72(_getJuelsFromUsd(s_config.donFeeCentsUsd) / 100); } /// @inheritdoc IFunctionsBilling - function getAdminFee() public view override returns (uint72) { + function getOperationFeeJuels() public view override returns (uint72) { + // s_config.donFee is in cents of USD. Get Juel amount then convert to dollars. + return SafeCast.toUint72(_getJuelsFromUsd(s_config.operationFeeCentsUsd) / 100); + } + + /// @inheritdoc IFunctionsBilling + function getAdminFeeJuels() public view override returns (uint72) { return _getRouter().getAdminFee(); } /// @inheritdoc IFunctionsBilling function getWeiPerUnitLink() public view returns (uint256) { - FunctionsBillingConfig memory config = s_config; (, int256 weiPerUnitLink, , uint256 timestamp, ) = s_linkToNativeFeed.latestRoundData(); // solhint-disable-next-line not-rely-on-time - if (config.feedStalenessSeconds < block.timestamp - timestamp && config.feedStalenessSeconds > 0) { - return config.fallbackNativePerUnitLink; + if (s_config.feedStalenessSeconds < block.timestamp - timestamp && s_config.feedStalenessSeconds > 0) { + return s_config.fallbackNativePerUnitLink; } if (weiPerUnitLink <= 0) { revert InvalidLinkWeiPrice(weiPerUnitLink); @@ -124,6 +140,26 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { return SafeCast.toUint96((1e18 * amountWei) / getWeiPerUnitLink()); } + /// @inheritdoc IFunctionsBilling + function getUsdPerUnitLink() public view returns (uint256, uint8) { + (, int256 usdPerUnitLink, , uint256 timestamp, ) = s_linkToUsdFeed.latestRoundData(); + // solhint-disable-next-line not-rely-on-time + if (s_config.feedStalenessSeconds < block.timestamp - timestamp && s_config.feedStalenessSeconds > 0) { + return (s_config.fallbackUsdPerUnitLink, s_config.fallbackUsdPerUnitLinkDecimals); + } + if (usdPerUnitLink <= 0) { + revert InvalidUsdLinkPrice(usdPerUnitLink); + } + return (uint256(usdPerUnitLink), s_linkToUsdFeed.decimals()); + } + + function _getJuelsFromUsd(uint256 amountUsd) private view returns (uint96) { + (uint256 usdPerLink, uint8 decimals) = getUsdPerUnitLink(); + // (usd) * (10**18 juels/link) * (10**decimals) / (link / usd) = juels + // There are only 1e9*1e18 = 1e27 juels in existence, should not exceed uint96 (2^96 ~ 7e28) + return SafeCast.toUint96((amountUsd * 10 ** (18 + decimals)) / usdPerLink); + } + // ================================================================ // | Cost Estimation | // ================================================================ @@ -140,9 +176,10 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { if (gasPriceWei > REASONABLE_GAS_PRICE_CEILING) { revert InvalidCalldata(); } - uint72 adminFee = getAdminFee(); - uint72 donFee = getDONFee(data); - return _calculateCostEstimate(callbackGasLimit, gasPriceWei, donFee, adminFee); + uint72 adminFee = getAdminFeeJuels(); + uint72 donFee = getDONFeeJuels(data); + uint72 operationFee = getOperationFeeJuels(); + return _calculateCostEstimate(callbackGasLimit, gasPriceWei, donFee, adminFee, operationFee); } /// @notice Estimate the cost in Juels of LINK @@ -151,8 +188,9 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { function _calculateCostEstimate( uint32 callbackGasLimit, uint256 gasPriceWei, - uint72 donFee, - uint72 adminFee + uint72 donFeeJuels, + uint72 adminFeeJuels, + uint72 operationFeeJuels ) internal view returns (uint96) { // If gas price is less than the minimum fulfillment gas price, override to using the minimum if (gasPriceWei < s_config.minimumEstimateGasPriceWei) { @@ -167,7 +205,7 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { uint256 l1FeeWei = ChainSpecificUtil._getCurrentTxL1GasFees(msg.data); uint96 estimatedGasReimbursementJuels = _getJuelsFromWei((gasPriceWithOverestimation * executionGas) + l1FeeWei); - uint96 feesJuels = uint96(donFee) + uint96(adminFee); + uint96 feesJuels = uint96(donFeeJuels) + uint96(adminFeeJuels) + uint96(operationFeeJuels); return estimatedGasReimbursementJuels + feesJuels; } @@ -182,20 +220,20 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { /// @return commitment - The parameters of the request that must be held consistent at response time function _startBilling( FunctionsResponse.RequestMeta memory request - ) internal returns (FunctionsResponse.Commitment memory commitment) { - FunctionsBillingConfig memory config = s_config; - + ) internal returns (FunctionsResponse.Commitment memory commitment, uint72 operationFee) { // Nodes should support all past versions of the structure - if (request.dataVersion > config.maxSupportedRequestDataVersion) { + if (request.dataVersion > s_config.maxSupportedRequestDataVersion) { revert UnsupportedRequestDataVersion(); } - uint72 donFee = getDONFee(request.data); + uint72 donFee = getDONFeeJuels(request.data); + operationFee = getOperationFeeJuels(); uint96 estimatedTotalCostJuels = _calculateCostEstimate( request.callbackGasLimit, tx.gasprice, donFee, - request.adminFee + request.adminFee, + operationFee ); // Check that subscription can afford the estimated cost @@ -203,7 +241,7 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { revert InsufficientBalance(); } - uint32 timeoutTimestamp = uint32(block.timestamp + config.requestTimeoutSeconds); + uint32 timeoutTimestamp = uint32(block.timestamp + s_config.requestTimeoutSeconds); bytes32 requestId = keccak256( abi.encode( address(this), @@ -230,13 +268,13 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { timeoutTimestamp: timeoutTimestamp, requestId: requestId, donFee: donFee, - gasOverheadBeforeCallback: config.gasOverheadBeforeCallback, - gasOverheadAfterCallback: config.gasOverheadAfterCallback + gasOverheadBeforeCallback: s_config.gasOverheadBeforeCallback, + gasOverheadAfterCallback: s_config.gasOverheadAfterCallback }); s_requestCommitments[requestId] = keccak256(abi.encode(commitment)); - return commitment; + return (commitment, operationFee); } /// @notice Finalize billing process for an Functions request by sending a callback to the Client contract and then charging the subscription @@ -268,9 +306,24 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { response, err, juelsPerGas, - gasOverheadJuels + commitment.donFee, // cost without callback or admin fee, those will be added by the Router + // The following line represents: "cost without callback or admin fee, those will be added by the Router" + // But because the _offchain_ Commitment is using operation fee in the place of the admin fee, this now adds admin fee (actually operation fee) + // Admin fee is configured to 0 in the Router + gasOverheadJuels + commitment.donFee + commitment.adminFee, msg.sender, - commitment + FunctionsResponse.Commitment({ + adminFee: 0, // The Router should have adminFee set to 0. If it does not this will cause fulfillments to fail with INVALID_COMMITMENT instead of carrying out incorrect bookkeeping. + coordinator: commitment.coordinator, + client: commitment.client, + subscriptionId: commitment.subscriptionId, + callbackGasLimit: commitment.callbackGasLimit, + estimatedTotalCostJuels: commitment.estimatedTotalCostJuels, + timeoutTimestamp: commitment.timeoutTimestamp, + requestId: commitment.requestId, + donFee: commitment.donFee, + gasOverheadBeforeCallback: commitment.gasOverheadBeforeCallback, + gasOverheadAfterCallback: commitment.gasOverheadAfterCallback + }) ); // The router will only pay the DON on successfully processing the fulfillment @@ -282,19 +335,23 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { ) { delete s_requestCommitments[requestId]; // Reimburse the transmitter for the fulfillment gas cost - s_withdrawableTokens[msg.sender] = gasOverheadJuels + callbackCostJuels; + s_withdrawableTokens[msg.sender] += gasOverheadJuels + callbackCostJuels; // Put donFee into the pool of fees, to be split later // Saves on storage writes that would otherwise be charged to the user s_feePool += commitment.donFee; + // Pay the operation fee to the Coordinator owner + s_withdrawableTokens[_owner()] += commitment.adminFee; // OperationFee is used in the slot for Admin Fee in the Offchain Commitment. Admin Fee is set to 0 in the Router (enforced by line 316 in FunctionsBilling.sol). emit RequestBilled({ requestId: requestId, juelsPerGas: juelsPerGas, l1FeeShareWei: l1FeeShareWei, callbackCostJuels: callbackCostJuels, - totalCostJuels: gasOverheadJuels + callbackCostJuels + commitment.donFee + commitment.adminFee + donFeeJuels: commitment.donFee, + // The following two lines are because of OperationFee being used in the Offchain Commitment + adminFeeJuels: 0, + operationFeeJuels: commitment.adminFee }); } - return resultCode; } @@ -377,4 +434,7 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { function _isExistingRequest(bytes32 requestId) internal view returns (bool) { return s_requestCommitments[requestId] != bytes32(0); } + + // Overriden in FunctionsCoordinator.sol + function _owner() internal view virtual returns (address owner); } diff --git a/contracts/src/v0.8/functions/dev/v1_X/FunctionsCoordinator.sol b/contracts/src/v0.8/functions/dev/v1_X/FunctionsCoordinator.sol index 9b3e0cc7d7b..a70a8a752bb 100644 --- a/contracts/src/v0.8/functions/dev/v1_X/FunctionsCoordinator.sol +++ b/contracts/src/v0.8/functions/dev/v1_X/FunctionsCoordinator.sol @@ -17,7 +17,7 @@ contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilli /// @inheritdoc ITypeAndVersion // solhint-disable-next-line chainlink-solidity/all-caps-constant-storage-variables - string public constant override typeAndVersion = "Functions Coordinator v1.2.0"; + string public constant override typeAndVersion = "Functions Coordinator v1.3.0"; event OracleRequest( bytes32 indexed requestId, @@ -43,8 +43,9 @@ contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilli constructor( address router, FunctionsBillingConfig memory config, - address linkToNativeFeed - ) OCR2Base() FunctionsBilling(router, config, linkToNativeFeed) {} + address linkToNativeFeed, + address linkToUsdFeed + ) OCR2Base() FunctionsBilling(router, config, linkToNativeFeed, linkToUsdFeed) {} /// @inheritdoc IFunctionsCoordinator function getThresholdPublicKey() external view override returns (bytes memory) { @@ -80,10 +81,9 @@ contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilli /// @dev check if node is in current transmitter list function _isTransmitter(address node) internal view returns (bool) { - address[] memory nodes = s_transmitters; // Bounded by "maxNumOracles" on OCR2Abstract.sol - for (uint256 i = 0; i < nodes.length; ++i) { - if (nodes[i] == node) { + for (uint256 i = 0; i < s_transmitters.length; ++i) { + if (s_transmitters[i] == node) { return true; } } @@ -94,7 +94,8 @@ contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilli function startRequest( FunctionsResponse.RequestMeta calldata request ) external override onlyRouter returns (FunctionsResponse.Commitment memory commitment) { - commitment = _startBilling(request); + uint72 operationFee; + (commitment, operationFee) = _startBilling(request); emit OracleRequest( commitment.requestId, @@ -107,7 +108,21 @@ contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilli request.dataVersion, request.flags, request.callbackGasLimit, - commitment + FunctionsResponse.Commitment({ + coordinator: commitment.coordinator, + client: commitment.client, + subscriptionId: commitment.subscriptionId, + callbackGasLimit: commitment.callbackGasLimit, + estimatedTotalCostJuels: commitment.estimatedTotalCostJuels, + timeoutTimestamp: commitment.timeoutTimestamp, + requestId: commitment.requestId, + donFee: commitment.donFee, + gasOverheadBeforeCallback: commitment.gasOverheadBeforeCallback, + gasOverheadAfterCallback: commitment.gasOverheadAfterCallback, + // The following line is done to use the Coordinator's operationFee in place of the Router's operation fee + // With this in place the Router.adminFee must be set to 0 in the Router. + adminFee: operationFee + }) ); return commitment; @@ -205,4 +220,9 @@ contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilli function _onlyOwner() internal view override { _validateOwnership(); } + + /// @dev Used in FunctionsBilling.sol + function _owner() internal view override returns (address owner) { + return this.owner(); + } } diff --git a/contracts/src/v0.8/functions/dev/v1_X/interfaces/IFunctionsBilling.sol b/contracts/src/v0.8/functions/dev/v1_X/interfaces/IFunctionsBilling.sol index 0bd7817f779..79806f1eb18 100644 --- a/contracts/src/v0.8/functions/dev/v1_X/interfaces/IFunctionsBilling.sol +++ b/contracts/src/v0.8/functions/dev/v1_X/interfaces/IFunctionsBilling.sol @@ -7,14 +7,23 @@ interface IFunctionsBilling { /// @return weiPerUnitLink - The amount of WEI in one LINK function getWeiPerUnitLink() external view returns (uint256); + /// @notice Return the current conversion from LINK to USD from the configured Chainlink data feed + /// @return weiPerUnitLink - The amount of USD that one LINK is worth + /// @return decimals - The number of decimals that should be represented in the price feed's response + function getUsdPerUnitLink() external view returns (uint256, uint8); + /// @notice Determine the fee that will be split between Node Operators for servicing a request /// @param requestCBOR - CBOR encoded Chainlink Functions request data, use FunctionsRequest library to encode a request /// @return fee - Cost in Juels (1e18) of LINK - function getDONFee(bytes memory requestCBOR) external view returns (uint72); + function getDONFeeJuels(bytes memory requestCBOR) external view returns (uint72); + + /// @notice Determine the fee that will be paid to the Coordinator owner for operating the network + /// @return fee - Cost in Juels (1e18) of LINK + function getOperationFeeJuels() external view returns (uint72); /// @notice Determine the fee that will be paid to the Router owner for operating the network /// @return fee - Cost in Juels (1e18) of LINK - function getAdminFee() external view returns (uint72); + function getAdminFeeJuels() external view returns (uint72); /// @notice Estimate the total cost that will be charged to a subscription to make a request: transmitter gas re-reimbursement, plus DON fee, plus Registry fee /// @param - subscriptionId An identifier of the billing account @@ -53,9 +62,12 @@ struct FunctionsBillingConfig { uint32 feedStalenessSeconds; // ║ How long before we consider the feed price to be stale and fallback to fallbackNativePerUnitLink. uint32 gasOverheadBeforeCallback; // ║ Represents the average gas execution cost before the fulfillment callback. This amount is always billed for every request. uint32 gasOverheadAfterCallback; // ║ Represents the average gas execution cost after the fulfillment callback. This amount is always billed for every request. - uint72 donFee; // ║ Additional flat fee (in Juels of LINK) that will be split between Node Operators. Max value is 2^80 - 1 == 1.2m LINK. uint40 minimumEstimateGasPriceWei; // ║ The lowest amount of wei that will be used as the tx.gasprice when estimating the cost to fulfill the request - uint16 maxSupportedRequestDataVersion; // ═══════╝ The highest support request data version supported by the node. All lower versions should also be supported. + uint16 maxSupportedRequestDataVersion; // ║ The highest support request data version supported by the node. All lower versions should also be supported. + uint64 fallbackUsdPerUnitLink; // ║ Fallback LINK / USD conversion rate if the data feed is stale + uint8 fallbackUsdPerUnitLinkDecimals; // ════════╝ Fallback LINK / USD conversion rate decimal places if the data feed is stale uint224 fallbackNativePerUnitLink; // ═══════════╗ Fallback NATIVE CURRENCY / LINK conversion rate if the data feed is stale uint32 requestTimeoutSeconds; // ════════════════╝ How many seconds it takes before we consider a request to be timed out + uint16 donFeeCentsUsd; // ═══════════════════════════════╗ Additional flat fee (denominated in cents of USD, paid as LINK) that will be split between Node Operators. + uint16 operationFeeCentsUsd; // ═════════════════════════╝ Additional flat fee (denominated in cents of USD, paid as LINK) that will be paid to the owner of the Coordinator contract. } diff --git a/contracts/src/v0.8/functions/tests/v1_X/FunctionsBilling.t.sol b/contracts/src/v0.8/functions/tests/v1_X/FunctionsBilling.t.sol index 66640003427..774fe4e875c 100644 --- a/contracts/src/v0.8/functions/tests/v1_X/FunctionsBilling.t.sol +++ b/contracts/src/v0.8/functions/tests/v1_X/FunctionsBilling.t.sol @@ -32,7 +32,7 @@ contract FunctionsBilling_GetConfig is FunctionsRouterSetup { assertEq(config.gasOverheadBeforeCallback, getCoordinatorConfig().gasOverheadBeforeCallback); assertEq(config.gasOverheadAfterCallback, getCoordinatorConfig().gasOverheadAfterCallback); assertEq(config.requestTimeoutSeconds, getCoordinatorConfig().requestTimeoutSeconds); - assertEq(config.donFee, getCoordinatorConfig().donFee); + assertEq(config.donFeeCentsUsd, getCoordinatorConfig().donFeeCentsUsd); assertEq(config.maxSupportedRequestDataVersion, getCoordinatorConfig().maxSupportedRequestDataVersion); assertEq(config.fulfillmentGasPriceOverEstimationBP, getCoordinatorConfig().fulfillmentGasPriceOverEstimationBP); assertEq(config.fallbackNativePerUnitLink, getCoordinatorConfig().fallbackNativePerUnitLink); @@ -46,15 +46,19 @@ contract FunctionsBilling_UpdateConfig is FunctionsRouterSetup { function setUp() public virtual override { FunctionsRouterSetup.setUp(); + // Multiply all config values by 2 to confirm that they change configToSet = FunctionsBillingConfig({ feedStalenessSeconds: getCoordinatorConfig().feedStalenessSeconds * 2, gasOverheadAfterCallback: getCoordinatorConfig().gasOverheadAfterCallback * 2, gasOverheadBeforeCallback: getCoordinatorConfig().gasOverheadBeforeCallback * 2, requestTimeoutSeconds: getCoordinatorConfig().requestTimeoutSeconds * 2, - donFee: getCoordinatorConfig().donFee * 2, + donFeeCentsUsd: getCoordinatorConfig().donFeeCentsUsd * 2, + operationFeeCentsUsd: getCoordinatorConfig().operationFeeCentsUsd * 2, maxSupportedRequestDataVersion: getCoordinatorConfig().maxSupportedRequestDataVersion * 2, fulfillmentGasPriceOverEstimationBP: getCoordinatorConfig().fulfillmentGasPriceOverEstimationBP * 2, fallbackNativePerUnitLink: getCoordinatorConfig().fallbackNativePerUnitLink * 2, + fallbackUsdPerUnitLink: getCoordinatorConfig().fallbackUsdPerUnitLink * 2, + fallbackUsdPerUnitLinkDecimals: getCoordinatorConfig().fallbackUsdPerUnitLinkDecimals * 2, minimumEstimateGasPriceWei: getCoordinatorConfig().minimumEstimateGasPriceWei * 2 }); } @@ -86,34 +90,53 @@ contract FunctionsBilling_UpdateConfig is FunctionsRouterSetup { assertEq(config.gasOverheadAfterCallback, configToSet.gasOverheadAfterCallback); assertEq(config.gasOverheadBeforeCallback, configToSet.gasOverheadBeforeCallback); assertEq(config.requestTimeoutSeconds, configToSet.requestTimeoutSeconds); - assertEq(config.donFee, configToSet.donFee); + assertEq(config.donFeeCentsUsd, configToSet.donFeeCentsUsd); + assertEq(config.operationFeeCentsUsd, configToSet.operationFeeCentsUsd); assertEq(config.maxSupportedRequestDataVersion, configToSet.maxSupportedRequestDataVersion); assertEq(config.fulfillmentGasPriceOverEstimationBP, configToSet.fulfillmentGasPriceOverEstimationBP); assertEq(config.fallbackNativePerUnitLink, configToSet.fallbackNativePerUnitLink); assertEq(config.minimumEstimateGasPriceWei, configToSet.minimumEstimateGasPriceWei); + assertEq(config.fallbackUsdPerUnitLink, configToSet.fallbackUsdPerUnitLink); + assertEq(config.fallbackUsdPerUnitLinkDecimals, configToSet.fallbackUsdPerUnitLinkDecimals); } } /// @notice #getDONFee -contract FunctionsBilling_GetDONFee is FunctionsRouterSetup { - function test_GetDONFee_Success() public { +contract FunctionsBilling_GetDONFeeJuels is FunctionsRouterSetup { + function test_GetDONFeeJuels_Success() public { // Send as stranger vm.stopPrank(); vm.startPrank(STRANGER_ADDRESS); - uint72 donFee = s_functionsCoordinator.getDONFee(new bytes(0)); - assertEq(donFee, s_donFee); + uint72 donFee = s_functionsCoordinator.getDONFeeJuels(new bytes(0)); + uint72 expectedDonFee = uint72(((s_donFee * 10 ** (18 + LINK_USD_DECIMALS)) / uint256(LINK_USD_RATE)) / 100); + assertEq(donFee, expectedDonFee); + } +} + +/// @notice #getOperationFee +contract FunctionsBilling_GetOperationFee is FunctionsRouterSetup { + function test_GetOperationFeeJuels_Success() public { + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + + uint72 operationFee = s_functionsCoordinator.getOperationFeeJuels(); + uint72 expectedOperationFee = uint72( + ((s_operationFee * 10 ** (18 + LINK_USD_DECIMALS)) / uint256(LINK_USD_RATE)) / 100 + ); + assertEq(operationFee, expectedOperationFee); } } /// @notice #getAdminFee -contract FunctionsBilling_GetAdminFee is FunctionsRouterSetup { - function test_GetAdminFee_Success() public { +contract FunctionsBilling_GetAdminFeeJuels is FunctionsRouterSetup { + function test_GetAdminFeeJuels_Success() public { // Send as stranger vm.stopPrank(); vm.startPrank(STRANGER_ADDRESS); - uint72 adminFee = s_functionsCoordinator.getAdminFee(); + uint72 adminFee = s_functionsCoordinator.getAdminFeeJuels(); assertEq(adminFee, s_adminFee); } } @@ -183,7 +206,10 @@ contract FunctionsBilling_EstimateCost is FunctionsSubscriptionSetup { callbackGasLimit, gasPriceWei ); - uint96 expectedCostEstimate = 51110500000000200; + uint96 expectedCostEstimate = 51110500000000000 + + s_adminFee + + s_functionsCoordinator.getDONFeeJuels(requestData) + + s_functionsCoordinator.getOperationFeeJuels(); assertEq(costEstimate, expectedCostEstimate); } @@ -208,7 +234,10 @@ contract FunctionsBilling_EstimateCost is FunctionsSubscriptionSetup { callbackGasLimit, gasPriceWei ); - uint96 expectedCostEstimate = 255552500000000200; + uint96 expectedCostEstimate = 255552500000000000 + + s_adminFee + + s_functionsCoordinator.getDONFeeJuels(requestData) + + s_functionsCoordinator.getOperationFeeJuels(); assertEq(costEstimate, expectedCostEstimate); } } @@ -276,17 +305,15 @@ contract FunctionsBilling__FulfillAndBill is FunctionsClientRequestSetup { uint96 juelsPerGas, uint256 l1FeeShareWei, uint96 callbackCostJuels, - uint96 totalCostJuels + uint72 donFee, + uint72 adminFee, + uint72 operationFee ); function test__FulfillAndBill_Success() public { uint96 juelsPerGas = uint96((1e18 * TX_GASPRICE_START) / uint256(LINK_ETH_RATE)); uint96 callbackCostGas = 5072; // Taken manually uint96 callbackCostJuels = juelsPerGas * callbackCostGas; - uint96 gasOverheadJuels = juelsPerGas * - (getCoordinatorConfig().gasOverheadBeforeCallback + getCoordinatorConfig().gasOverheadAfterCallback); - - uint96 totalCostJuels = gasOverheadJuels + callbackCostJuels + s_donFee + s_adminFee; // topic0 (function signature, always checked), check topic1 (true), NOT topic2 (false), NOT topic3 (false), and data (true). bool checkTopic1 = true; @@ -294,7 +321,15 @@ contract FunctionsBilling__FulfillAndBill is FunctionsClientRequestSetup { bool checkTopic3 = false; bool checkData = true; vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData); - emit RequestBilled(s_requests[1].requestId, juelsPerGas, 0, callbackCostJuels, totalCostJuels); + emit RequestBilled( + s_requests[1].requestId, + juelsPerGas, + 0, + callbackCostJuels, + s_functionsCoordinator.getDONFeeJuels(new bytes(0)), + s_adminFee, + s_functionsCoordinator.getOperationFeeJuels() + ); FunctionsResponse.FulfillResult resultCode = s_functionsCoordinator.fulfillAndBill_HARNESS( s_requests[1].requestId, @@ -377,7 +412,7 @@ contract FunctionsBilling_OracleWithdraw is FunctionsMultipleFulfillmentsSetup { vm.stopPrank(); vm.startPrank(NOP_TRANSMITTER_ADDRESS_1); - uint96 expectedTransmitterBalance = s_fulfillmentCoordinatorBalance / 3; + uint96 expectedTransmitterBalance = s_fulfillmentCoordinatorBalance / s_requestsFulfilled; // Attempt to withdraw half of balance uint96 halfBalance = expectedTransmitterBalance / 2; @@ -394,33 +429,49 @@ contract FunctionsBilling_OracleWithdraw is FunctionsMultipleFulfillmentsSetup { uint256[4] memory transmitterBalancesBefore = _getTransmitterBalances(); _assertTransmittersAllHaveBalance(transmitterBalancesBefore, 0); - // Send as transmitter 1, which has transmitted 1 report + // Send as transmitter 1, which has transmitted 2 reports vm.stopPrank(); vm.startPrank(NOP_TRANSMITTER_ADDRESS_1); // Attempt to withdraw with no amount, which will withdraw the full balance s_functionsCoordinator.oracleWithdraw(NOP_TRANSMITTER_ADDRESS_1, 0); - // 3 report transmissions have been made - uint96 totalDonFees = s_donFee * 3; - // 4 transmitters will share the DON fees - uint96 donFeeShare = totalDonFees / 4; - uint96 expectedTransmitterBalance = ((s_fulfillmentCoordinatorBalance - totalDonFees) / 3) + donFeeShare; + uint96 totalOperationFees = s_functionsCoordinator.getOperationFeeJuels() * s_requestsFulfilled; + uint96 totalDonFees = s_functionsCoordinator.getDONFeeJuels(new bytes(0)) * s_requestsFulfilled; + uint96 donFeeShare = totalDonFees / uint8(s_transmitters.length); + uint96 expectedBalancePerFulfillment = ((s_fulfillmentCoordinatorBalance - totalOperationFees - totalDonFees) / + s_requestsFulfilled); uint256[4] memory transmitterBalancesAfter = _getTransmitterBalances(); - assertEq(transmitterBalancesAfter[0], expectedTransmitterBalance); + // Transmitter 1 has transmitted twice + assertEq(transmitterBalancesAfter[0], (expectedBalancePerFulfillment * 2) + donFeeShare); assertEq(transmitterBalancesAfter[1], 0); assertEq(transmitterBalancesAfter[2], 0); assertEq(transmitterBalancesAfter[3], 0); } + + function test_OracleWithdraw_SuccessCoordinatorOwner() public { + // Send as Coordinator Owner + address coordinatorOwner = s_functionsCoordinator.owner(); + vm.stopPrank(); + vm.startPrank(coordinatorOwner); + + uint256 coordinatorOwnerBalanceBefore = s_linkToken.balanceOf(coordinatorOwner); + + // Attempt to withdraw with no amount, which will withdraw the full balance + s_functionsCoordinator.oracleWithdraw(coordinatorOwner, 0); + + // 4 report transmissions have been made + uint96 totalOperationFees = s_functionsCoordinator.getOperationFeeJuels() * s_requestsFulfilled; + + uint256 coordinatorOwnerBalanceAfter = s_linkToken.balanceOf(coordinatorOwner); + assertEq(coordinatorOwnerBalanceBefore + totalOperationFees, coordinatorOwnerBalanceAfter); + } } /// @notice #oracleWithdrawAll contract FunctionsBilling_OracleWithdrawAll is FunctionsMultipleFulfillmentsSetup { function setUp() public virtual override { - // Use no DON fee so that a transmitter has a balance of 0 - s_donFee = 0; - FunctionsMultipleFulfillmentsSetup.setUp(); } @@ -439,22 +490,28 @@ contract FunctionsBilling_OracleWithdrawAll is FunctionsMultipleFulfillmentsSetu s_functionsCoordinator.oracleWithdrawAll(); - uint96 expectedTransmitterBalance = s_fulfillmentCoordinatorBalance / 3; + uint96 totalOperationFees = s_functionsCoordinator.getOperationFeeJuels() * s_requestsFulfilled; + uint96 totalDonFees = s_functionsCoordinator.getDONFeeJuels(new bytes(0)) * s_requestsFulfilled; + uint96 donFeeShare = totalDonFees / uint8(s_transmitters.length); + uint96 expectedBalancePerFulfillment = ((s_fulfillmentCoordinatorBalance - totalOperationFees - totalDonFees) / + s_requestsFulfilled); uint256[4] memory transmitterBalancesAfter = _getTransmitterBalances(); - assertEq(transmitterBalancesAfter[0], expectedTransmitterBalance); - assertEq(transmitterBalancesAfter[1], expectedTransmitterBalance); - assertEq(transmitterBalancesAfter[2], expectedTransmitterBalance); - // Transmitter 4 has no balance - assertEq(transmitterBalancesAfter[3], 0); + // Transmitter 1 has transmitted twice + assertEq(transmitterBalancesAfter[0], (expectedBalancePerFulfillment * 2) + donFeeShare); + // Transmitter 2 and 3 have transmitted once + assertEq(transmitterBalancesAfter[1], expectedBalancePerFulfillment + donFeeShare); + assertEq(transmitterBalancesAfter[2], expectedBalancePerFulfillment + donFeeShare); + // Transmitter 4 only not transmitted, it only has its share of the DON fees + assertEq(transmitterBalancesAfter[3], donFeeShare); } } /// @notice #_disperseFeePool contract FunctionsBilling__DisperseFeePool is FunctionsRouterSetup { function test__DisperseFeePool_RevertIfNotSet() public { - // Manually set s_feePool (at slot 11) to 1 to get past first check in _disperseFeePool - vm.store(address(s_functionsCoordinator), bytes32(uint256(11)), bytes32(uint256(1))); + // Manually set s_feePool (at slot 12) to 1 to get past first check in _disperseFeePool + vm.store(address(s_functionsCoordinator), bytes32(uint256(12)), bytes32(uint256(1))); vm.expectRevert(FunctionsBilling.NoTransmittersSet.selector); s_functionsCoordinator.disperseFeePool_HARNESS(); diff --git a/contracts/src/v0.8/functions/tests/v1_X/FunctionsCoordinator.t.sol b/contracts/src/v0.8/functions/tests/v1_X/FunctionsCoordinator.t.sol index c21a2c090f7..3944c5873b1 100644 --- a/contracts/src/v0.8/functions/tests/v1_X/FunctionsCoordinator.t.sol +++ b/contracts/src/v0.8/functions/tests/v1_X/FunctionsCoordinator.t.sol @@ -14,7 +14,7 @@ import {FunctionsRouterSetup, FunctionsDONSetup, FunctionsSubscriptionSetup} fro /// @notice #constructor contract FunctionsCoordinator_Constructor is FunctionsRouterSetup { function test_Constructor_Success() public { - assertEq(s_functionsCoordinator.typeAndVersion(), "Functions Coordinator v1.2.0"); + assertEq(s_functionsCoordinator.typeAndVersion(), "Functions Coordinator v1.3.0"); assertEq(s_functionsCoordinator.owner(), OWNER_ADDRESS); } } @@ -189,8 +189,9 @@ contract FunctionsCoordinator_StartRequest is FunctionsSubscriptionSetup { ) ); + // WARNING: Kludge in place. Remove in contracts v2.0.0 FunctionsResponse.Commitment memory expectedComittment = FunctionsResponse.Commitment({ - adminFee: s_adminFee, + adminFee: s_functionsCoordinator.getOperationFeeJuels(), coordinator: address(s_functionsCoordinator), client: address(s_functionsClient), subscriptionId: s_subscriptionId, @@ -198,7 +199,7 @@ contract FunctionsCoordinator_StartRequest is FunctionsSubscriptionSetup { estimatedTotalCostJuels: costEstimate, timeoutTimestamp: timeoutTimestamp, requestId: expectedRequestId, - donFee: s_donFee, + donFee: s_functionsCoordinator.getDONFeeJuels(_requestData), gasOverheadBeforeCallback: getCoordinatorConfig().gasOverheadBeforeCallback, gasOverheadAfterCallback: getCoordinatorConfig().gasOverheadAfterCallback }); diff --git a/contracts/src/v0.8/functions/tests/v1_X/FunctionsRouter.t.sol b/contracts/src/v0.8/functions/tests/v1_X/FunctionsRouter.t.sol index 43540ba02b8..62db3e467d6 100644 --- a/contracts/src/v0.8/functions/tests/v1_X/FunctionsRouter.t.sol +++ b/contracts/src/v0.8/functions/tests/v1_X/FunctionsRouter.t.sol @@ -518,7 +518,8 @@ contract FunctionsRouter_SendRequestToProposed is FunctionsSubscriptionSetup { s_functionsCoordinator2 = new FunctionsCoordinatorTestHelper( address(s_functionsRouter), getCoordinatorConfig(), - address(s_linkEthFeed) + address(s_linkEthFeed), + address(s_linkUsdFeed) ); // Propose new Coordinator contract @@ -1085,7 +1086,20 @@ contract FunctionsRouter_Fulfill is FunctionsClientRequestSetup { callbackGasLimit: callbackGasLimit }), requestId: requestId, - commitment: _commitment + commitment: _commitment, // This commitment contains the operationFee in place of adminFee + commitmentOnchain: FunctionsResponse.Commitment({ + coordinator: _commitment.coordinator, + client: _commitment.client, + subscriptionId: _commitment.subscriptionId, + callbackGasLimit: _commitment.callbackGasLimit, + estimatedTotalCostJuels: _commitment.estimatedTotalCostJuels, + timeoutTimestamp: _commitment.timeoutTimestamp, + requestId: _commitment.requestId, + donFee: _commitment.donFee, + gasOverheadBeforeCallback: _commitment.gasOverheadBeforeCallback, + gasOverheadAfterCallback: _commitment.gasOverheadAfterCallback, + adminFee: s_adminFee + }) }); // Fulfill @@ -1271,7 +1285,8 @@ contract FunctionsRouter_GetProposedContractById is FunctionsRoutesSetup { s_functionsCoordinator2 = new FunctionsCoordinatorTestHelper( address(s_functionsRouter), getCoordinatorConfig(), - address(s_linkEthFeed) + address(s_linkEthFeed), + address(s_linkUsdFeed) ); // Propose new Coordinator contract @@ -1317,7 +1332,8 @@ contract FunctionsRouter_GetProposedContractSet is FunctionsRoutesSetup { s_functionsCoordinator2 = new FunctionsCoordinatorTestHelper( address(s_functionsRouter), getCoordinatorConfig(), - address(s_linkEthFeed) + address(s_linkEthFeed), + address(s_linkUsdFeed) ); // Propose new Coordinator contract @@ -1357,7 +1373,8 @@ contract FunctionsRouter_ProposeContractsUpdate is FunctionsRoutesSetup { s_functionsCoordinator2 = new FunctionsCoordinatorTestHelper( address(s_functionsRouter), getCoordinatorConfig(), - address(s_linkEthFeed) + address(s_linkEthFeed), + address(s_linkUsdFeed) ); // Propose new Coordinator contract @@ -1459,7 +1476,8 @@ contract FunctionsRouter_UpdateContracts is FunctionsRoutesSetup { s_functionsCoordinator2 = new FunctionsCoordinatorTestHelper( address(s_functionsRouter), getCoordinatorConfig(), - address(s_linkEthFeed) + address(s_linkEthFeed), + address(s_linkUsdFeed) ); // Propose new Coordinator contract diff --git a/contracts/src/v0.8/functions/tests/v1_X/FunctionsSubscriptions.t.sol b/contracts/src/v0.8/functions/tests/v1_X/FunctionsSubscriptions.t.sol index d036b5354ef..a6dda5a94df 100644 --- a/contracts/src/v0.8/functions/tests/v1_X/FunctionsSubscriptions.t.sol +++ b/contracts/src/v0.8/functions/tests/v1_X/FunctionsSubscriptions.t.sol @@ -1233,15 +1233,15 @@ contract FunctionsSubscriptions_TimeoutRequests is FunctionsClientRequestSetup { vm.expectRevert("Pausable: paused"); FunctionsResponse.Commitment[] memory commitments = new FunctionsResponse.Commitment[](1); - commitments[0] = s_requests[1].commitment; + commitments[0] = s_requests[1].commitmentOnchain; s_functionsRouter.timeoutRequests(commitments); } function test_TimeoutRequests_RevertInvalidRequest() public { // Modify the commitment so that it doesn't match - s_requests[1].commitment.donFee = 123456789; + s_requests[1].commitmentOnchain.donFee = 123456789; FunctionsResponse.Commitment[] memory commitments = new FunctionsResponse.Commitment[](1); - commitments[0] = s_requests[1].commitment; + commitments[0] = s_requests[1].commitmentOnchain; vm.expectRevert(FunctionsSubscriptions.InvalidCalldata.selector); s_functionsRouter.timeoutRequests(commitments); } @@ -1249,7 +1249,7 @@ contract FunctionsSubscriptions_TimeoutRequests is FunctionsClientRequestSetup { function test_TimeoutRequests_RevertIfTimeoutNotExceeded() public { vm.expectRevert(FunctionsSubscriptions.TimeoutNotExceeded.selector); FunctionsResponse.Commitment[] memory commitments = new FunctionsResponse.Commitment[](1); - commitments[0] = s_requests[1].commitment; + commitments[0] = s_requests[1].commitmentOnchain; s_functionsRouter.timeoutRequests(commitments); } @@ -1269,10 +1269,10 @@ contract FunctionsSubscriptions_TimeoutRequests is FunctionsClientRequestSetup { emit RequestTimedOut(s_requests[1].requestId); // Jump ahead in time past timeout timestamp - vm.warp(s_requests[1].commitment.timeoutTimestamp + 1); + vm.warp(s_requests[1].commitmentOnchain.timeoutTimestamp + 1); FunctionsResponse.Commitment[] memory commitments = new FunctionsResponse.Commitment[](1); - commitments[0] = s_requests[1].commitment; + commitments[0] = s_requests[1].commitmentOnchain; s_functionsRouter.timeoutRequests(commitments); // Releases blocked balance and increments completed requests diff --git a/contracts/src/v0.8/functions/tests/v1_X/Setup.t.sol b/contracts/src/v0.8/functions/tests/v1_X/Setup.t.sol index 296e61c040c..32dc53e42ab 100644 --- a/contracts/src/v0.8/functions/tests/v1_X/Setup.t.sol +++ b/contracts/src/v0.8/functions/tests/v1_X/Setup.t.sol @@ -20,17 +20,22 @@ contract FunctionsRouterSetup is BaseTest { FunctionsRouterHarness internal s_functionsRouter; FunctionsCoordinatorHarness internal s_functionsCoordinator; MockV3Aggregator internal s_linkEthFeed; + MockV3Aggregator internal s_linkUsdFeed; TermsOfServiceAllowList internal s_termsOfServiceAllowList; MockLinkToken internal s_linkToken; uint16 internal s_maxConsumersPerSubscription = 3; - uint72 internal s_adminFee = 100; - uint72 internal s_donFee = 100; + uint72 internal s_adminFee = 0; // Keep as 0. Setting this to anything else will cause fulfillments to fail with INVALID_COMMITMENT + uint16 internal s_donFee = 100; // $1 + uint16 internal s_operationFee = 100; // $1 bytes4 internal s_handleOracleFulfillmentSelector = 0x0ca76175; uint16 s_subscriptionDepositMinimumRequests = 1; uint72 s_subscriptionDepositJuels = 11 * JUELS_PER_LINK; - int256 internal LINK_ETH_RATE = 6000000000000000; + int256 internal LINK_ETH_RATE = 6_000_000_000_000_000; + uint8 internal LINK_ETH_DECIMALS = 18; + int256 internal LINK_USD_RATE = 1_500_000_000; + uint8 internal LINK_USD_DECIMALS = 8; uint256 internal TOS_SIGNER_PRIVATE_KEY = 0x3; address internal TOS_SIGNER = vm.addr(TOS_SIGNER_PRIVATE_KEY); @@ -39,11 +44,13 @@ contract FunctionsRouterSetup is BaseTest { BaseTest.setUp(); s_linkToken = new MockLinkToken(); s_functionsRouter = new FunctionsRouterHarness(address(s_linkToken), getRouterConfig()); - s_linkEthFeed = new MockV3Aggregator(0, LINK_ETH_RATE); + s_linkEthFeed = new MockV3Aggregator(LINK_ETH_DECIMALS, LINK_ETH_RATE); + s_linkUsdFeed = new MockV3Aggregator(LINK_USD_DECIMALS, LINK_USD_RATE); s_functionsCoordinator = new FunctionsCoordinatorHarness( address(s_functionsRouter), getCoordinatorConfig(), - address(s_linkEthFeed) + address(s_linkEthFeed), + address(s_linkUsdFeed) ); address[] memory initialAllowedSenders; address[] memory initialBlockedSenders; @@ -79,10 +86,13 @@ contract FunctionsRouterSetup is BaseTest { gasOverheadAfterCallback: 93_942, gasOverheadBeforeCallback: 105_000, requestTimeoutSeconds: 60 * 5, // 5 minutes - donFee: s_donFee, + donFeeCentsUsd: s_donFee, + operationFeeCentsUsd: s_operationFee, maxSupportedRequestDataVersion: 1, fulfillmentGasPriceOverEstimationBP: 5000, fallbackNativePerUnitLink: 5000000000000000, + fallbackUsdPerUnitLink: 1400000000, + fallbackUsdPerUnitLinkDecimals: 8, minimumEstimateGasPriceWei: 1000000000 // 1 gwei }); } @@ -94,22 +104,22 @@ contract FunctionsRouterSetup is BaseTest { /// @notice Set up to set the OCR configuration of the Coordinator contract contract FunctionsDONSetup is FunctionsRouterSetup { - uint256 internal NOP_SIGNER_PRIVATE_KEY_1 = 0x100; + uint256 internal NOP_SIGNER_PRIVATE_KEY_1 = 0x400; address internal NOP_SIGNER_ADDRESS_1 = vm.addr(NOP_SIGNER_PRIVATE_KEY_1); - uint256 internal NOP_SIGNER_PRIVATE_KEY_2 = 0x101; + uint256 internal NOP_SIGNER_PRIVATE_KEY_2 = 0x401; address internal NOP_SIGNER_ADDRESS_2 = vm.addr(NOP_SIGNER_PRIVATE_KEY_2); - uint256 internal NOP_SIGNER_PRIVATE_KEY_3 = 0x102; + uint256 internal NOP_SIGNER_PRIVATE_KEY_3 = 0x402; address internal NOP_SIGNER_ADDRESS_3 = vm.addr(NOP_SIGNER_PRIVATE_KEY_3); - uint256 internal NOP_SIGNER_PRIVATE_KEY_4 = 0x103; + uint256 internal NOP_SIGNER_PRIVATE_KEY_4 = 0x403; address internal NOP_SIGNER_ADDRESS_4 = vm.addr(NOP_SIGNER_PRIVATE_KEY_4); - uint256 internal NOP_TRANSMITTER_PRIVATE_KEY_1 = 0x104; + uint256 internal NOP_TRANSMITTER_PRIVATE_KEY_1 = 0x404; address internal NOP_TRANSMITTER_ADDRESS_1 = vm.addr(NOP_TRANSMITTER_PRIVATE_KEY_1); - uint256 internal NOP_TRANSMITTER_PRIVATE_KEY_2 = 0x105; + uint256 internal NOP_TRANSMITTER_PRIVATE_KEY_2 = 0x405; address internal NOP_TRANSMITTER_ADDRESS_2 = vm.addr(NOP_TRANSMITTER_PRIVATE_KEY_2); - uint256 internal NOP_TRANSMITTER_PRIVATE_KEY_3 = 0x106; + uint256 internal NOP_TRANSMITTER_PRIVATE_KEY_3 = 0x406; address internal NOP_TRANSMITTER_ADDRESS_3 = vm.addr(NOP_TRANSMITTER_PRIVATE_KEY_3); - uint256 internal NOP_TRANSMITTER_PRIVATE_KEY_4 = 0x107; + uint256 internal NOP_TRANSMITTER_PRIVATE_KEY_4 = 0x407; address internal NOP_TRANSMITTER_ADDRESS_4 = vm.addr(NOP_TRANSMITTER_PRIVATE_KEY_4); address[] internal s_signers; @@ -251,7 +261,8 @@ contract FunctionsClientRequestSetup is FunctionsSubscriptionSetup { struct Request { RequestData requestData; bytes32 requestId; - FunctionsResponse.Commitment commitment; + FunctionsResponse.Commitment commitment; // Offchain commitment that contains operation fee in the place of admin fee + FunctionsResponse.Commitment commitmentOnchain; // Commitment that is persisted as a hash in the Router } mapping(uint256 requestNumber => Request) s_requests; @@ -264,6 +275,8 @@ contract FunctionsClientRequestSetup is FunctionsSubscriptionSetup { uint96 s_fulfillmentRouterOwnerBalance = 0; uint96 s_fulfillmentCoordinatorBalance = 0; + uint8 s_requestsSent = 0; + uint8 s_requestsFulfilled = 0; function setUp() public virtual override { FunctionsSubscriptionSetup.setUp(); @@ -289,7 +302,13 @@ contract FunctionsClientRequestSetup is FunctionsSubscriptionSetup { uint96 gasOverheadJuels = juelsPerGas * ((getCoordinatorConfig().gasOverheadBeforeCallback + getCoordinatorConfig().gasOverheadAfterCallback)); uint96 callbackGasCostJuels = uint96(juelsPerGas * callbackGas); - return gasOverheadJuels + s_donFee + s_adminFee + callbackGasCostJuels; + bytes memory emptyData = new bytes(0); + return + gasOverheadJuels + + s_functionsCoordinator.getDONFeeJuels(emptyData) + + s_adminFee + + s_functionsCoordinator.getOperationFeeJuels() + + callbackGasCostJuels; } /// @notice Predicts the actual cost of a request @@ -299,7 +318,13 @@ contract FunctionsClientRequestSetup is FunctionsSubscriptionSetup { uint96 gasOverheadJuels = juelsPerGas * (getCoordinatorConfig().gasOverheadBeforeCallback + getCoordinatorConfig().gasOverheadAfterCallback); uint96 callbackGasCostJuels = uint96(juelsPerGas * gasUsed); - return gasOverheadJuels + s_donFee + s_adminFee + callbackGasCostJuels; + bytes memory emptyData = new bytes(0); + return + gasOverheadJuels + + s_functionsCoordinator.getDONFeeJuels(emptyData) + + s_adminFee + + s_functionsCoordinator.getOperationFeeJuels() + + callbackGasCostJuels; } /// @notice Send a request and store information about it in s_requests @@ -350,8 +375,22 @@ contract FunctionsClientRequestSetup is FunctionsSubscriptionSetup { callbackGasLimit: callbackGasLimit }), requestId: requestId, - commitment: commitment + commitment: commitment, // Has operationFee in place of adminFee + commitmentOnchain: FunctionsResponse.Commitment({ + coordinator: commitment.coordinator, + client: commitment.client, + subscriptionId: commitment.subscriptionId, + callbackGasLimit: commitment.callbackGasLimit, + estimatedTotalCostJuels: commitment.estimatedTotalCostJuels, + timeoutTimestamp: commitment.timeoutTimestamp, + requestId: commitment.requestId, + donFee: commitment.donFee, + gasOverheadBeforeCallback: commitment.gasOverheadBeforeCallback, + gasOverheadAfterCallback: commitment.gasOverheadAfterCallback, + adminFee: s_adminFee + }) }); + s_requestsSent += 1; } /// @notice Send a request and store information about it in s_requests @@ -505,7 +544,7 @@ contract FunctionsClientRequestSetup is FunctionsSubscriptionSetup { // Send as transmitter vm.stopPrank(); - vm.startPrank(transmitter); + vm.startPrank(transmitter, transmitter); // Send report vm.recordLogs(); @@ -530,6 +569,7 @@ contract FunctionsClientRequestSetup is FunctionsSubscriptionSetup { // TODO: handle multiple requests s_fulfillmentCoordinatorBalance += totalCostJuels - s_adminFee; } + s_requestsFulfilled += 1; // Return prank to Owner vm.stopPrank(); @@ -632,7 +672,7 @@ contract FunctionsMultipleFulfillmentsSetup is FunctionsFulfillmentSetup { function setUp() public virtual override { FunctionsFulfillmentSetup.setUp(); - // Make 2 additional requests (1 already complete) + // Make 3 additional requests (1 already complete) // *** Request #2 *** // Send @@ -662,5 +702,17 @@ contract FunctionsMultipleFulfillmentsSetup is FunctionsFulfillmentSetup { bytes[] memory errors2 = new bytes[](1); errors2[0] = new bytes(0); _reportAndStore(requestNumberKeys2, results2, errors2, NOP_TRANSMITTER_ADDRESS_3, true); + + // *** Request #4 *** + // Send + _sendAndStoreRequest(4, sourceCode, secrets, args, bytesArgs, callbackGasLimit); + // Fulfill as transmitter #1 + uint256[] memory requestNumberKeys3 = new uint256[](1); + requestNumberKeys3[0] = 4; + string[] memory results3 = new string[](1); + results3[0] = "hello world!"; + bytes[] memory errors3 = new bytes[](1); + errors3[0] = new bytes(0); + _reportAndStore(requestNumberKeys3, results3, errors3, NOP_TRANSMITTER_ADDRESS_1, true); } } diff --git a/contracts/src/v0.8/functions/tests/v1_X/testhelpers/FunctionsCoordinatorHarness.sol b/contracts/src/v0.8/functions/tests/v1_X/testhelpers/FunctionsCoordinatorHarness.sol index e4e9f7279a7..0de449f3a0e 100644 --- a/contracts/src/v0.8/functions/tests/v1_X/testhelpers/FunctionsCoordinatorHarness.sol +++ b/contracts/src/v0.8/functions/tests/v1_X/testhelpers/FunctionsCoordinatorHarness.sol @@ -10,14 +10,17 @@ import {FunctionsBillingConfig} from "../../../dev/v1_X/interfaces/IFunctionsBil /// @notice Contract to expose internal functions for testing purposes contract FunctionsCoordinatorHarness is FunctionsCoordinator { address s_linkToNativeFeed_HARNESS; + address s_linkToUsdFeed_HARNESS; address s_router_HARNESS; constructor( address router, FunctionsBillingConfig memory config, - address linkToNativeFeed - ) FunctionsCoordinator(router, config, linkToNativeFeed) { + address linkToNativeFeed, + address linkToUsdFeed + ) FunctionsCoordinator(router, config, linkToNativeFeed, linkToUsdFeed) { s_linkToNativeFeed_HARNESS = linkToNativeFeed; + s_linkToUsdFeed_HARNESS = linkToUsdFeed; s_router_HARNESS = router; } @@ -50,6 +53,10 @@ contract FunctionsCoordinatorHarness is FunctionsCoordinator { return s_linkToNativeFeed_HARNESS; } + function getLinkToUsdFeed_HARNESS() external view returns (address) { + return s_linkToUsdFeed_HARNESS; + } + function getRouter_HARNESS() external view returns (address) { return s_router_HARNESS; } @@ -58,14 +65,15 @@ contract FunctionsCoordinatorHarness is FunctionsCoordinator { uint32 callbackGasLimit, uint256 gasPriceWei, uint72 donFee, - uint72 adminFee + uint72 adminFee, + uint72 operationFee ) external view returns (uint96) { - return super._calculateCostEstimate(callbackGasLimit, gasPriceWei, donFee, adminFee); + return super._calculateCostEstimate(callbackGasLimit, gasPriceWei, donFee, adminFee, operationFee); } function startBilling_HARNESS( FunctionsResponse.RequestMeta memory request - ) external returns (FunctionsResponse.Commitment memory commitment) { + ) external returns (FunctionsResponse.Commitment memory commitment, uint72 operationFee) { return super._startBilling(request); } @@ -84,6 +92,10 @@ contract FunctionsCoordinatorHarness is FunctionsCoordinator { return super._disperseFeePool(); } + function owner_HARNESS() external view returns (address owner) { + return super._owner(); + } + // ================================================================ // | OCR2 | // ================================================================ diff --git a/contracts/src/v0.8/functions/tests/v1_X/testhelpers/FunctionsCoordinatorTestHelper.sol b/contracts/src/v0.8/functions/tests/v1_X/testhelpers/FunctionsCoordinatorTestHelper.sol index abfec4c2de5..8703d2b254e 100644 --- a/contracts/src/v0.8/functions/tests/v1_X/testhelpers/FunctionsCoordinatorTestHelper.sol +++ b/contracts/src/v0.8/functions/tests/v1_X/testhelpers/FunctionsCoordinatorTestHelper.sol @@ -9,8 +9,9 @@ contract FunctionsCoordinatorTestHelper is FunctionsCoordinator { constructor( address router, FunctionsBillingConfig memory config, - address linkToNativeFeed - ) FunctionsCoordinator(router, config, linkToNativeFeed) {} + address linkToNativeFeed, + address linkToUsdFeed + ) FunctionsCoordinator(router, config, linkToNativeFeed, linkToUsdFeed) {} function callReport(bytes calldata report) external { address[MAX_NUM_ORACLES] memory signers; @@ -54,23 +55,4 @@ contract FunctionsCoordinatorTestHelper is FunctionsCoordinator { }) ); } - - function callReportWithSigners(bytes calldata report, address[MAX_NUM_ORACLES] memory /* signers */) external { - ( - bytes32[] memory requestIds, - bytes[] memory results, - bytes[] memory errors, - bytes[] memory onchainMetadata, - bytes[] memory offchainMetadata - ) = abi.decode(report, (bytes32[], bytes[], bytes[], bytes[], bytes[])); - _report( - DecodedReport({ - requestIds: requestIds, - results: results, - errors: errors, - onchainMetadata: onchainMetadata, - offchainMetadata: offchainMetadata - }) - ); - } } diff --git a/contracts/test/v0.8/functions/v1/RouterBase.test.ts b/contracts/test/v0.8/functions/v1/RouterBase.test.ts index 3a3b58b8f6b..92f9c7d320b 100644 --- a/contracts/test/v0.8/functions/v1/RouterBase.test.ts +++ b/contracts/test/v0.8/functions/v1/RouterBase.test.ts @@ -31,6 +31,7 @@ describe('FunctionsRouter - Base', () => { contracts.router.address, coordinatorConfig, contracts.mockLinkEth.address, + contracts.mockLinkUsd.address, ) const coordinator3 = await factories.functionsCoordinatorFactory .connect(roles.defaultAccount) @@ -38,6 +39,7 @@ describe('FunctionsRouter - Base', () => { contracts.router.address, coordinatorConfig, contracts.mockLinkEth.address, + contracts.mockLinkUsd.address, ) const coordinator4 = await factories.functionsCoordinatorFactory .connect(roles.defaultAccount) @@ -45,6 +47,7 @@ describe('FunctionsRouter - Base', () => { contracts.router.address, coordinatorConfig, contracts.mockLinkEth.address, + contracts.mockLinkUsd.address, ) await expect( diff --git a/contracts/test/v0.8/functions/v1/utils.ts b/contracts/test/v0.8/functions/v1/utils.ts index ffe5468f136..dd3853c2d9d 100644 --- a/contracts/test/v0.8/functions/v1/utils.ts +++ b/contracts/test/v0.8/functions/v1/utils.ts @@ -26,6 +26,7 @@ export type FunctionsContracts = { client: Contract linkToken: Contract mockLinkEth: Contract + mockLinkUsd: Contract accessControl: Contract } @@ -94,11 +95,14 @@ export type CoordinatorConfig = { gasOverheadBeforeCallback: number gasOverheadAfterCallback: number requestTimeoutSeconds: number - donFee: number + donFeeCentsUsd: number maxSupportedRequestDataVersion: number fulfillmentGasPriceOverEstimationBP: number fallbackNativePerUnitLink: BigNumber minimumEstimateGasPriceWei: number + operationFeeCentsUsd: number + fallbackUsdPerUnitLink: number + fallbackUsdPerUnitLinkDecimals: number } const fallbackNativePerUnitLink = 5000000000000000 export const coordinatorConfig: CoordinatorConfig = { @@ -106,12 +110,18 @@ export const coordinatorConfig: CoordinatorConfig = { gasOverheadBeforeCallback: 44_615, gasOverheadAfterCallback: 44_615, requestTimeoutSeconds: 300, - donFee: 0, + donFeeCentsUsd: 0, maxSupportedRequestDataVersion: 1, fulfillmentGasPriceOverEstimationBP: 0, fallbackNativePerUnitLink: BigNumber.from(fallbackNativePerUnitLink), minimumEstimateGasPriceWei: 1000000000, + operationFeeCentsUsd: 0, + fallbackUsdPerUnitLink: 1500000000, + fallbackUsdPerUnitLinkDecimals: 8, } +const linkEthRate = '5021530000000000' +const linkUsdRate = '1500000000' + export const accessControlMockPublicKey = ethers.utils.getAddress( '0x32237412cC0321f56422d206e505dB4B3871AF5c', ) @@ -237,8 +247,6 @@ export function getSetupFactory(): () => { }) beforeEach(async () => { - const linkEthRate = BigNumber.from(5021530000000000) - // Deploy const linkToken = await factories.linkTokenFactory .connect(roles.defaultAccount) @@ -246,7 +254,12 @@ export function getSetupFactory(): () => { const mockLinkEth = await factories.mockAggregatorV3Factory.deploy( 0, - linkEthRate, + BigNumber.from(linkEthRate), + ) + + const mockLinkUsd = await factories.mockAggregatorV3Factory.deploy( + 0, + BigNumber.from(linkUsdRate), ) const router = await factories.functionsRouterFactory @@ -255,7 +268,12 @@ export function getSetupFactory(): () => { const coordinator = await factories.functionsCoordinatorFactory .connect(roles.defaultAccount) - .deploy(router.address, coordinatorConfig, mockLinkEth.address) + .deploy( + router.address, + coordinatorConfig, + mockLinkEth.address, + mockLinkUsd.address, + ) const initialAllowedSenders: string[] = [] const initialBlockedSenders: string[] = [] @@ -290,6 +308,7 @@ export function getSetupFactory(): () => { router, linkToken, mockLinkEth, + mockLinkUsd, accessControl, } }) diff --git a/core/gethwrappers/functions/generated/functions_coordinator/functions_coordinator.go b/core/gethwrappers/functions/generated/functions_coordinator/functions_coordinator.go index 07b1b5e1720..6099c541c69 100644 --- a/core/gethwrappers/functions/generated/functions_coordinator/functions_coordinator.go +++ b/core/gethwrappers/functions/generated/functions_coordinator/functions_coordinator.go @@ -35,11 +35,14 @@ type FunctionsBillingConfig struct { FeedStalenessSeconds uint32 GasOverheadBeforeCallback uint32 GasOverheadAfterCallback uint32 - DonFee *big.Int MinimumEstimateGasPriceWei *big.Int MaxSupportedRequestDataVersion uint16 + FallbackUsdPerUnitLink uint64 + FallbackUsdPerUnitLinkDecimals uint8 FallbackNativePerUnitLink *big.Int RequestTimeoutSeconds uint32 + DonFeeCentsUsd uint16 + OperationFeeCentsUsd uint16 } type FunctionsResponseCommitment struct { @@ -71,15 +74,15 @@ type FunctionsResponseRequestMeta struct { } var FunctionsCoordinatorMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"fulfillmentGasPriceOverEstimationBP\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"feedStalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint40\",\"name\":\"minimumEstimateGasPriceWei\",\"type\":\"uint40\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint224\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"}],\"internalType\":\"structFunctionsBillingConfig\",\"name\":\"config\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"linkToNativeFeed\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"EmptyPublicKey\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InconsistentReportData\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCalldata\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"linkWei\",\"type\":\"int256\"}],\"name\":\"InvalidLinkWeiPrice\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSubscription\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"MustBeSubOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoTransmittersSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByRouterOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"ReportInvalid\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RouterMustBeSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedPublicKeyChange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSender\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnsupportedRequestDataVersion\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"CommitmentDeleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"fulfillmentGasPriceOverEstimationBP\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"feedStalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint40\",\"name\":\"minimumEstimateGasPriceWei\",\"type\":\"uint40\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint224\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"}],\"indexed\":false,\"internalType\":\"structFunctionsBillingConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"requestingContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requestInitiator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"subscriptionOwner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"flags\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"callbackGasLimit\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"estimatedTotalCostJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint40\"},{\"internalType\":\"uint32\",\"name\":\"timeoutTimestamp\",\"type\":\"uint32\"}],\"indexed\":false,\"internalType\":\"structFunctionsResponse.Commitment\",\"name\":\"commitment\",\"type\":\"tuple\"}],\"name\":\"OracleRequest\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"}],\"name\":\"OracleResponse\",\"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\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"juelsPerGas\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"l1FeeShareWei\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"callbackCostJuels\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalCostJuels\",\"type\":\"uint96\"}],\"name\":\"RequestBilled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"deleteCommitment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"gasPriceWei\",\"type\":\"uint256\"}],\"name\":\"estimateCost\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAdminFee\",\"outputs\":[{\"internalType\":\"uint72\",\"name\":\"\",\"type\":\"uint72\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"fulfillmentGasPriceOverEstimationBP\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"feedStalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint40\",\"name\":\"minimumEstimateGasPriceWei\",\"type\":\"uint40\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint224\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"}],\"internalType\":\"structFunctionsBillingConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"getDONFee\",\"outputs\":[{\"internalType\":\"uint72\",\"name\":\"\",\"type\":\"uint72\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDONPublicKey\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getThresholdPublicKey\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getWeiPerUnitLink\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"oracleWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"oracleWithdrawAll\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"_transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"_f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"_onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"_offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"_offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"donPublicKey\",\"type\":\"bytes\"}],\"name\":\"setDONPublicKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"thresholdPublicKey\",\"type\":\"bytes\"}],\"name\":\"setThresholdPublicKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes32\",\"name\":\"flags\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"requestingContract\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"availableBalance\",\"type\":\"uint96\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"initiatedRequests\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint64\",\"name\":\"completedRequests\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"subscriptionOwner\",\"type\":\"address\"}],\"internalType\":\"structFunctionsResponse.RequestMeta\",\"name\":\"request\",\"type\":\"tuple\"}],\"name\":\"startRequest\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"estimatedTotalCostJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint40\"},{\"internalType\":\"uint32\",\"name\":\"timeoutTimestamp\",\"type\":\"uint32\"}],\"internalType\":\"structFunctionsResponse.Commitment\",\"name\":\"commitment\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"transmitters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"fulfillmentGasPriceOverEstimationBP\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"feedStalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint40\",\"name\":\"minimumEstimateGasPriceWei\",\"type\":\"uint40\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint224\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"}],\"internalType\":\"structFunctionsBillingConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"updateConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60a06040523480156200001157600080fd5b50604051620057a9380380620057a983398101604081905262000034916200046d565b8282828233806000816200008f5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c257620000c28162000139565b5050506001600160a01b038116620000ed57604051632530e88560e11b815260040160405180910390fd5b6001600160a01b03908116608052600b80549183166c01000000000000000000000000026001600160601b039092169190911790556200012d82620001e4565b5050505050506200062c565b336001600160a01b03821603620001935760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000086565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b620001ee62000342565b80516008805460208401516040808601516060870151608088015160a089015160c08a015161ffff16600160f01b026001600160f01b0364ffffffffff909216600160c81b0264ffffffffff60c81b196001600160481b03909416600160801b0293909316600160801b600160f01b031963ffffffff9586166c010000000000000000000000000263ffffffff60601b19978716680100000000000000000297909716600160401b600160801b0319998716640100000000026001600160401b0319909b169c87169c909c1799909917979097169990991793909317959095169390931793909317929092169390931790915560e0830151610100840151909216600160e01b026001600160e01b0390921691909117600955517f5f32d06f5e83eda3a68e0e964ef2e6af5cb613e8117aa103c2d6bca5f5184862906200033790839062000576565b60405180910390a150565b6200034c6200034e565b565b6000546001600160a01b031633146200034c5760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000086565b80516001600160a01b0381168114620003c257600080fd5b919050565b60405161012081016001600160401b0381118282101715620003f957634e487b7160e01b600052604160045260246000fd5b60405290565b805163ffffffff81168114620003c257600080fd5b80516001600160481b0381168114620003c257600080fd5b805164ffffffffff81168114620003c257600080fd5b805161ffff81168114620003c257600080fd5b80516001600160e01b0381168114620003c257600080fd5b60008060008385036101608112156200048557600080fd5b6200049085620003aa565b935061012080601f1983011215620004a757600080fd5b620004b1620003c7565b9150620004c160208701620003ff565b8252620004d160408701620003ff565b6020830152620004e460608701620003ff565b6040830152620004f760808701620003ff565b60608301526200050a60a0870162000414565b60808301526200051d60c087016200042c565b60a08301526200053060e0870162000442565b60c08301526101006200054581880162000455565b60e084015262000557828801620003ff565b908301525091506200056d6101408501620003aa565b90509250925092565b815163ffffffff908116825260208084015182169083015260408084015182169083015260608084015191821690830152610120820190506080830151620005c960808401826001600160481b03169052565b5060a0830151620005e360a084018264ffffffffff169052565b5060c0830151620005fa60c084018261ffff169052565b5060e08301516200061660e08401826001600160e01b03169052565b506101009283015163ffffffff16919092015290565b6080516151376200067260003960008181610845015281816109d301528181610ca601528181610f3a0152818161104501528181611790015261357001526151376000f3fe608060405234801561001057600080fd5b506004361061018d5760003560e01c806381ff7048116100e3578063c3f909d41161008c578063e3d0e71211610066578063e3d0e71214610560578063e4ddcea614610573578063f2fde38b1461058957600080fd5b8063c3f909d4146103b0578063d227d24514610528578063d328a91e1461055857600080fd5b8063a631571e116100bd578063a631571e1461035d578063afcb95d71461037d578063b1dc65a41461039d57600080fd5b806381ff7048146102b557806385b214cf146103225780638da5cb5b1461033557600080fd5b806366316d8d116101455780637f15e1661161011f5780637f15e16614610285578063814118341461029857806381f1b938146102ad57600080fd5b806366316d8d1461026257806379ba5097146102755780637d4807871461027d57600080fd5b8063181f5a7711610176578063181f5a77146101ba5780632a905ccc1461020c57806359b5b7ac1461022e57600080fd5b8063083a5466146101925780631112dadc146101a7575b600080fd5b6101a56101a0366004613aad565b61059c565b005b6101a56101b5366004613c56565b6105f1565b6101f66040518060400160405280601c81526020017f46756e6374696f6e7320436f6f7264696e61746f722076312e322e300000000081525081565b6040516102039190613d7a565b60405180910390f35b610214610841565b60405168ffffffffffffffffff9091168152602001610203565b61021461023c366004613e1b565b50600854700100000000000000000000000000000000900468ffffffffffffffffff1690565b6101a5610270366004613eaa565b6108d7565b6101a5610a90565b6101a5610b92565b6101a5610293366004613aad565b610d92565b6102a0610de2565b6040516102039190613f34565b6101f6610e51565b6102ff60015460025463ffffffff74010000000000000000000000000000000000000000830481169378010000000000000000000000000000000000000000000000009093041691565b6040805163ffffffff948516815293909216602084015290820152606001610203565b6101a5610330366004613f47565b610f22565b60005460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610203565b61037061036b366004613f60565b610fd4565b60405161020391906140b5565b604080516001815260006020820181905291810191909152606001610203565b6101a56103ab366004614109565b611175565b61051b6040805161012081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081019190915250604080516101208101825260085463ffffffff80821683526401000000008204811660208401526801000000000000000082048116938301939093526c01000000000000000000000000810483166060830152700100000000000000000000000000000000810468ffffffffffffffffff166080830152790100000000000000000000000000000000000000000000000000810464ffffffffff1660a08301527e01000000000000000000000000000000000000000000000000000000000000900461ffff1660c08201526009547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811660e08301527c0100000000000000000000000000000000000000000000000000000000900490911661010082015290565b60405161020391906141c0565b61053b6105363660046142b0565b61178c565b6040516bffffffffffffffffffffffff9091168152602001610203565b6101f66118ec565b6101a561056e3660046143c9565b611943565b61057b6124bf565b604051908152602001610203565b6101a5610597366004614496565b612718565b6105a461272c565b60008190036105df576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600d6105ec82848361454c565b505050565b6105f96127af565b80516008805460208401516040808601516060870151608088015160a089015160c08a015161ffff167e01000000000000000000000000000000000000000000000000000000000000027dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff64ffffffffff909216790100000000000000000000000000000000000000000000000000027fffff0000000000ffffffffffffffffffffffffffffffffffffffffffffffffff68ffffffffffffffffff90941670010000000000000000000000000000000002939093167fffff0000000000000000000000000000ffffffffffffffffffffffffffffffff63ffffffff9586166c01000000000000000000000000027fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff9787166801000000000000000002979097167fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff998716640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909b169c87169c909c1799909917979097169990991793909317959095169390931793909317929092169390931790915560e08301516101008401519092167c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff90921691909117600955517f5f32d06f5e83eda3a68e0e964ef2e6af5cb613e8117aa103c2d6bca5f5184862906108369083906141c0565b60405180910390a150565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632a905ccc6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108d29190614672565b905090565b6108df6127b7565b806bffffffffffffffffffffffff166000036109195750336000908152600a60205260409020546bffffffffffffffffffffffff16610973565b336000908152600a60205260409020546bffffffffffffffffffffffff80831691161015610973576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600a6020526040812080548392906109a09084906bffffffffffffffffffffffff166146be565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055506109f57f000000000000000000000000000000000000000000000000000000000000000090565b6040517f66316d8d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301526bffffffffffffffffffffffff8416602483015291909116906366316d8d90604401600060405180830381600087803b158015610a7457600080fd5b505af1158015610a88573d6000803e3d6000fd5b505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610b16576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610b9a6127af565b610ba26127b7565b6000610bac610de2565b905060005b8151811015610d8e576000600a6000848481518110610bd257610bd26146e3565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252810191909152604001600020546bffffffffffffffffffffffff1690508015610d7d576000600a6000858581518110610c3157610c316146e3565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550610cc87f000000000000000000000000000000000000000000000000000000000000000090565b73ffffffffffffffffffffffffffffffffffffffff166366316d8d848481518110610cf557610cf56146e3565b6020026020010151836040518363ffffffff1660e01b8152600401610d4a92919073ffffffffffffffffffffffffffffffffffffffff9290921682526bffffffffffffffffffffffff16602082015260400190565b600060405180830381600087803b158015610d6457600080fd5b505af1158015610d78573d6000803e3d6000fd5b505050505b50610d8781614712565b9050610bb1565b5050565b610d9a61272c565b6000819003610dd5576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600c6105ec82848361454c565b60606006805480602002602001604051908101604052809291908181526020018280548015610e4757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610e1c575b5050505050905090565b6060600d8054610e60906144b3565b9050600003610e9b576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600d8054610ea8906144b3565b80601f0160208091040260200160405190810160405280929190818152602001828054610ed4906144b3565b8015610e475780601f10610ef657610100808354040283529160200191610e47565b820191906000526020600020905b815481529060010190602001808311610f0457509395945050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610f91576040517fc41a5b0900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008181526007602052604080822091909155517f8a4b97add3359bd6bcf5e82874363670eb5ad0f7615abddbd0ed0a3a98f0f416906108369083815260200190565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091523373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161461109c576040517fc41a5b0900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6110ad6110a88361474a565b612963565b90506110bf6060830160408401614496565b815173ffffffffffffffffffffffffffffffffffffffff91909116907fbf50768ccf13bd0110ca6d53a9c4f1f3271abdd4c24a56878863ed25b20598ff3261110d60c0870160a08801614837565b61111f61016088016101408901614496565b6111298880614854565b61113b6101208b016101008c016148b9565b60208b01356111516101008d0160e08e016148d4565b8b604051611167999897969594939291906148f1565b60405180910390a35b919050565b6000806111828989612e01565b915091508115611193575050611782565b604080518b3580825262ffffff6020808f0135600881901c9290921690840152909290917fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a16111f08b8b8b8b8b8b612f8a565b60035460009060029061120e9060ff80821691610100900416614999565b61121891906149e1565b611223906001614999565b60ff169050888114611291576040517f660bd4ba00000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f77726f6e67206e756d626572206f66207369676e6174757265730000000000006044820152606401610b0d565b888714611320576040517f660bd4ba00000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f7265706f727420727320616e64207373206d757374206265206f66206571756160448201527f6c206c656e6774680000000000000000000000000000000000000000000000006064820152608401610b0d565b3360009081526004602090815260408083208151808301909252805460ff8082168452929391929184019161010090910416600281111561136357611363614a03565b600281111561137457611374614a03565b905250905060028160200151600281111561139157611391614a03565b141580156113da57506006816000015160ff16815481106113b4576113b46146e3565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff163314155b15611441576040517f660bd4ba00000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f756e617574686f72697a6564207472616e736d697474657200000000000000006044820152606401610b0d565b5050505061144d613a4c565b60008a8a60405161145f929190614a32565b604051908190038120611476918e90602001614a42565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120838301909252600080845290830152915060005b898110156117725760006001848984602081106114df576114df6146e3565b6114ec91901a601b614999565b8e8e868181106114fe576114fe6146e3565b905060200201358d8d87818110611517576115176146e3565b9050602002013560405160008152602001604052604051611554949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015611576573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff811660009081526004602090815290849020838501909452835460ff808216855292965092945084019161010090041660028111156115f6576115f6614a03565b600281111561160757611607614a03565b905250925060018360200151600281111561162457611624614a03565b1461168b576040517f660bd4ba00000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f61646472657373206e6f7420617574686f72697a656420746f207369676e00006044820152606401610b0d565b8251600090869060ff16601f81106116a5576116a56146e3565b602002015173ffffffffffffffffffffffffffffffffffffffff1614611727576040517f660bd4ba00000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6e6f6e2d756e69717565207369676e61747572650000000000000000000000006044820152606401610b0d565b8085846000015160ff16601f8110611741576117416146e3565b73ffffffffffffffffffffffffffffffffffffffff90921660209290920201525061176b81614712565b90506114c0565b50505061177e82613041565b5050505b5050505050505050565b60007f00000000000000000000000000000000000000000000000000000000000000006040517f10fc49c100000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8816600482015263ffffffff8516602482015273ffffffffffffffffffffffffffffffffffffffff91909116906310fc49c19060440160006040518083038186803b15801561182c57600080fd5b505afa158015611840573d6000803e3d6000fd5b5050505066038d7ea4c68000821115611885576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061188f610841565b905060006118d287878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061023c92505050565b90506118e085858385613190565b98975050505050505050565b6060600c80546118fb906144b3565b9050600003611936576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600c8054610ea8906144b3565b855185518560ff16601f8311156119b6576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f746f6f206d616e79207369676e657273000000000000000000000000000000006044820152606401610b0d565b80600003611a20576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f66206d75737420626520706f73697469766500000000000000000000000000006044820152606401610b0d565b818314611aae576040517f89a61989000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f6f7261636c6520616464726573736573206f7574206f6620726567697374726160448201527f74696f6e000000000000000000000000000000000000000000000000000000006064820152608401610b0d565b611ab9816003614a56565b8311611b21576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661756c74792d6f7261636c65206620746f6f206869676800000000000000006044820152606401610b0d565b611b2961272c565b6040805160c0810182528a8152602081018a905260ff89169181018290526060810188905267ffffffffffffffff8716608082015260a0810186905290611b7090886132fd565b60055415611d2557600554600090611b8a90600190614a6d565b9050600060058281548110611ba157611ba16146e3565b60009182526020822001546006805473ffffffffffffffffffffffffffffffffffffffff90921693509084908110611bdb57611bdb6146e3565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff85811684526004909252604080842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000090811690915592909116808452922080549091169055600580549192509080611c5b57611c5b614a80565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff00000000000000000000000000000000000000001690550190556006805480611cc457611cc4614a80565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905501905550611b70915050565b60005b8151518110156122dc57815180516000919083908110611d4a57611d4a6146e3565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603611dcf576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f7369676e6572206d757374206e6f7420626520656d70747900000000000000006044820152606401610b0d565b600073ffffffffffffffffffffffffffffffffffffffff1682602001518281518110611dfd57611dfd6146e3565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603611e82576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f7472616e736d6974746572206d757374206e6f7420626520656d7074790000006044820152606401610b0d565b60006004600084600001518481518110611e9e57611e9e6146e3565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002054610100900460ff166002811115611ee857611ee8614a03565b14611f4f576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265706561746564207369676e657220616464726573730000000000000000006044820152606401610b0d565b6040805180820190915260ff82168152600160208201528251805160049160009185908110611f8057611f806146e3565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000161761010083600281111561202157612021614a03565b0217905550600091506120319050565b600460008460200151848151811061204b5761204b6146e3565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002054610100900460ff16600281111561209557612095614a03565b146120fc576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f7265706561746564207472616e736d69747465722061646472657373000000006044820152606401610b0d565b6040805180820190915260ff82168152602081016002815250600460008460200151848151811061212f5761212f6146e3565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000016176101008360028111156121d0576121d0614a03565b0217905550508251805160059250839081106121ee576121ee6146e3565b602090810291909101810151825460018101845560009384529282902090920180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909316929092179091558201518051600691908390811061226a5761226a6146e3565b60209081029190910181015182546001810184556000938452919092200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909216919091179055806122d481614712565b915050611d28565b506040810151600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff909216919091179055600180547fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff8116780100000000000000000000000000000000000000000000000063ffffffff438116820292909217808555920481169291829160149161239491849174010000000000000000000000000000000000000000900416614aaf565b92506101000a81548163ffffffff021916908363ffffffff1602179055506123f34630600160149054906101000a900463ffffffff1663ffffffff16856000015186602001518760400151886060015189608001518a60a00151613316565b600281905582518051600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010060ff9093169290920291909117905560015460208501516040808701516060880151608089015160a08a015193517f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e05986124aa988b9891977401000000000000000000000000000000000000000090920463ffffffff16969095919491939192614acc565b60405180910390a15050505050505050505050565b604080516101208101825260085463ffffffff80821683526401000000008204811660208401526801000000000000000082048116838501526c0100000000000000000000000080830482166060850152700100000000000000000000000000000000830468ffffffffffffffffff166080850152790100000000000000000000000000000000000000000000000000830464ffffffffff1660a0808601919091527e0100000000000000000000000000000000000000000000000000000000000090930461ffff1660c08501526009547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811660e08601527c01000000000000000000000000000000000000000000000000000000009004909116610100840152600b5484517ffeaf968c00000000000000000000000000000000000000000000000000000000815294516000958694859490930473ffffffffffffffffffffffffffffffffffffffff169263feaf968c926004808401938290030181865afa15801561264d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126719190614b7c565b5093505092505080426126849190614a6d565b836020015163ffffffff161080156126a657506000836020015163ffffffff16115b156126d457505060e001517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16919050565b60008213612711576040517f43d4cf6600000000000000000000000000000000000000000000000000000000815260048101839052602401610b0d565b5092915050565b61272061272c565b612729816133c1565b50565b60005473ffffffffffffffffffffffffffffffffffffffff1633146127ad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610b0d565b565b6127ad61272c565b600b546bffffffffffffffffffffffff166000036127d157565b60006127db610de2565b8051909150600081900361281b576040517f30274b3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600b5460009061283a9083906bffffffffffffffffffffffff16614bcc565b905060005b828110156129055781600a600086848151811061285e5761285e6146e3565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282829054906101000a90046bffffffffffffffffffffffff166128c69190614bf7565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550806128fe90614712565b905061283f565b506129108282614c1c565b600b80546000906129309084906bffffffffffffffffffffffff166146be565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810191909152604080516101208101825260085463ffffffff80821683526401000000008204811660208401526801000000000000000082048116938301939093526c0100000000000000000000000081048316606083015268ffffffffffffffffff700100000000000000000000000000000000820416608083015264ffffffffff79010000000000000000000000000000000000000000000000000082041660a083015261ffff7e01000000000000000000000000000000000000000000000000000000000000909104811660c083018190526009547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811660e08501527c0100000000000000000000000000000000000000000000000000000000900490931661010080840191909152850151919291161115612b1e576040517fdada758700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600854600090700100000000000000000000000000000000900468ffffffffffffffffff1690506000612b5b8560e001513a848860800151613190565b9050806bffffffffffffffffffffffff1685606001516bffffffffffffffffffffffff161015612bb7576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600083610100015163ffffffff1642612bd09190614c44565b905060003087604001518860a001518960c001516001612bf09190614c57565b8a5180516020918201206101008d015160e08e0151604051612ca498979695948c918c9132910173ffffffffffffffffffffffffffffffffffffffff9a8b168152988a1660208a015267ffffffffffffffff97881660408a0152959096166060880152608087019390935261ffff9190911660a086015263ffffffff90811660c08601526bffffffffffffffffffffffff9190911660e0850152919091166101008301529091166101208201526101400190565b6040516020818303038152906040528051906020012090506040518061016001604052808281526020013073ffffffffffffffffffffffffffffffffffffffff168152602001846bffffffffffffffffffffffff168152602001886040015173ffffffffffffffffffffffffffffffffffffffff1681526020018860a0015167ffffffffffffffff1681526020018860e0015163ffffffff168152602001886080015168ffffffffffffffffff1681526020018568ffffffffffffffffff168152602001866040015163ffffffff1664ffffffffff168152602001866060015163ffffffff1664ffffffffff1681526020018363ffffffff16815250955085604051602001612db391906140b5565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012060009384526007909252909120555092949350505050565b6000612e356040518060a0016040528060608152602001606081526020016060815260200160608152602001606081525090565b600080808080612e47888a018a614d53565b84519499509297509095509350915060ff16801580612e67575084518114155b80612e73575083518114155b80612e7f575082518114155b80612e8b575081518114155b15612ef2576040517f660bd4ba00000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4669656c6473206d75737420626520657175616c206c656e67746800000000006044820152606401610b0d565b60005b81811015612f5857612f2e878281518110612f1257612f126146e3565b6020026020010151600090815260076020526040902054151590565b612f5857612f3d600183614a6d565b8103612f4857600198505b612f5181614712565b9050612ef5565b50506040805160a0810182529586526020860194909452928401919091526060830152608082015290505b9250929050565b6000612f97826020614a56565b612fa2856020614a56565b612fae88610144614c44565b612fb89190614c44565b612fc29190614c44565b612fcd906000614c44565b9050368114613038576040517f660bd4ba00000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f63616c6c64617461206c656e677468206d69736d6174636800000000000000006044820152606401610b0d565b50505050505050565b80515160ff1660005b818110156105ec5760006130f38460000151838151811061306d5761306d6146e3565b60200260200101518560200151848151811061308b5761308b6146e3565b6020026020010151866040015185815181106130a9576130a96146e3565b6020026020010151876060015186815181106130c7576130c76146e3565b6020026020010151886080015187815181106130e5576130e56146e3565b6020026020010151886134b6565b9050600081600681111561310957613109614a03565b14806131265750600181600681111561312457613124614a03565b145b1561317f57835180518390811061313f5761313f6146e3565b60209081029190910181015160405133815290917fc708e0440951fd63499c0f7a73819b469ee5dd3ecc356c0ab4eb7f18389009d9910160405180910390a25b5061318981614712565b905061304a565b600854600090790100000000000000000000000000000000000000000000000000900464ffffffffff168410156131eb57600854790100000000000000000000000000000000000000000000000000900464ffffffffff1693505b600854600090612710906132059063ffffffff1687614a56565b61320f9190614e25565b6132199086614c44565b60085490915060009087906132529063ffffffff6c01000000000000000000000000820481169168010000000000000000900416614aaf565b61325c9190614aaf565b63ffffffff16905060006132a66000368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506137ca92505050565b905060006132c7826132b88587614a56565b6132c29190614c44565b61390c565b905060006132e368ffffffffffffffffff808916908a16614bf7565b90506132ef8183614bf7565b9a9950505050505050505050565b6000613307610de2565b511115610d8e57610d8e6127b7565b6000808a8a8a8a8a8a8a8a8a60405160200161333a99989796959493929190614e39565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b3373ffffffffffffffffffffffffffffffffffffffff821603613440576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610b0d565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600080848060200190518101906134cd9190614f05565b905060003a8261012001518361010001516134e89190614fcd565b64ffffffffff166134f99190614a56565b905060008460ff166135416000368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506137ca92505050565b61354b9190614e25565b9050600061355c6132c28385614c44565b905060006135693a61390c565b90506000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663330605298e8e868b60e0015168ffffffffffffffffff16896135c89190614bf7565b338d6040518763ffffffff1660e01b81526004016135eb96959493929190614feb565b60408051808303816000875af1158015613609573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061362d9190615067565b9092509050600082600681111561364657613646614a03565b14806136635750600182600681111561366157613661614a03565b145b156137b95760008e8152600760205260408120556136818185614bf7565b336000908152600a6020526040812080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff93841617905560e0890151600b805468ffffffffffffffffff909216939092916136ed91859116614bf7565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508d7f90815c2e624694e8010bffad2bcefaf96af282ef1bc2ebc0042d1b89a585e0468487848b60c0015168ffffffffffffffffff168c60e0015168ffffffffffffffffff16878b61376c9190614bf7565b6137769190614bf7565b6137809190614bf7565b604080516bffffffffffffffffffffffff9586168152602081019490945291841683830152909216606082015290519081900360800190a25b509c9b505050505050505050505050565b6000466137d681613940565b1561385257606c73ffffffffffffffffffffffffffffffffffffffff1663c6f7de0e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613827573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061384b919061509a565b9392505050565b61385b81613963565b156139035773420000000000000000000000000000000000000f73ffffffffffffffffffffffffffffffffffffffff166349948e0e846040518060800160405280604881526020016150e3604891396040516020016138bb9291906150b3565b6040516020818303038152906040526040518263ffffffff1660e01b81526004016138e69190613d7a565b602060405180830381865afa158015613827573d6000803e3d6000fd5b50600092915050565b600061393a6139196124bf565b61392b84670de0b6b3a7640000614a56565b6139359190614e25565b6139aa565b92915050565b600061a4b1821480613954575062066eed82145b8061393a57505062066eee1490565b6000600a82148061397557506101a482145b80613982575062aa37dc82145b8061398e575061210582145b8061399b575062014a3382145b8061393a57505062014a341490565b60006bffffffffffffffffffffffff821115613a48576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201527f36206269747300000000000000000000000000000000000000000000000000006064820152608401610b0d565b5090565b604051806103e00160405280601f906020820280368337509192915050565b60008083601f840112613a7d57600080fd5b50813567ffffffffffffffff811115613a9557600080fd5b602083019150836020828501011115612f8357600080fd5b60008060208385031215613ac057600080fd5b823567ffffffffffffffff811115613ad757600080fd5b613ae385828601613a6b565b90969095509350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610120810167ffffffffffffffff81118282101715613b4257613b42613aef565b60405290565b604051610160810167ffffffffffffffff81118282101715613b4257613b42613aef565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613bb357613bb3613aef565b604052919050565b63ffffffff8116811461272957600080fd5b803561117081613bbb565b68ffffffffffffffffff8116811461272957600080fd5b803561117081613bd8565b64ffffffffff8116811461272957600080fd5b803561117081613bfa565b803561ffff8116811461117057600080fd5b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116811461117057600080fd5b60006101208284031215613c6957600080fd5b613c71613b1e565b613c7a83613bcd565b8152613c8860208401613bcd565b6020820152613c9960408401613bcd565b6040820152613caa60608401613bcd565b6060820152613cbb60808401613bef565b6080820152613ccc60a08401613c0d565b60a0820152613cdd60c08401613c18565b60c0820152613cee60e08401613c2a565b60e0820152610100613d01818501613bcd565b908201529392505050565b60005b83811015613d27578181015183820152602001613d0f565b50506000910152565b60008151808452613d48816020860160208601613d0c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061384b6020830184613d30565b600082601f830112613d9e57600080fd5b813567ffffffffffffffff811115613db857613db8613aef565b613de960207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613b6c565b818152846020838601011115613dfe57600080fd5b816020850160208301376000918101602001919091529392505050565b600060208284031215613e2d57600080fd5b813567ffffffffffffffff811115613e4457600080fd5b613e5084828501613d8d565b949350505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461272957600080fd5b803561117081613e58565b6bffffffffffffffffffffffff8116811461272957600080fd5b803561117081613e85565b60008060408385031215613ebd57600080fd5b8235613ec881613e58565b91506020830135613ed881613e85565b809150509250929050565b600081518084526020808501945080840160005b83811015613f2957815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101613ef7565b509495945050505050565b60208152600061384b6020830184613ee3565b600060208284031215613f5957600080fd5b5035919050565b600060208284031215613f7257600080fd5b813567ffffffffffffffff811115613f8957600080fd5b8201610160818503121561384b57600080fd5b805182526020810151613fc7602084018273ffffffffffffffffffffffffffffffffffffffff169052565b506040810151613fe760408401826bffffffffffffffffffffffff169052565b50606081015161400f606084018273ffffffffffffffffffffffffffffffffffffffff169052565b50608081015161402b608084018267ffffffffffffffff169052565b5060a081015161404360a084018263ffffffff169052565b5060c081015161406060c084018268ffffffffffffffffff169052565b5060e081015161407d60e084018268ffffffffffffffffff169052565b506101008181015164ffffffffff9081169184019190915261012080830151909116908301526101409081015163ffffffff16910152565b610160810161393a8284613f9c565b60008083601f8401126140d657600080fd5b50813567ffffffffffffffff8111156140ee57600080fd5b6020830191508360208260051b8501011115612f8357600080fd5b60008060008060008060008060e0898b03121561412557600080fd5b606089018a81111561413657600080fd5b8998503567ffffffffffffffff8082111561415057600080fd5b61415c8c838d01613a6b565b909950975060808b013591508082111561417557600080fd5b6141818c838d016140c4565b909750955060a08b013591508082111561419a57600080fd5b506141a78b828c016140c4565b999c989b50969995989497949560c00135949350505050565b815163ffffffff908116825260208084015182169083015260408084015182169083015260608084015191821690830152610120820190506080830151614214608084018268ffffffffffffffffff169052565b5060a083015161422d60a084018264ffffffffff169052565b5060c083015161424360c084018261ffff169052565b5060e083015161427360e08401827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff169052565b506101008381015163ffffffff8116848301525b505092915050565b67ffffffffffffffff8116811461272957600080fd5b80356111708161428f565b6000806000806000608086880312156142c857600080fd5b85356142d38161428f565b9450602086013567ffffffffffffffff8111156142ef57600080fd5b6142fb88828901613a6b565b909550935050604086013561430f81613bbb565b949793965091946060013592915050565b600067ffffffffffffffff82111561433a5761433a613aef565b5060051b60200190565b600082601f83011261435557600080fd5b8135602061436a61436583614320565b613b6c565b82815260059290921b8401810191818101908684111561438957600080fd5b8286015b848110156143ad5780356143a081613e58565b835291830191830161438d565b509695505050505050565b803560ff8116811461117057600080fd5b60008060008060008060c087890312156143e257600080fd5b863567ffffffffffffffff808211156143fa57600080fd5b6144068a838b01614344565b9750602089013591508082111561441c57600080fd5b6144288a838b01614344565b965061443660408a016143b8565b9550606089013591508082111561444c57600080fd5b6144588a838b01613d8d565b945061446660808a016142a5565b935060a089013591508082111561447c57600080fd5b5061448989828a01613d8d565b9150509295509295509295565b6000602082840312156144a857600080fd5b813561384b81613e58565b600181811c908216806144c757607f821691505b602082108103614500577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f8211156105ec57600081815260208120601f850160051c8101602086101561452d5750805b601f850160051c820191505b81811015610a8857828155600101614539565b67ffffffffffffffff83111561456457614564613aef565b6145788361457283546144b3565b83614506565b6000601f8411600181146145ca57600085156145945750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355614660565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b8281101561461957868501358255602094850194600190920191016145f9565b5086821015614654577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b805161117081613bd8565b60006020828403121561468457600080fd5b815161384b81613bd8565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6bffffffffffffffffffffffff8281168282160390808211156127115761271161468f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036147435761474361468f565b5060010190565b6000610160823603121561475d57600080fd5b614765613b48565b823567ffffffffffffffff81111561477c57600080fd5b61478836828601613d8d565b825250602083013560208201526147a160408401613e7a565b60408201526147b260608401613e9f565b60608201526147c360808401613bef565b60808201526147d460a084016142a5565b60a08201526147e560c084016142a5565b60c08201526147f660e08401613bcd565b60e0820152610100614809818501613c18565b9082015261012061481b8482016142a5565b9082015261014061482d848201613e7a565b9082015292915050565b60006020828403121561484957600080fd5b813561384b8161428f565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261488957600080fd5b83018035915067ffffffffffffffff8211156148a457600080fd5b602001915036819003821315612f8357600080fd5b6000602082840312156148cb57600080fd5b61384b82613c18565b6000602082840312156148e657600080fd5b813561384b81613bbb565b73ffffffffffffffffffffffffffffffffffffffff8a8116825267ffffffffffffffff8a166020830152881660408201526102406060820181905281018690526000610260878982850137600083890182015261ffff8716608084015260a0830186905263ffffffff851660c0840152601f88017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01683010190506132ef60e0830184613f9c565b60ff818116838216019081111561393a5761393a61468f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600060ff8316806149f4576149f46149b2565b8060ff84160491505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8183823760009101908152919050565b828152606082602083013760800192915050565b808202811582820484141761393a5761393a61468f565b8181038181111561393a5761393a61468f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b63ffffffff8181168382160190808211156127115761271161468f565b600061012063ffffffff808d1684528b6020850152808b16604085015250806060840152614afc8184018a613ee3565b90508281036080840152614b108189613ee3565b905060ff871660a084015282810360c0840152614b2d8187613d30565b905067ffffffffffffffff851660e0840152828103610100840152614b528185613d30565b9c9b505050505050505050505050565b805169ffffffffffffffffffff8116811461117057600080fd5b600080600080600060a08688031215614b9457600080fd5b614b9d86614b62565b9450602086015193506040860151925060608601519150614bc060808701614b62565b90509295509295909350565b60006bffffffffffffffffffffffff80841680614beb57614beb6149b2565b92169190910492915050565b6bffffffffffffffffffffffff8181168382160190808211156127115761271161468f565b6bffffffffffffffffffffffff8181168382160280821691908281146142875761428761468f565b8082018082111561393a5761393a61468f565b67ffffffffffffffff8181168382160190808211156127115761271161468f565b600082601f830112614c8957600080fd5b81356020614c9961436583614320565b82815260059290921b84018101918181019086841115614cb857600080fd5b8286015b848110156143ad5780358352918301918301614cbc565b600082601f830112614ce457600080fd5b81356020614cf461436583614320565b82815260059290921b84018101918181019086841115614d1357600080fd5b8286015b848110156143ad57803567ffffffffffffffff811115614d375760008081fd5b614d458986838b0101613d8d565b845250918301918301614d17565b600080600080600060a08688031215614d6b57600080fd5b853567ffffffffffffffff80821115614d8357600080fd5b614d8f89838a01614c78565b96506020880135915080821115614da557600080fd5b614db189838a01614cd3565b95506040880135915080821115614dc757600080fd5b614dd389838a01614cd3565b94506060880135915080821115614de957600080fd5b614df589838a01614cd3565b93506080880135915080821115614e0b57600080fd5b50614e1888828901614cd3565b9150509295509295909350565b600082614e3457614e346149b2565b500490565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b166040850152816060850152614e808285018b613ee3565b91508382036080850152614e94828a613ee3565b915060ff881660a085015283820360c0850152614eb18288613d30565b90861660e08501528381036101008501529050614b528185613d30565b805161117081613e58565b805161117081613e85565b80516111708161428f565b805161117081613bbb565b805161117081613bfa565b60006101608284031215614f1857600080fd5b614f20613b48565b82518152614f3060208401614ece565b6020820152614f4160408401614ed9565b6040820152614f5260608401614ece565b6060820152614f6360808401614ee4565b6080820152614f7460a08401614eef565b60a0820152614f8560c08401614667565b60c0820152614f9660e08401614667565b60e0820152610100614fa9818501614efa565b90820152610120614fbb848201614efa565b90820152610140613d01848201614eef565b64ffffffffff8181168382160190808211156127115761271161468f565b6000610200808352614fff8184018a613d30565b905082810360208401526150138189613d30565b6bffffffffffffffffffffffff88811660408601528716606085015273ffffffffffffffffffffffffffffffffffffffff86166080850152915061505c905060a0830184613f9c565b979650505050505050565b6000806040838503121561507a57600080fd5b82516007811061508957600080fd5b6020840151909250613ed881613e85565b6000602082840312156150ac57600080fd5b5051919050565b600083516150c5818460208801613d0c565b8351908301906150d9818360208801613d0c565b0194935050505056fe307866666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666a164736f6c6343000813000a", + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"fulfillmentGasPriceOverEstimationBP\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"feedStalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint40\",\"name\":\"minimumEstimateGasPriceWei\",\"type\":\"uint40\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint64\",\"name\":\"fallbackUsdPerUnitLink\",\"type\":\"uint64\"},{\"internalType\":\"uint8\",\"name\":\"fallbackUsdPerUnitLinkDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint224\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"donFeeCentsUsd\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"operationFeeCentsUsd\",\"type\":\"uint16\"}],\"internalType\":\"structFunctionsBillingConfig\",\"name\":\"config\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"linkToNativeFeed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"linkToUsdFeed\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"EmptyPublicKey\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InconsistentReportData\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCalldata\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"linkWei\",\"type\":\"int256\"}],\"name\":\"InvalidLinkWeiPrice\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSubscription\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"usdLink\",\"type\":\"int256\"}],\"name\":\"InvalidUsdLinkPrice\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"MustBeSubOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoTransmittersSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByRouterOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"ReportInvalid\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RouterMustBeSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedPublicKeyChange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSender\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnsupportedRequestDataVersion\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"CommitmentDeleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"fulfillmentGasPriceOverEstimationBP\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"feedStalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint40\",\"name\":\"minimumEstimateGasPriceWei\",\"type\":\"uint40\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint64\",\"name\":\"fallbackUsdPerUnitLink\",\"type\":\"uint64\"},{\"internalType\":\"uint8\",\"name\":\"fallbackUsdPerUnitLinkDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint224\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"donFeeCentsUsd\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"operationFeeCentsUsd\",\"type\":\"uint16\"}],\"indexed\":false,\"internalType\":\"structFunctionsBillingConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"requestingContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requestInitiator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"subscriptionOwner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"flags\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"callbackGasLimit\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"estimatedTotalCostJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint40\"},{\"internalType\":\"uint32\",\"name\":\"timeoutTimestamp\",\"type\":\"uint32\"}],\"indexed\":false,\"internalType\":\"structFunctionsResponse.Commitment\",\"name\":\"commitment\",\"type\":\"tuple\"}],\"name\":\"OracleRequest\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"}],\"name\":\"OracleResponse\",\"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\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"juelsPerGas\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"l1FeeShareWei\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"callbackCostJuels\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint72\",\"name\":\"donFeeJuels\",\"type\":\"uint72\"},{\"indexed\":false,\"internalType\":\"uint72\",\"name\":\"adminFeeJuels\",\"type\":\"uint72\"},{\"indexed\":false,\"internalType\":\"uint72\",\"name\":\"operationFeeJuels\",\"type\":\"uint72\"}],\"name\":\"RequestBilled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"deleteCommitment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"gasPriceWei\",\"type\":\"uint256\"}],\"name\":\"estimateCost\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAdminFeeJuels\",\"outputs\":[{\"internalType\":\"uint72\",\"name\":\"\",\"type\":\"uint72\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"fulfillmentGasPriceOverEstimationBP\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"feedStalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint40\",\"name\":\"minimumEstimateGasPriceWei\",\"type\":\"uint40\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint64\",\"name\":\"fallbackUsdPerUnitLink\",\"type\":\"uint64\"},{\"internalType\":\"uint8\",\"name\":\"fallbackUsdPerUnitLinkDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint224\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"donFeeCentsUsd\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"operationFeeCentsUsd\",\"type\":\"uint16\"}],\"internalType\":\"structFunctionsBillingConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"getDONFeeJuels\",\"outputs\":[{\"internalType\":\"uint72\",\"name\":\"\",\"type\":\"uint72\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDONPublicKey\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOperationFeeJuels\",\"outputs\":[{\"internalType\":\"uint72\",\"name\":\"\",\"type\":\"uint72\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getThresholdPublicKey\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getUsdPerUnitLink\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getWeiPerUnitLink\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"oracleWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"oracleWithdrawAll\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"_transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"_f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"_onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"_offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"_offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"donPublicKey\",\"type\":\"bytes\"}],\"name\":\"setDONPublicKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"thresholdPublicKey\",\"type\":\"bytes\"}],\"name\":\"setThresholdPublicKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes32\",\"name\":\"flags\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"requestingContract\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"availableBalance\",\"type\":\"uint96\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"initiatedRequests\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint64\",\"name\":\"completedRequests\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"subscriptionOwner\",\"type\":\"address\"}],\"internalType\":\"structFunctionsResponse.RequestMeta\",\"name\":\"request\",\"type\":\"tuple\"}],\"name\":\"startRequest\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"estimatedTotalCostJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint40\"},{\"internalType\":\"uint32\",\"name\":\"timeoutTimestamp\",\"type\":\"uint32\"}],\"internalType\":\"structFunctionsResponse.Commitment\",\"name\":\"commitment\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"transmitters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"fulfillmentGasPriceOverEstimationBP\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"feedStalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint40\",\"name\":\"minimumEstimateGasPriceWei\",\"type\":\"uint40\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint64\",\"name\":\"fallbackUsdPerUnitLink\",\"type\":\"uint64\"},{\"internalType\":\"uint8\",\"name\":\"fallbackUsdPerUnitLinkDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint224\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"donFeeCentsUsd\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"operationFeeCentsUsd\",\"type\":\"uint16\"}],\"internalType\":\"structFunctionsBillingConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"updateConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60a06040523480156200001157600080fd5b506040516200601f3803806200601f8339810160408190526200003491620004db565b83838383833380600081620000905760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c357620000c3816200014e565b5050506001600160a01b038116620000ee57604051632530e88560e11b815260040160405180910390fd5b6001600160a01b03908116608052600c80546001600160601b03166c0100000000000000000000000085841602179055600d80546001600160a01b0319169183169190911790556200014083620001f9565b505050505050505062000742565b336001600160a01b03821603620001a85760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000087565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b620002036200039e565b80516008805460208401516040808601516060870151608088015160a089015160c08a015160e08b015160ff16600160f81b026001600160f81b036001600160401b03909216600160b81b02919091166001600160b81b0361ffff938416600160a81b0261ffff60a81b1964ffffffffff909616600160801b029590951666ffffffffffffff60801b1963ffffffff9788166c010000000000000000000000000263ffffffff60601b19998916680100000000000000000299909916600160401b600160801b03199b8916640100000000026001600160401b0319909d169e89169e909e179b909b17999099169b909b1795909517979097169590951717969096161792909217909255610100840151610120850151909316600160e01b026001600160e01b0390931692909217600955610140830151600a80546101608601518416620100000263ffffffff19919091169290931691909117919091179055517f2e2c8535dcc25459d519f2300c114d2d2128bf6399722d04eca078461a3bf33a906200039390839062000639565b60405180910390a150565b620003a8620003aa565b565b6000546001600160a01b03163314620003a85760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000087565b80516001600160a01b03811681146200041e57600080fd5b919050565b60405161018081016001600160401b03811182821017156200045557634e487b7160e01b600052604160045260246000fd5b60405290565b805163ffffffff811681146200041e57600080fd5b805164ffffffffff811681146200041e57600080fd5b805161ffff811681146200041e57600080fd5b80516001600160401b03811681146200041e57600080fd5b805160ff811681146200041e57600080fd5b80516001600160e01b03811681146200041e57600080fd5b6000806000808486036101e0811215620004f457600080fd5b620004ff8662000406565b945061018080601f19830112156200051657600080fd5b6200052062000423565b915062000530602088016200045b565b825262000540604088016200045b565b602083015262000553606088016200045b565b604083015262000566608088016200045b565b60608301526200057960a0880162000470565b60808301526200058c60c0880162000486565b60a08301526200059f60e0880162000499565b60c0830152610100620005b4818901620004b1565b60e0840152610120620005c9818a01620004c3565b828501526101409150620005df828a016200045b565b90840152610160620005f389820162000486565b8285015262000604838a0162000486565b90840152509093506200061d90506101a0860162000406565b91506200062e6101c0860162000406565b905092959194509250565b815163ffffffff1681526101808101602083015162000660602084018263ffffffff169052565b50604083015162000679604084018263ffffffff169052565b50606083015162000692606084018263ffffffff169052565b506080830151620006ac608084018264ffffffffff169052565b5060a0830151620006c360a084018261ffff169052565b5060c0830151620006df60c08401826001600160401b03169052565b5060e0830151620006f560e084018260ff169052565b50610100838101516001600160e01b0316908301526101208084015163ffffffff16908301526101408084015161ffff908116918401919091526101609384015116929091019190915290565b608051615897620007886000396000818161079c01528181610c7d01528181610f110152818161102701528181611b2d015281816129eb015261396901526158976000f3fe608060405234801561001057600080fd5b50600436106101a35760003560e01c80638da5cb5b116100ee578063d227d24511610097578063e4ddcea611610071578063e4ddcea6146105d5578063f2f22ef1146105eb578063f2fde38b146105f3578063f6ea41f61461060657600080fd5b8063d227d2451461058a578063d328a91e146105ba578063e3d0e712146105c257600080fd5b8063b1dc65a4116100c8578063b1dc65a414610396578063ba9c924d146103a9578063c3f909d4146103bc57600080fd5b80638da5cb5b1461032e578063a631571e14610356578063afcb95d71461037657600080fd5b80637d4807871161015057806381f1b9381161012a57806381f1b938146102a657806381ff7048146102ae57806385b214cf1461031b57600080fd5b80637d480787146102765780637f15e1661461027e578063814118341461029157600080fd5b806366316d8d1161018157806366316d8d1461023c5780637212762f1461024f57806379ba50971461026e57600080fd5b8063083a5466146101a8578063181f5a77146101bd578063626f458c1461020f575b600080fd5b6101bb6101b6366004614010565b61060e565b005b6101f96040518060400160405280601c81526020017f46756e6374696f6e7320436f6f7264696e61746f722076312e332e300000000081525081565b60405161020691906140c0565b60405180910390f35b61022261021d36600461422d565b610663565b60405168ffffffffffffffffff9091168152602001610206565b6101bb61024a3660046142b4565b6106a0565b610257610859565b6040805192835260ff909116602083015201610206565b6101bb610a6c565b6101bb610b69565b6101bb61028c366004614010565b610d69565b610299610db9565b604051610206919061433e565b6101f9610e28565b6102f860015460025463ffffffff74010000000000000000000000000000000000000000830481169378010000000000000000000000000000000000000000000000009093041691565b6040805163ffffffff948516815293909216602084015290820152606001610206565b6101bb610329366004614351565b610ef9565b60005460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610206565b61036961036436600461436a565b610fb6565b60405161020691906144bf565b604080516001815260006020820181905291810191909152606001610206565b6101bb6103a4366004614513565b611247565b6101bb6103b736600461467e565b61185e565b61057d6040805161018081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081019190915250604080516101808101825260085463ffffffff80821683526401000000008204811660208401526801000000000000000082048116938301939093526c01000000000000000000000000810483166060830152700100000000000000000000000000000000810464ffffffffff1660808301527501000000000000000000000000000000000000000000810461ffff90811660a084015277010000000000000000000000000000000000000000000000820467ffffffffffffffff1660c08401527f010000000000000000000000000000000000000000000000000000000000000090910460ff1660e08301526009547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81166101008401527c01000000000000000000000000000000000000000000000000000000009004909216610120820152600a5480831661014083015262010000900490911661016082015290565b604051610206919061476a565b61059d610598366004614887565b611b29565b6040516bffffffffffffffffffffffff9091168152602001610206565b6101f9611c97565b6101bb6105d036600461498f565b611cee565b6105dd61286a565b604051908152602001610206565b6102226129ae565b6101bb610601366004614a5c565b6129d3565b6102226129e7565b610616612a78565b6000819003610651576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600f61065e828483614b0c565b505050565b600a5460009061069a9060649061067d9061ffff16612afb565b6106879190614c85565b6bffffffffffffffffffffffff16612b48565b92915050565b6106a8612be7565b806bffffffffffffffffffffffff166000036106e25750336000908152600b60205260409020546bffffffffffffffffffffffff1661073c565b336000908152600b60205260409020546bffffffffffffffffffffffff8083169116101561073c576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600b6020526040812080548392906107699084906bffffffffffffffffffffffff16614cb0565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055506107be7f000000000000000000000000000000000000000000000000000000000000000090565b6040517f66316d8d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301526bffffffffffffffffffffffff8416602483015291909116906366316d8d90604401600060405180830381600087803b15801561083d57600080fd5b505af1158015610851573d6000803e3d6000fd5b505050505050565b600080600080600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa1580156108cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f09190614cf6565b5093505092505080426109039190614d46565b600854640100000000900463ffffffff161080156109305750600854640100000000900463ffffffff1615155b1561098d57505060085477010000000000000000000000000000000000000000000000810467ffffffffffffffff16937f010000000000000000000000000000000000000000000000000000000000000090910460ff1692509050565b600082136109cf576040517f56b22ab8000000000000000000000000000000000000000000000000000000008152600481018390526024015b60405180910390fd5b600d54604080517f313ce5670000000000000000000000000000000000000000000000000000000081529051849273ffffffffffffffffffffffffffffffffffffffff169163313ce5679160048083019260209291908290030181865afa158015610a3e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a629190614d59565b9350935050509091565b60015473ffffffffffffffffffffffffffffffffffffffff163314610aed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016109c6565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610b71612d93565b610b79612be7565b6000610b83610db9565b905060005b8151811015610d65576000600b6000848481518110610ba957610ba9614d76565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252810191909152604001600020546bffffffffffffffffffffffff1690508015610d54576000600b6000858581518110610c0857610c08614d76565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550610c9f7f000000000000000000000000000000000000000000000000000000000000000090565b73ffffffffffffffffffffffffffffffffffffffff166366316d8d848481518110610ccc57610ccc614d76565b6020026020010151836040518363ffffffff1660e01b8152600401610d2192919073ffffffffffffffffffffffffffffffffffffffff9290921682526bffffffffffffffffffffffff16602082015260400190565b600060405180830381600087803b158015610d3b57600080fd5b505af1158015610d4f573d6000803e3d6000fd5b505050505b50610d5e81614da5565b9050610b88565b5050565b610d71612a78565b6000819003610dac576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600e61065e828483614b0c565b60606006805480602002602001604051908101604052809291908181526020018280548015610e1e57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610df3575b5050505050905090565b6060600f8054610e3790614a79565b9050600003610e72576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600f8054610e7f90614a79565b80601f0160208091040260200160405190810160405280929190818152602001828054610eab90614a79565b8015610e1e5780601f10610ecd57610100808354040283529160200191610e1e565b820191906000526020600020905b815481529060010190602001808311610edb57509395945050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610f68576040517fc41a5b0900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008181526007602052604080822091909155517f8a4b97add3359bd6bcf5e82874363670eb5ad0f7615abddbd0ed0a3a98f0f41690610fab9083815260200190565b60405180910390a150565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091523373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161461107e576040517fc41a5b0900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061109161108c84614dff565b612d9b565b90925090506110a66060840160408501614a5c565b825173ffffffffffffffffffffffffffffffffffffffff91909116907fbf50768ccf13bd0110ca6d53a9c4f1f3271abdd4c24a56878863ed25b20598ff326110f460c0880160a08901614eec565b61110661016089016101408a01614a5c565b6111108980614f09565b6111226101208c016101008d01614f6e565b60208c01356111386101008e0160e08f01614f89565b6040518061016001604052808e6000015181526020018e6020015173ffffffffffffffffffffffffffffffffffffffff1681526020018e604001516bffffffffffffffffffffffff1681526020018e6060015173ffffffffffffffffffffffffffffffffffffffff1681526020018e6080015167ffffffffffffffff1681526020018e60a0015163ffffffff1681526020018d68ffffffffffffffffff1681526020018e60e0015168ffffffffffffffffff1681526020018e610100015164ffffffffff1681526020018e610120015164ffffffffff1681526020018e610140015163ffffffff1681525060405161123899989796959493929190614fa6565b60405180910390a3505b919050565b600080611254898961314d565b915091508115611265575050611854565b604080518b3580825262ffffff6020808f0135600881901c9290921690840152909290917fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a16112c28b8b8b8b8b8b6132d6565b6003546000906002906112e09060ff8082169161010090041661505c565b6112ea9190615075565b6112f590600161505c565b60ff169050888114611363576040517f660bd4ba00000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f77726f6e67206e756d626572206f66207369676e61747572657300000000000060448201526064016109c6565b8887146113f2576040517f660bd4ba00000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f7265706f727420727320616e64207373206d757374206265206f66206571756160448201527f6c206c656e67746800000000000000000000000000000000000000000000000060648201526084016109c6565b3360009081526004602090815260408083208151808301909252805460ff8082168452929391929184019161010090910416600281111561143557611435615097565b600281111561144657611446615097565b905250905060028160200151600281111561146357611463615097565b141580156114ac57506006816000015160ff168154811061148657611486614d76565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff163314155b15611513576040517f660bd4ba00000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f756e617574686f72697a6564207472616e736d6974746572000000000000000060448201526064016109c6565b5050505061151f613faf565b60008a8a6040516115319291906150c6565b604051908190038120611548918e906020016150d6565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120838301909252600080845290830152915060005b898110156118445760006001848984602081106115b1576115b1614d76565b6115be91901a601b61505c565b8e8e868181106115d0576115d0614d76565b905060200201358d8d878181106115e9576115e9614d76565b9050602002013560405160008152602001604052604051611626949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015611648573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff811660009081526004602090815290849020838501909452835460ff808216855292965092945084019161010090041660028111156116c8576116c8615097565b60028111156116d9576116d9615097565b90525092506001836020015160028111156116f6576116f6615097565b1461175d576040517f660bd4ba00000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f61646472657373206e6f7420617574686f72697a656420746f207369676e000060448201526064016109c6565b8251600090869060ff16601f811061177757611777614d76565b602002015173ffffffffffffffffffffffffffffffffffffffff16146117f9576040517f660bd4ba00000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6e6f6e2d756e69717565207369676e617475726500000000000000000000000060448201526064016109c6565b8085846000015160ff16601f811061181357611813614d76565b73ffffffffffffffffffffffffffffffffffffffff90921660209290920201525061183d81614da5565b9050611592565b5050506118508261338d565b5050505b5050505050505050565b611866612d93565b80516008805460208401516040808601516060870151608088015160a089015160c08a015160e08b015160ff167f0100000000000000000000000000000000000000000000000000000000000000027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff67ffffffffffffffff90921677010000000000000000000000000000000000000000000000029190911676ffffffffffffffffffffffffffffffffffffffffffffff61ffff9384167501000000000000000000000000000000000000000000027fffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffff64ffffffffff90961670010000000000000000000000000000000002959095167fffffffffffffffffff00000000000000ffffffffffffffffffffffffffffffff63ffffffff9788166c01000000000000000000000000027fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff9989166801000000000000000002999099167fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff9b8916640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909d169e89169e909e179b909b17999099169b909b17959095179790971695909517179690961617929092179092556101008401516101208501519093167c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff90931692909217600955610140830151600a8054610160860151841662010000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000919091169290931691909117919091179055517f2e2c8535dcc25459d519f2300c114d2d2128bf6399722d04eca078461a3bf33a90610fab90839061476a565b60007f00000000000000000000000000000000000000000000000000000000000000006040517f10fc49c100000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8816600482015263ffffffff8516602482015273ffffffffffffffffffffffffffffffffffffffff91909116906310fc49c19060440160006040518083038186803b158015611bc957600080fd5b505afa158015611bdd573d6000803e3d6000fd5b5050505066038d7ea4c68000821115611c22576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611c2c6129e7565b90506000611c6f87878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061066392505050565b90506000611c7b6129ae565b9050611c8a86868486856134dc565b9998505050505050505050565b6060600e8054611ca690614a79565b9050600003611ce1576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600e8054610e7f90614a79565b855185518560ff16601f831115611d61576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f746f6f206d616e79207369676e6572730000000000000000000000000000000060448201526064016109c6565b80600003611dcb576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f66206d75737420626520706f736974697665000000000000000000000000000060448201526064016109c6565b818314611e59576040517f89a61989000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f6f7261636c6520616464726573736573206f7574206f6620726567697374726160448201527f74696f6e0000000000000000000000000000000000000000000000000000000060648201526084016109c6565b611e648160036150ea565b8311611ecc576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661756c74792d6f7261636c65206620746f6f2068696768000000000000000060448201526064016109c6565b611ed4612a78565b6040805160c0810182528a8152602081018a905260ff89169181018290526060810188905267ffffffffffffffff8716608082015260a0810186905290611f1b9088613658565b600554156120d057600554600090611f3590600190614d46565b9050600060058281548110611f4c57611f4c614d76565b60009182526020822001546006805473ffffffffffffffffffffffffffffffffffffffff90921693509084908110611f8657611f86614d76565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff85811684526004909252604080842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00009081169091559290911680845292208054909116905560058054919250908061200657612006615101565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055019055600680548061206f5761206f615101565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905501905550611f1b915050565b60005b815151811015612687578151805160009190839081106120f5576120f5614d76565b602002602001015173ffffffffffffffffffffffffffffffffffffffff160361217a576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f7369676e6572206d757374206e6f7420626520656d707479000000000000000060448201526064016109c6565b600073ffffffffffffffffffffffffffffffffffffffff16826020015182815181106121a8576121a8614d76565b602002602001015173ffffffffffffffffffffffffffffffffffffffff160361222d576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f7472616e736d6974746572206d757374206e6f7420626520656d70747900000060448201526064016109c6565b6000600460008460000151848151811061224957612249614d76565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002054610100900460ff16600281111561229357612293615097565b146122fa576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265706561746564207369676e6572206164647265737300000000000000000060448201526064016109c6565b6040805180820190915260ff8216815260016020820152825180516004916000918590811061232b5761232b614d76565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000016176101008360028111156123cc576123cc615097565b0217905550600091506123dc9050565b60046000846020015184815181106123f6576123f6614d76565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002054610100900460ff16600281111561244057612440615097565b146124a7576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f7265706561746564207472616e736d697474657220616464726573730000000060448201526064016109c6565b6040805180820190915260ff8216815260208101600281525060046000846020015184815181106124da576124da614d76565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000161761010083600281111561257b5761257b615097565b02179055505082518051600592508390811061259957612599614d76565b602090810291909101810151825460018101845560009384529282902090920180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909316929092179091558201518051600691908390811061261557612615614d76565b60209081029190910181015182546001810184556000938452919092200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9092169190911790558061267f81614da5565b9150506120d3565b506040810151600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff909216919091179055600180547fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff8116780100000000000000000000000000000000000000000000000063ffffffff438116820292909217808555920481169291829160149161273f91849174010000000000000000000000000000000000000000900416615130565b92506101000a81548163ffffffff021916908363ffffffff16021790555061279e4630600160149054906101000a900463ffffffff1663ffffffff16856000015186602001518760400151886060015189608001518a60a00151613671565b600281905582518051600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010060ff9093169290920291909117905560015460208501516040808701516060880151608089015160a08a015193517f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0598612855988b9891977401000000000000000000000000000000000000000090920463ffffffff1696909591949193919261514d565b60405180910390a15050505050505050505050565b6000806000600c8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa1580156128da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128fe9190614cf6565b5093505092505080426129119190614d46565b600854640100000000900463ffffffff1610801561293e5750600854640100000000900463ffffffff1615155b1561296b5750506009547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16919050565b600082136129a8576040517f43d4cf66000000000000000000000000000000000000000000000000000000008152600481018390526024016109c6565b50919050565b600a546000906129ce9060649061067d9062010000900461ffff16612afb565b905090565b6129db612a78565b6129e48161371c565b50565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632a905ccc6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612a54573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129ce91906151ee565b60005473ffffffffffffffffffffffffffffffffffffffff163314612af9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016109c6565b565b6000806000612b08610859565b9092509050612b4082612b1c83601261505c565b612b2790600a61532b565b612b3190876150ea565b612b3b919061533a565b613811565b949350505050565b600068ffffffffffffffffff821115612be3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203760448201527f322062697473000000000000000000000000000000000000000000000000000060648201526084016109c6565b5090565b600c546bffffffffffffffffffffffff16600003612c0157565b6000612c0b610db9565b80519091506000819003612c4b576040517f30274b3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600c54600090612c6a9083906bffffffffffffffffffffffff16614c85565b905060005b82811015612d355781600b6000868481518110612c8e57612c8e614d76565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282829054906101000a90046bffffffffffffffffffffffff16612cf6919061534e565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555080612d2e90614da5565b9050612c6f565b50612d408282615373565b600c8054600090612d609084906bffffffffffffffffffffffff16614cb0565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550505050565b612af9612a78565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915260085461010083015160009161ffff7501000000000000000000000000000000000000000000909104811691161115612e59576040517fdada758700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612e688460000151610663565b9050612e726129ae565b91506000612e8b8560e001513a848860800151876134dc565b9050806bffffffffffffffffffffffff1685606001516bffffffffffffffffffffffff161015612ee7576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600954600090612f1d907c0100000000000000000000000000000000000000000000000000000000900463ffffffff164261539b565b905060003087604001518860a001518960c001516001612f3d91906153ae565b8a5180516020918201206101008d015160e08e0151604051612ff198979695948c918c9132910173ffffffffffffffffffffffffffffffffffffffff9a8b168152988a1660208a015267ffffffffffffffff97881660408a0152959096166060880152608087019390935261ffff9190911660a086015263ffffffff90811660c08601526bffffffffffffffffffffffff9190911660e0850152919091166101008301529091166101208201526101400190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201206101608401835280845230848301526bffffffffffffffffffffffff8716848401528a83015173ffffffffffffffffffffffffffffffffffffffff16606085015260a0808c015167ffffffffffffffff1660808087019190915260e0808e015163ffffffff90811693880193909352908d015168ffffffffffffffffff90811660c08801528a169086015260085468010000000000000000810482166101008701526c0100000000000000000000000090048116610120860152861661014085015291519298509092506130fd918891016144bf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181528151602092830120600093845260079092529091205550929491935090915050565b60006131816040518060a0016040528060608152602001606081526020016060815260200160608152602001606081525090565b600080808080613193888a018a6154aa565b84519499509297509095509350915060ff168015806131b3575084518114155b806131bf575083518114155b806131cb575082518114155b806131d7575081518114155b1561323e576040517f660bd4ba00000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4669656c6473206d75737420626520657175616c206c656e677468000000000060448201526064016109c6565b60005b818110156132a45761327a87828151811061325e5761325e614d76565b6020026020010151600090815260076020526040902054151590565b6132a457613289600183614d46565b810361329457600198505b61329d81614da5565b9050613241565b50506040805160a0810182529586526020860194909452928401919091526060830152608082015290505b9250929050565b60006132e38260206150ea565b6132ee8560206150ea565b6132fa8861014461539b565b613304919061539b565b61330e919061539b565b61331990600061539b565b9050368114613384576040517f660bd4ba00000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f63616c6c64617461206c656e677468206d69736d61746368000000000000000060448201526064016109c6565b50505050505050565b80515160ff1660005b8181101561065e57600061343f846000015183815181106133b9576133b9614d76565b6020026020010151856020015184815181106133d7576133d7614d76565b6020026020010151866040015185815181106133f5576133f5614d76565b60200260200101518760600151868151811061341357613413614d76565b60200260200101518860800151878151811061343157613431614d76565b6020026020010151886138af565b9050600081600681111561345557613455615097565b14806134725750600181600681111561347057613470615097565b145b156134cb57835180518390811061348b5761348b614d76565b60209081029190910181015160405133815290917fc708e0440951fd63499c0f7a73819b469ee5dd3ecc356c0ab4eb7f18389009d9910160405180910390a25b506134d581614da5565b9050613396565b600854600090700100000000000000000000000000000000900464ffffffffff1685101561352557600854700100000000000000000000000000000000900464ffffffffff1694505b6008546000906127109061353f9063ffffffff16886150ea565b613549919061533a565b613553908761539b565b600854909150600090889061358c9063ffffffff6c01000000000000000000000000820481169168010000000000000000900416615130565b6135969190615130565b63ffffffff16905060006135e06000368080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250613d7392505050565b90506000613601826135f285876150ea565b6135fc919061539b565b613eb5565b905060008668ffffffffffffffffff168868ffffffffffffffffff168a68ffffffffffffffffff16613633919061534e565b61363d919061534e565b9050613649818361534e565b9b9a5050505050505050505050565b6000613662610db9565b511115610d6557610d65612be7565b6000808a8a8a8a8a8a8a8a8a6040516020016136959998979695949392919061557c565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b3373ffffffffffffffffffffffffffffffffffffffff82160361379b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016109c6565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60006bffffffffffffffffffffffff821115612be3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201527f362062697473000000000000000000000000000000000000000000000000000060648201526084016109c6565b600080848060200190518101906138c69190615648565b905060003a8261012001518361010001516138e19190615710565b64ffffffffff166138f291906150ea565b905060008460ff1661393a6000368080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250613d7392505050565b613944919061533a565b905060006139556135fc838561539b565b905060006139623a613eb5565b90506000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663330605298e8e868b60c0015168ffffffffffffffffff168c60e0015168ffffffffffffffffff168a6139d1919061534e565b6139db919061534e565b336040518061016001604052808f6000015181526020018f6020015173ffffffffffffffffffffffffffffffffffffffff1681526020018f604001516bffffffffffffffffffffffff1681526020018f6060015173ffffffffffffffffffffffffffffffffffffffff1681526020018f6080015167ffffffffffffffff1681526020018f60a0015163ffffffff168152602001600068ffffffffffffffffff1681526020018f60e0015168ffffffffffffffffff1681526020018f610100015164ffffffffff1681526020018f610120015164ffffffffff1681526020018f610140015163ffffffff168152506040518763ffffffff1660e01b8152600401613ae99695949392919061572e565b60408051808303816000875af1158015613b07573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b2b91906157aa565b90925090506000826006811115613b4457613b44615097565b1480613b6157506001826006811115613b5f57613b5f615097565b145b15613d625760008e815260076020526040812055613b7f818561534e565b336000908152600b602052604081208054909190613bac9084906bffffffffffffffffffffffff1661534e565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508660e0015168ffffffffffffffffff16600c60008282829054906101000a90046bffffffffffffffffffffffff16613c12919061534e565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508660c0015168ffffffffffffffffff16600b6000613c5c613ed4565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160009081208054909190613ca29084906bffffffffffffffffffffffff1661534e565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508d7f08a4a0761e3c98d288cb4af9342660f49550d83139fb3b762b70d34bed6273688487848b60e0015160008d60c00151604051613d59969594939291906bffffffffffffffffffffffff9687168152602081019590955292909416604084015268ffffffffffffffffff9081166060840152928316608083015290911660a082015260c00190565b60405180910390a25b509c9b505050505050505050505050565b600046613d7f81613f45565b15613dfb57606c73ffffffffffffffffffffffffffffffffffffffff1663c6f7de0e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613dd0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613df491906157dd565b9392505050565b613e0481613f68565b15613eac5773420000000000000000000000000000000000000f73ffffffffffffffffffffffffffffffffffffffff166349948e0e8460405180608001604052806048815260200161584360489139604051602001613e649291906157f6565b6040516020818303038152906040526040518263ffffffff1660e01b8152600401613e8f91906140c0565b602060405180830381865afa158015613dd0573d6000803e3d6000fd5b50600092915050565b600061069a613ec261286a565b612b3184670de0b6b3a76400006150ea565b60003073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613f21573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129ce9190615825565b600061a4b1821480613f59575062066eed82145b8061069a57505062066eee1490565b6000600a821480613f7a57506101a482145b80613f87575062aa37dc82145b80613f93575061210582145b80613fa0575062014a3382145b8061069a57505062014a341490565b604051806103e00160405280601f906020820280368337509192915050565b60008083601f840112613fe057600080fd5b50813567ffffffffffffffff811115613ff857600080fd5b6020830191508360208285010111156132cf57600080fd5b6000806020838503121561402357600080fd5b823567ffffffffffffffff81111561403a57600080fd5b61404685828601613fce565b90969095509350505050565b60005b8381101561406d578181015183820152602001614055565b50506000910152565b6000815180845261408e816020860160208601614052565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000613df46020830184614076565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610180810167ffffffffffffffff81118282101715614126576141266140d3565b60405290565b604051610160810167ffffffffffffffff81118282101715614126576141266140d3565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614197576141976140d3565b604052919050565b600082601f8301126141b057600080fd5b813567ffffffffffffffff8111156141ca576141ca6140d3565b6141fb60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614150565b81815284602083860101111561421057600080fd5b816020850160208301376000918101602001919091529392505050565b60006020828403121561423f57600080fd5b813567ffffffffffffffff81111561425657600080fd5b612b408482850161419f565b73ffffffffffffffffffffffffffffffffffffffff811681146129e457600080fd5b803561124281614262565b6bffffffffffffffffffffffff811681146129e457600080fd5b80356112428161428f565b600080604083850312156142c757600080fd5b82356142d281614262565b915060208301356142e28161428f565b809150509250929050565b600081518084526020808501945080840160005b8381101561433357815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101614301565b509495945050505050565b602081526000613df460208301846142ed565b60006020828403121561436357600080fd5b5035919050565b60006020828403121561437c57600080fd5b813567ffffffffffffffff81111561439357600080fd5b82016101608185031215613df457600080fd5b8051825260208101516143d1602084018273ffffffffffffffffffffffffffffffffffffffff169052565b5060408101516143f160408401826bffffffffffffffffffffffff169052565b506060810151614419606084018273ffffffffffffffffffffffffffffffffffffffff169052565b506080810151614435608084018267ffffffffffffffff169052565b5060a081015161444d60a084018263ffffffff169052565b5060c081015161446a60c084018268ffffffffffffffffff169052565b5060e081015161448760e084018268ffffffffffffffffff169052565b506101008181015164ffffffffff9081169184019190915261012080830151909116908301526101409081015163ffffffff16910152565b610160810161069a82846143a6565b60008083601f8401126144e057600080fd5b50813567ffffffffffffffff8111156144f857600080fd5b6020830191508360208260051b85010111156132cf57600080fd5b60008060008060008060008060e0898b03121561452f57600080fd5b606089018a81111561454057600080fd5b8998503567ffffffffffffffff8082111561455a57600080fd5b6145668c838d01613fce565b909950975060808b013591508082111561457f57600080fd5b61458b8c838d016144ce565b909750955060a08b01359150808211156145a457600080fd5b506145b18b828c016144ce565b999c989b50969995989497949560c00135949350505050565b63ffffffff811681146129e457600080fd5b8035611242816145ca565b64ffffffffff811681146129e457600080fd5b8035611242816145e7565b803561ffff8116811461124257600080fd5b67ffffffffffffffff811681146129e457600080fd5b803561124281614617565b60ff811681146129e457600080fd5b803561124281614638565b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116811461124257600080fd5b6000610180828403121561469157600080fd5b614699614102565b6146a2836145dc565b81526146b0602084016145dc565b60208201526146c1604084016145dc565b60408201526146d2606084016145dc565b60608201526146e3608084016145fa565b60808201526146f460a08401614605565b60a082015261470560c0840161462d565b60c082015261471660e08401614647565b60e0820152610100614729818501614652565b9082015261012061473b8482016145dc565b9082015261014061474d848201614605565b9082015261016061475f848201614605565b908201529392505050565b815163ffffffff16815261018081016020830151614790602084018263ffffffff169052565b5060408301516147a8604084018263ffffffff169052565b5060608301516147c0606084018263ffffffff169052565b5060808301516147d9608084018264ffffffffff169052565b5060a08301516147ef60a084018261ffff169052565b5060c083015161480b60c084018267ffffffffffffffff169052565b5060e083015161482060e084018260ff169052565b50610100838101517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16908301526101208084015163ffffffff16908301526101408084015161ffff908116918401919091526101608085015191821681850152905b505092915050565b60008060008060006080868803121561489f57600080fd5b85356148aa81614617565b9450602086013567ffffffffffffffff8111156148c657600080fd5b6148d288828901613fce565b90955093505060408601356148e6816145ca565b949793965091946060013592915050565b600067ffffffffffffffff821115614911576149116140d3565b5060051b60200190565b600082601f83011261492c57600080fd5b8135602061494161493c836148f7565b614150565b82815260059290921b8401810191818101908684111561496057600080fd5b8286015b8481101561498457803561497781614262565b8352918301918301614964565b509695505050505050565b60008060008060008060c087890312156149a857600080fd5b863567ffffffffffffffff808211156149c057600080fd5b6149cc8a838b0161491b565b975060208901359150808211156149e257600080fd5b6149ee8a838b0161491b565b96506149fc60408a01614647565b95506060890135915080821115614a1257600080fd5b614a1e8a838b0161419f565b9450614a2c60808a0161462d565b935060a0890135915080821115614a4257600080fd5b50614a4f89828a0161419f565b9150509295509295509295565b600060208284031215614a6e57600080fd5b8135613df481614262565b600181811c90821680614a8d57607f821691505b6020821081036129a8577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b601f82111561065e57600081815260208120601f850160051c81016020861015614aed5750805b601f850160051c820191505b8181101561085157828155600101614af9565b67ffffffffffffffff831115614b2457614b246140d3565b614b3883614b328354614a79565b83614ac6565b6000601f841160018114614b8a5760008515614b545750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355614c20565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015614bd95786850135825560209485019460019092019101614bb9565b5086821015614c14577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006bffffffffffffffffffffffff80841680614ca457614ca4614c27565b92169190910492915050565b6bffffffffffffffffffffffff828116828216039080821115614cd557614cd5614c56565b5092915050565b805169ffffffffffffffffffff8116811461124257600080fd5b600080600080600060a08688031215614d0e57600080fd5b614d1786614cdc565b9450602086015193506040860151925060608601519150614d3a60808701614cdc565b90509295509295909350565b8181038181111561069a5761069a614c56565b600060208284031215614d6b57600080fd5b8151613df481614638565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614dd657614dd6614c56565b5060010190565b68ffffffffffffffffff811681146129e457600080fd5b803561124281614ddd565b60006101608236031215614e1257600080fd5b614e1a61412c565b823567ffffffffffffffff811115614e3157600080fd5b614e3d3682860161419f565b82525060208301356020820152614e5660408401614284565b6040820152614e67606084016142a9565b6060820152614e7860808401614df4565b6080820152614e8960a0840161462d565b60a0820152614e9a60c0840161462d565b60c0820152614eab60e084016145dc565b60e0820152610100614ebe818501614605565b90820152610120614ed084820161462d565b90820152610140614ee2848201614284565b9082015292915050565b600060208284031215614efe57600080fd5b8135613df481614617565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112614f3e57600080fd5b83018035915067ffffffffffffffff821115614f5957600080fd5b6020019150368190038213156132cf57600080fd5b600060208284031215614f8057600080fd5b613df482614605565b600060208284031215614f9b57600080fd5b8135613df4816145ca565b73ffffffffffffffffffffffffffffffffffffffff8a8116825267ffffffffffffffff8a166020830152881660408201526102406060820181905281018690526000610260878982850137600083890182015261ffff8716608084015260a0830186905263ffffffff851660c0840152601f88017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016830101905061504e60e08301846143a6565b9a9950505050505050505050565b60ff818116838216019081111561069a5761069a614c56565b600060ff83168061508857615088614c27565b8060ff84160491505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8183823760009101908152919050565b828152606082602083013760800192915050565b808202811582820484141761069a5761069a614c56565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b63ffffffff818116838216019080821115614cd557614cd5614c56565b600061012063ffffffff808d1684528b6020850152808b1660408501525080606084015261517d8184018a6142ed565b9050828103608084015261519181896142ed565b905060ff871660a084015282810360c08401526151ae8187614076565b905067ffffffffffffffff851660e08401528281036101008401526151d38185614076565b9c9b505050505050505050505050565b805161124281614ddd565b60006020828403121561520057600080fd5b8151613df481614ddd565b600181815b8085111561526457817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561524a5761524a614c56565b8085161561525757918102915b93841c9390800290615210565b509250929050565b60008261527b5750600161069a565b816152885750600061069a565b816001811461529e57600281146152a8576152c4565b600191505061069a565b60ff8411156152b9576152b9614c56565b50506001821b61069a565b5060208310610133831016604e8410600b84101617156152e7575081810a61069a565b6152f1838361520b565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561532357615323614c56565b029392505050565b6000613df460ff84168361526c565b60008261534957615349614c27565b500490565b6bffffffffffffffffffffffff818116838216019080821115614cd557614cd5614c56565b6bffffffffffffffffffffffff81811683821602808216919082811461487f5761487f614c56565b8082018082111561069a5761069a614c56565b67ffffffffffffffff818116838216019080821115614cd557614cd5614c56565b600082601f8301126153e057600080fd5b813560206153f061493c836148f7565b82815260059290921b8401810191818101908684111561540f57600080fd5b8286015b848110156149845780358352918301918301615413565b600082601f83011261543b57600080fd5b8135602061544b61493c836148f7565b82815260059290921b8401810191818101908684111561546a57600080fd5b8286015b8481101561498457803567ffffffffffffffff81111561548e5760008081fd5b61549c8986838b010161419f565b84525091830191830161546e565b600080600080600060a086880312156154c257600080fd5b853567ffffffffffffffff808211156154da57600080fd5b6154e689838a016153cf565b965060208801359150808211156154fc57600080fd5b61550889838a0161542a565b9550604088013591508082111561551e57600080fd5b61552a89838a0161542a565b9450606088013591508082111561554057600080fd5b61554c89838a0161542a565b9350608088013591508082111561556257600080fd5b5061556f8882890161542a565b9150509295509295909350565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b1660408501528160608501526155c38285018b6142ed565b915083820360808501526155d7828a6142ed565b915060ff881660a085015283820360c08501526155f48288614076565b90861660e085015283810361010085015290506151d38185614076565b805161124281614262565b80516112428161428f565b805161124281614617565b8051611242816145ca565b8051611242816145e7565b6000610160828403121561565b57600080fd5b61566361412c565b8251815261567360208401615611565b60208201526156846040840161561c565b604082015261569560608401615611565b60608201526156a660808401615627565b60808201526156b760a08401615632565b60a08201526156c860c084016151e3565b60c08201526156d960e084016151e3565b60e08201526101006156ec81850161563d565b908201526101206156fe84820161563d565b9082015261014061475f848201615632565b64ffffffffff818116838216019080821115614cd557614cd5614c56565b60006102008083526157428184018a614076565b905082810360208401526157568189614076565b6bffffffffffffffffffffffff88811660408601528716606085015273ffffffffffffffffffffffffffffffffffffffff86166080850152915061579f905060a08301846143a6565b979650505050505050565b600080604083850312156157bd57600080fd5b8251600781106157cc57600080fd5b60208401519092506142e28161428f565b6000602082840312156157ef57600080fd5b5051919050565b60008351615808818460208801614052565b83519083019061581c818360208801614052565b01949350505050565b60006020828403121561583757600080fd5b8151613df48161426256fe307866666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666a164736f6c6343000813000a", } var FunctionsCoordinatorABI = FunctionsCoordinatorMetaData.ABI var FunctionsCoordinatorBin = FunctionsCoordinatorMetaData.Bin -func DeployFunctionsCoordinator(auth *bind.TransactOpts, backend bind.ContractBackend, router common.Address, config FunctionsBillingConfig, linkToNativeFeed common.Address) (common.Address, *types.Transaction, *FunctionsCoordinator, error) { +func DeployFunctionsCoordinator(auth *bind.TransactOpts, backend bind.ContractBackend, router common.Address, config FunctionsBillingConfig, linkToNativeFeed common.Address, linkToUsdFeed common.Address) (common.Address, *types.Transaction, *FunctionsCoordinator, error) { parsed, err := FunctionsCoordinatorMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err @@ -88,7 +91,7 @@ func DeployFunctionsCoordinator(auth *bind.TransactOpts, backend bind.ContractBa return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(FunctionsCoordinatorBin), backend, router, config, linkToNativeFeed) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(FunctionsCoordinatorBin), backend, router, config, linkToNativeFeed, linkToUsdFeed) if err != nil { return common.Address{}, nil, nil, err } @@ -233,9 +236,9 @@ func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) EstimateCost(sub return _FunctionsCoordinator.Contract.EstimateCost(&_FunctionsCoordinator.CallOpts, subscriptionId, data, callbackGasLimit, gasPriceWei) } -func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetAdminFee(opts *bind.CallOpts) (*big.Int, error) { +func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetAdminFeeJuels(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _FunctionsCoordinator.contract.Call(opts, &out, "getAdminFee") + err := _FunctionsCoordinator.contract.Call(opts, &out, "getAdminFeeJuels") if err != nil { return *new(*big.Int), err @@ -247,12 +250,12 @@ func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetAdminFee(opts *bind. } -func (_FunctionsCoordinator *FunctionsCoordinatorSession) GetAdminFee() (*big.Int, error) { - return _FunctionsCoordinator.Contract.GetAdminFee(&_FunctionsCoordinator.CallOpts) +func (_FunctionsCoordinator *FunctionsCoordinatorSession) GetAdminFeeJuels() (*big.Int, error) { + return _FunctionsCoordinator.Contract.GetAdminFeeJuels(&_FunctionsCoordinator.CallOpts) } -func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) GetAdminFee() (*big.Int, error) { - return _FunctionsCoordinator.Contract.GetAdminFee(&_FunctionsCoordinator.CallOpts) +func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) GetAdminFeeJuels() (*big.Int, error) { + return _FunctionsCoordinator.Contract.GetAdminFeeJuels(&_FunctionsCoordinator.CallOpts) } func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetConfig(opts *bind.CallOpts) (FunctionsBillingConfig, error) { @@ -277,9 +280,9 @@ func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) GetConfig() (Fun return _FunctionsCoordinator.Contract.GetConfig(&_FunctionsCoordinator.CallOpts) } -func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetDONFee(opts *bind.CallOpts, arg0 []byte) (*big.Int, error) { +func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetDONFeeJuels(opts *bind.CallOpts, arg0 []byte) (*big.Int, error) { var out []interface{} - err := _FunctionsCoordinator.contract.Call(opts, &out, "getDONFee", arg0) + err := _FunctionsCoordinator.contract.Call(opts, &out, "getDONFeeJuels", arg0) if err != nil { return *new(*big.Int), err @@ -291,12 +294,12 @@ func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetDONFee(opts *bind.Ca } -func (_FunctionsCoordinator *FunctionsCoordinatorSession) GetDONFee(arg0 []byte) (*big.Int, error) { - return _FunctionsCoordinator.Contract.GetDONFee(&_FunctionsCoordinator.CallOpts, arg0) +func (_FunctionsCoordinator *FunctionsCoordinatorSession) GetDONFeeJuels(arg0 []byte) (*big.Int, error) { + return _FunctionsCoordinator.Contract.GetDONFeeJuels(&_FunctionsCoordinator.CallOpts, arg0) } -func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) GetDONFee(arg0 []byte) (*big.Int, error) { - return _FunctionsCoordinator.Contract.GetDONFee(&_FunctionsCoordinator.CallOpts, arg0) +func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) GetDONFeeJuels(arg0 []byte) (*big.Int, error) { + return _FunctionsCoordinator.Contract.GetDONFeeJuels(&_FunctionsCoordinator.CallOpts, arg0) } func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetDONPublicKey(opts *bind.CallOpts) ([]byte, error) { @@ -321,6 +324,28 @@ func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) GetDONPublicKey( return _FunctionsCoordinator.Contract.GetDONPublicKey(&_FunctionsCoordinator.CallOpts) } +func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetOperationFeeJuels(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _FunctionsCoordinator.contract.Call(opts, &out, "getOperationFeeJuels") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_FunctionsCoordinator *FunctionsCoordinatorSession) GetOperationFeeJuels() (*big.Int, error) { + return _FunctionsCoordinator.Contract.GetOperationFeeJuels(&_FunctionsCoordinator.CallOpts) +} + +func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) GetOperationFeeJuels() (*big.Int, error) { + return _FunctionsCoordinator.Contract.GetOperationFeeJuels(&_FunctionsCoordinator.CallOpts) +} + func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetThresholdPublicKey(opts *bind.CallOpts) ([]byte, error) { var out []interface{} err := _FunctionsCoordinator.contract.Call(opts, &out, "getThresholdPublicKey") @@ -343,6 +368,29 @@ func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) GetThresholdPubl return _FunctionsCoordinator.Contract.GetThresholdPublicKey(&_FunctionsCoordinator.CallOpts) } +func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetUsdPerUnitLink(opts *bind.CallOpts) (*big.Int, uint8, error) { + var out []interface{} + err := _FunctionsCoordinator.contract.Call(opts, &out, "getUsdPerUnitLink") + + if err != nil { + return *new(*big.Int), *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + out1 := *abi.ConvertType(out[1], new(uint8)).(*uint8) + + return out0, out1, err + +} + +func (_FunctionsCoordinator *FunctionsCoordinatorSession) GetUsdPerUnitLink() (*big.Int, uint8, error) { + return _FunctionsCoordinator.Contract.GetUsdPerUnitLink(&_FunctionsCoordinator.CallOpts) +} + +func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) GetUsdPerUnitLink() (*big.Int, uint8, error) { + return _FunctionsCoordinator.Contract.GetUsdPerUnitLink(&_FunctionsCoordinator.CallOpts) +} + func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetWeiPerUnitLink(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} err := _FunctionsCoordinator.contract.Call(opts, &out, "getWeiPerUnitLink") @@ -1593,7 +1641,9 @@ type FunctionsCoordinatorRequestBilled struct { JuelsPerGas *big.Int L1FeeShareWei *big.Int CallbackCostJuels *big.Int - TotalCostJuels *big.Int + DonFeeJuels *big.Int + AdminFeeJuels *big.Int + OperationFeeJuels *big.Int Raw types.Log } @@ -1823,7 +1873,7 @@ func (FunctionsCoordinatorConfigSet) Topic() common.Hash { } func (FunctionsCoordinatorConfigUpdated) Topic() common.Hash { - return common.HexToHash("0x5f32d06f5e83eda3a68e0e964ef2e6af5cb613e8117aa103c2d6bca5f5184862") + return common.HexToHash("0x2e2c8535dcc25459d519f2300c114d2d2128bf6399722d04eca078461a3bf33a") } func (FunctionsCoordinatorOracleRequest) Topic() common.Hash { @@ -1843,7 +1893,7 @@ func (FunctionsCoordinatorOwnershipTransferred) Topic() common.Hash { } func (FunctionsCoordinatorRequestBilled) Topic() common.Hash { - return common.HexToHash("0x90815c2e624694e8010bffad2bcefaf96af282ef1bc2ebc0042d1b89a585e046") + return common.HexToHash("0x08a4a0761e3c98d288cb4af9342660f49550d83139fb3b762b70d34bed627368") } func (FunctionsCoordinatorTransmitted) Topic() common.Hash { @@ -1857,16 +1907,20 @@ func (_FunctionsCoordinator *FunctionsCoordinator) Address() common.Address { type FunctionsCoordinatorInterface interface { EstimateCost(opts *bind.CallOpts, subscriptionId uint64, data []byte, callbackGasLimit uint32, gasPriceWei *big.Int) (*big.Int, error) - GetAdminFee(opts *bind.CallOpts) (*big.Int, error) + GetAdminFeeJuels(opts *bind.CallOpts) (*big.Int, error) GetConfig(opts *bind.CallOpts) (FunctionsBillingConfig, error) - GetDONFee(opts *bind.CallOpts, arg0 []byte) (*big.Int, error) + GetDONFeeJuels(opts *bind.CallOpts, arg0 []byte) (*big.Int, error) GetDONPublicKey(opts *bind.CallOpts) ([]byte, error) + GetOperationFeeJuels(opts *bind.CallOpts) (*big.Int, error) + GetThresholdPublicKey(opts *bind.CallOpts) ([]byte, error) + GetUsdPerUnitLink(opts *bind.CallOpts) (*big.Int, uint8, error) + GetWeiPerUnitLink(opts *bind.CallOpts) (*big.Int, error) LatestConfigDetails(opts *bind.CallOpts) (LatestConfigDetails, diff --git a/core/gethwrappers/functions/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/functions/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 102e377859c..7f441a59284 100644 --- a/core/gethwrappers/functions/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/functions/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -4,7 +4,7 @@ functions_allow_list: ../../../contracts/solc/v0.8.19/functions/v1_X/TermsOfServ functions_billing_registry_events_mock: ../../../contracts/solc/v0.8.6/functions/v0_0_0/FunctionsBillingRegistryEventsMock.abi ../../../contracts/solc/v0.8.6/functions/v0_0_0/FunctionsBillingRegistryEventsMock.bin 50deeb883bd9c3729702be335c0388f9d8553bab4be5e26ecacac496a89e2b77 functions_client: ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsClient.abi ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsClient.bin 2368f537a04489c720a46733f8596c4fc88a31062ecfa966d05f25dd98608aca functions_client_example: ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsClientExample.abi ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsClientExample.bin abf32e69f268f40e8530eb8d8e96bf310b798a4c0049a58022d9d2fb527b601b -functions_coordinator: ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsCoordinator.abi ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsCoordinator.bin 9686bdf83a0ce09ad07e81f6af52889735ea5af5709ffd018bb7b75e5d284c5e +functions_coordinator: ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsCoordinator.abi ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsCoordinator.bin 292d4742d039a154ed7875a0167c9725e2a90674ad9a05f152377819bb991082 functions_load_test_client: ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsLoadTestClient.abi ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsLoadTestClient.bin c8dbbd5ebb34435800d6674700068837c3a252db60046a14b0e61e829db517de functions_oracle_events_mock: ../../../contracts/solc/v0.8.6/functions/v0_0_0/FunctionsOracleEventsMock.abi ../../../contracts/solc/v0.8.6/functions/v0_0_0/FunctionsOracleEventsMock.bin 3ca70f966f8fe751987f0ccb50bebb6aa5be77e4a9f835d1ae99e0e9bfb7d52c functions_router: ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsRouter.abi ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsRouter.bin 1f6d18f9e0846ad74b37a0a6acef5942ab73ace1e84307f201899f69e732e776 diff --git a/core/services/ocr2/plugins/functions/integration_tests/v1/internal/testutils.go b/core/services/ocr2/plugins/functions/integration_tests/v1/internal/testutils.go index 7f75717feba..3061d818bf1 100644 --- a/core/services/ocr2/plugins/functions/integration_tests/v1/internal/testutils.go +++ b/core/services/ocr2/plugins/functions/integration_tests/v1/internal/testutils.go @@ -186,6 +186,10 @@ func StartNewChainWithContracts(t *testing.T, nClients int) (*bind.TransactOpts, linkEthFeedAddr, _, _, err := mock_v3_aggregator_contract.DeployMockV3AggregatorContract(owner, b, 18, big.NewInt(5_000_000_000_000_000)) require.NoError(t, err) + // Deploy mock LINK/USD price feed + linkUsdFeedAddr, _, _, err := mock_v3_aggregator_contract.DeployMockV3AggregatorContract(owner, b, 18, big.NewInt(1_500_00_000)) + require.NoError(t, err) + // Deploy Router contract handleOracleFulfillmentSelectorSlice, err := hex.DecodeString("0ca76175") require.NoError(t, err) @@ -222,16 +226,19 @@ func StartNewChainWithContracts(t *testing.T, nClients int) (*bind.TransactOpts, GasOverheadBeforeCallback: uint32(325_000), GasOverheadAfterCallback: uint32(50_000), RequestTimeoutSeconds: uint32(300), - DonFee: big.NewInt(0), + DonFeeCentsUsd: uint16(0), MaxSupportedRequestDataVersion: uint16(1), FulfillmentGasPriceOverEstimationBP: uint32(1_000), FallbackNativePerUnitLink: big.NewInt(5_000_000_000_000_000), MinimumEstimateGasPriceWei: big.NewInt(1_000_000_000), + OperationFeeCentsUsd: uint16(0), + FallbackUsdPerUnitLink: uint64(1_400_000_000), + FallbackUsdPerUnitLinkDecimals: uint8(8), } require.NoError(t, err) - coordinatorAddress, _, coordinatorContract, err := functions_coordinator.DeployFunctionsCoordinator(owner, b, routerAddress, coordinatorConfig, linkEthFeedAddr) + coordinatorAddress, _, coordinatorContract, err := functions_coordinator.DeployFunctionsCoordinator(owner, b, routerAddress, coordinatorConfig, linkEthFeedAddr, linkUsdFeedAddr) require.NoError(t, err) - proposalAddress, _, proposalContract, err := functions_coordinator.DeployFunctionsCoordinator(owner, b, routerAddress, coordinatorConfig, linkEthFeedAddr) + proposalAddress, _, proposalContract, err := functions_coordinator.DeployFunctionsCoordinator(owner, b, routerAddress, coordinatorConfig, linkEthFeedAddr, linkUsdFeedAddr) require.NoError(t, err) // Deploy Client contracts