From 59cb265a920436c6d821b462d8a350df063c64d1 Mon Sep 17 00:00:00 2001 From: Anirudh Warrier <12178754+anirudhwarrier@users.noreply.github.com> Date: Fri, 6 Oct 2023 18:02:37 +0400 Subject: [PATCH 01/10] [AUTO-5283] Fix automation benchmark, on-demands tests (#10640) * Increase DB disk space for benchmark test Signed-off-by: anirudhwarrier * update ondemand tests and benchmark test workflows Signed-off-by: anirudhwarrier * add keepers-team codeowners ondemand tests benchmark test workflows Signed-off-by: anirudhwarrier * update P2Pv2Bootstrapper - service name change in helm chart --------- Signed-off-by: anirudhwarrier Co-authored-by: anirudhwarrier --- .github/workflows/automation-benchmark-tests.yml | 2 +- .github/workflows/automation-ondemand-tests.yml | 15 +++++++++++++-- CODEOWNERS | 2 ++ .../actions/automation_ocr_helpers.go | 3 ++- integration-tests/benchmark/keeper_test.go | 4 ++-- 5 files changed, 20 insertions(+), 6 deletions(-) diff --git a/.github/workflows/automation-benchmark-tests.yml b/.github/workflows/automation-benchmark-tests.yml index 3eb44ea9c65..dc5f538f4ba 100644 --- a/.github/workflows/automation-benchmark-tests.yml +++ b/.github/workflows/automation-benchmark-tests.yml @@ -6,7 +6,7 @@ on: description: Chainlink image version to use required: true type: string - default: 2.0.0 + default: 2.5.0 chainlinkImage: description: Chainlink image repo to use required: true diff --git a/.github/workflows/automation-ondemand-tests.yml b/.github/workflows/automation-ondemand-tests.yml index 438264e222d..71cd08eaf45 100644 --- a/.github/workflows/automation-ondemand-tests.yml +++ b/.github/workflows/automation-ondemand-tests.yml @@ -10,6 +10,16 @@ on: description: Chainlink image repo to use (Leave empty to build from head/ref) required: false type: string + chainlinkVersionUpdate: + description: Chainlink image version to use initially for upgrade test + default: latest + required: true + type: string + chainlinkImageUpdate: + description: Chainlink image repo to use initially for upgrade test + required: true + default: public.ecr.aws/chainlink/chainlink + type: string env: ENV_JOB_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink-tests:${{ github.sha }} @@ -156,8 +166,8 @@ jobs: echo "upgrade_version=${{ inputs.chainlinkVersion }}" >>$GITHUB_OUTPUT fi if [[ "${{ matrix.tests.name }}" == "upgrade" ]]; then - echo "image=${{ env.CHAINLINK_IMAGE }}" >>$GITHUB_OUTPUT - echo "version=develop" >>$GITHUB_OUTPUT + echo "image=${{ inputs.chainlinkImageUpdate }}" >>$GITHUB_OUTPUT + echo "version=${{ inputs.chainlinkVersionUpdate }}" >>$GITHUB_OUTPUT fi - name: Run Tests uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@eccde1970eca69f079d3efb3409938a72ade8497 # v2.2.13 @@ -174,6 +184,7 @@ jobs: test_download_vendor_packages_command: cd ./integration-tests && go mod download cl_repo: ${{ steps.determine-build.outputs.image }} cl_image_tag: ${{ steps.determine-build.outputs.version }} + aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} artifacts_location: ./integration-tests/${{ matrix.tests.suite }}/logs publish_check_name: Automation On Demand Results ${{ matrix.tests.name }} token: ${{ secrets.GITHUB_TOKEN }} diff --git a/CODEOWNERS b/CODEOWNERS index 2b2fb18443a..e922010aefd 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -86,6 +86,8 @@ contracts/test/v0.8/functions @smartcontractkit/functions /.github/workflows/integration-chaos-tests.yml @smartcontractkit/test-tooling-team /.github/workflows/integration-tests-publish.yml @smartcontractkit/test-tooling-team /.github/workflows/performance-tests.yml @smartcontractkit/test-tooling-team +/.github/workflows/automation-ondemand-tests.yml @smartcontractkit/keepers +/.github/workflows/automation-benchmark-tests.yml @smartcontractkit/keepers /core/chainlink.Dockerfile @smartcontractkit/prodsec-public diff --git a/integration-tests/actions/automation_ocr_helpers.go b/integration-tests/actions/automation_ocr_helpers.go index 26bf2ac75ed..473ffc2bfca 100644 --- a/integration-tests/actions/automation_ocr_helpers.go +++ b/integration-tests/actions/automation_ocr_helpers.go @@ -201,7 +201,8 @@ func CreateOCRKeeperJobs( } _, err = bootstrapNode.MustCreateJob(bootstrapSpec) require.NoError(t, err, "Shouldn't fail creating bootstrap job on bootstrap node") - P2Pv2Bootstrapper := fmt.Sprintf("%s@%s:%d", bootstrapP2PId, bootstrapNode.Name(), 6690) + // TODO: Use service name returned by chainlink-env once that is available + P2Pv2Bootstrapper := fmt.Sprintf("%s@%s-node-1:%d", bootstrapP2PId, bootstrapNode.Name(), 6690) for nodeIndex := 1; nodeIndex < len(chainlinkNodes); nodeIndex++ { nodeTransmitterAddress, err := chainlinkNodes[nodeIndex].EthAddresses() diff --git a/integration-tests/benchmark/keeper_test.go b/integration-tests/benchmark/keeper_test.go index e016a72576d..0563cf4e097 100644 --- a/integration-tests/benchmark/keeper_test.go +++ b/integration-tests/benchmark/keeper_test.go @@ -81,7 +81,7 @@ LimitDefault = 5_000_000` }, }, "stateful": true, - "capacity": "1Gi", + "capacity": "10Gi", } soakChainlinkResources = map[string]interface{}{ @@ -108,7 +108,7 @@ LimitDefault = 5_000_000` }, }, "stateful": true, - "capacity": "1Gi", + "capacity": "10Gi", } ) From 961cc04bdae4ab19cd2b13e17e7d10c9bf01506f Mon Sep 17 00:00:00 2001 From: Jim W Date: Fri, 6 Oct 2023 11:09:57 -0400 Subject: [PATCH 02/10] switch some exp pkg usage to stable (#10876) * change maps pkg from exp to stable where applicable * replace exp_rand with crypto_rand --- core/internal/features/ocr2/features_ocr2_test.go | 2 +- core/services/blockhashstore/test_util.go | 2 +- core/services/chainlink/config_general_test.go | 3 +-- core/services/ocr2/plugins/s4/integration_test.go | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/core/internal/features/ocr2/features_ocr2_test.go b/core/internal/features/ocr2/features_ocr2_test.go index 3883e0319ed..0a6192c99c3 100644 --- a/core/internal/features/ocr2/features_ocr2_test.go +++ b/core/internal/features/ocr2/features_ocr2_test.go @@ -5,6 +5,7 @@ import ( "encoding/json" "fmt" "io" + "maps" "math/big" "net/http" "net/http/httptest" @@ -26,7 +27,6 @@ import ( "github.com/smartcontractkit/libocr/gethwrappers2/ocr2aggregator" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "golang.org/x/exp/maps" testoffchainaggregator2 "github.com/smartcontractkit/libocr/gethwrappers2/testocr2aggregator" confighelper2 "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" diff --git a/core/services/blockhashstore/test_util.go b/core/services/blockhashstore/test_util.go index 6b7c3836650..0ab07931295 100644 --- a/core/services/blockhashstore/test_util.go +++ b/core/services/blockhashstore/test_util.go @@ -2,11 +2,11 @@ package blockhashstore import ( "context" + "crypto/rand" "math/big" "github.com/ethereum/go-ethereum/common" "github.com/pkg/errors" - "golang.org/x/exp/rand" ) type TestCoordinator struct { diff --git a/core/services/chainlink/config_general_test.go b/core/services/chainlink/config_general_test.go index 8e95e389ffc..46931e53e2b 100644 --- a/core/services/chainlink/config_general_test.go +++ b/core/services/chainlink/config_general_test.go @@ -5,13 +5,12 @@ package chainlink import ( _ "embed" "fmt" + "maps" "net/url" "strings" "testing" "time" - maps "golang.org/x/exp/maps" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" diff --git a/core/services/ocr2/plugins/s4/integration_test.go b/core/services/ocr2/plugins/s4/integration_test.go index 01b269e2c85..98ccd312e4b 100644 --- a/core/services/ocr2/plugins/s4/integration_test.go +++ b/core/services/ocr2/plugins/s4/integration_test.go @@ -4,6 +4,7 @@ import ( "context" "crypto/ecdsa" "fmt" + "maps" "math/rand" "testing" "time" @@ -26,7 +27,6 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.uber.org/multierr" - "golang.org/x/exp/maps" ) // Disclaimer: this is not a true integration test, it's more of a S4 feature test, on purpose. From 064503ee4e425398878f8345b8da805b4bd5232c Mon Sep 17 00:00:00 2001 From: Makram Date: Fri, 6 Oct 2023 18:45:43 +0300 Subject: [PATCH 03/10] core/scripts/vrfv2plus: pk not required for deploy (#10874) The compressed vrf public key is not required to deploy the VRF universe. Move the code that parses it only if the associated CLI flag is set. --- .../vrfv2plus/testnet/super_scripts.go | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/core/scripts/vrfv2plus/testnet/super_scripts.go b/core/scripts/vrfv2plus/testnet/super_scripts.go index 3f18e18db9a..24a737be111 100644 --- a/core/scripts/vrfv2plus/testnet/super_scripts.go +++ b/core/scripts/vrfv2plus/testnet/super_scripts.go @@ -508,9 +508,7 @@ func deployUniverse(e helpers.Environment) { flatFeeLinkPPM := deployCmd.Int64("flat-fee-link-ppm", 500, "fulfillment flat fee LINK ppm") flatFeeEthPPM := deployCmd.Int64("flat-fee-eth-ppm", 500, "fulfillment flat fee ETH ppm") - helpers.ParseArgs( - deployCmd, os.Args[2:], "uncompressed-pub-key", "oracle-address", - ) + helpers.ParseArgs(deployCmd, os.Args[2:]) fallbackWeiPerUnitLink := decimal.RequireFromString(*fallbackWeiPerUnitLinkString).BigInt() subscriptionBalance := decimal.RequireFromString(*subscriptionBalanceString).BigInt() @@ -520,24 +518,6 @@ func deployUniverse(e helpers.Environment) { *registerKeyUncompressedPubKey = strings.Replace(*registerKeyUncompressedPubKey, "0x", "04", 1) } - // Generate compressed public key and key hash - pubBytes, err := hex.DecodeString(*registerKeyUncompressedPubKey) - helpers.PanicErr(err) - pk, err := crypto.UnmarshalPubkey(pubBytes) - helpers.PanicErr(err) - var pkBytes []byte - if big.NewInt(0).Mod(pk.Y, big.NewInt(2)).Uint64() != 0 { - pkBytes = append(pk.X.Bytes(), 1) - } else { - pkBytes = append(pk.X.Bytes(), 0) - } - var newPK secp256k1.PublicKey - copy(newPK[:], pkBytes) - - compressedPkHex := hexutil.Encode(pkBytes) - keyHash, err := newPK.Hash() - helpers.PanicErr(err) - if len(*linkAddress) == 0 { fmt.Println("\nDeploying LINK Token...") address := helpers.DeployLinkToken(e).String() @@ -594,7 +574,27 @@ func deployUniverse(e helpers.Environment) { fmt.Println("\nConfig set, getting current config from deployed contract...") printCoordinatorConfig(coordinator) + var compressedPkHex string + var keyHash common.Hash if len(*registerKeyUncompressedPubKey) > 0 && len(*registerKeyOracleAddress) > 0 { + // Generate compressed public key and key hash + pubBytes, err := hex.DecodeString(*registerKeyUncompressedPubKey) + helpers.PanicErr(err) + pk, err := crypto.UnmarshalPubkey(pubBytes) + helpers.PanicErr(err) + var pkBytes []byte + if big.NewInt(0).Mod(pk.Y, big.NewInt(2)).Uint64() != 0 { + pkBytes = append(pk.X.Bytes(), 1) + } else { + pkBytes = append(pk.X.Bytes(), 0) + } + var newPK secp256k1.PublicKey + copy(newPK[:], pkBytes) + + compressedPkHex = hexutil.Encode(pkBytes) + keyHash, err = newPK.Hash() + helpers.PanicErr(err) + fmt.Println("\nRegistering proving key...") registerCoordinatorProvingKey(e, *coordinator, *registerKeyUncompressedPubKey, *registerKeyOracleAddress) From 1e89a63b0eb568f11034c6e357ded1764632b00e Mon Sep 17 00:00:00 2001 From: Rens Rooimans Date: Fri, 6 Oct 2023 19:33:08 +0200 Subject: [PATCH 04/10] Enable Solhint (#10869) * enable solhint for /shared/ folder add others to ignore file add solhint to CICD * add chainlink-solidity ruleset * reduce ignore scope & fix interface folder issues * rm unused imports * clean /libraries * set no-unused-import to error * allow 968 warnings, the number we currently have * fix second layer imports * contracts/v0.8: fix solhint warnings for vrf contracts (#10875) * rm no-inline-assembly rule --------- Co-authored-by: Makram --- .github/workflows/solidity.yml | 2 + CODEOWNERS | 4 +- contracts/.solhint.json | 39 +++++++++++++++++- contracts/.solhintignore | 33 ++++++++++++++- contracts/package.json | 4 +- contracts/pnpm-lock.yaml | 9 ++++ contracts/scripts/native_solc_compile_all_vrf | 1 + contracts/src/v0.8/automation/KeeperBase.sol | 1 + .../src/v0.8/automation/KeeperCompatible.sol | 3 ++ .../interfaces/KeeperCompatibleInterface.sol | 1 + .../v1_2/KeeperRegistryInterface1_2.sol | 4 ++ .../automation/v1_3/KeeperRegistry1_3.sol | 2 +- .../automation/v1_3/KeeperRegistryBase1_3.sol | 2 +- .../automation/v2_0/KeeperRegistry2_0.sol | 2 +- .../automation/v2_0/KeeperRegistryBase2_0.sol | 1 - .../v2_0/KeeperRegistryLogic2_0.sol | 1 + .../automation/v2_1/AutomationUtils2_1.sol | 2 +- .../automation/v2_1/KeeperRegistry2_1.sol | 1 - .../automation/v2_1/KeeperRegistryBase2_1.sol | 2 +- .../automation/v2_1/UpkeepTranscoder4_0.sol | 1 - contracts/src/v0.8/dev/BlockhashStore.sol | 7 +++- .../v0.8/dev/VRFConsumerBaseV2Upgradeable.sol | 7 +++- .../dev/VRFSubscriptionBalanceMonitor.sol | 14 ++++--- .../dev/interfaces/IVRFCoordinatorV2Plus.sol | 4 +- .../IVRFCoordinatorV2PlusInternal.sol | 5 ++- .../dev/vrf/BatchVRFCoordinatorV2Plus.sol | 7 +++- contracts/src/v0.8/dev/vrf/BlockhashStore.sol | 7 +++- .../src/v0.8/dev/vrf/SubscriptionAPI.sol | 14 ++++--- .../v0.8/dev/vrf/TrustedBlockhashStore.sol | 6 +-- .../v0.8/dev/vrf/VRFConsumerBaseV2Plus.sol | 7 ++-- .../src/v0.8/dev/vrf/VRFCoordinatorV2_5.sol | 35 ++++++++++------ .../src/v0.8/dev/vrf/VRFV2PlusWrapper.sol | 41 +++++++++++++------ .../dev/vrf/VRFV2PlusWrapperConsumerBase.sol | 10 ++++- .../testhelpers/ExposedVRFCoordinatorV2_5.sol | 4 +- .../VRFConsumerV2PlusUpgradeableExample.sol | 13 ++++-- .../VRFCoordinatorV2PlusUpgradedVersion.sol | 36 ++++++++++------ .../VRFCoordinatorV2Plus_V2Example.sol | 9 ++-- .../VRFMaliciousConsumerV2Plus.sol | 19 +++++---- .../testhelpers/VRFV2PlusConsumerExample.sol | 16 ++++++-- .../VRFV2PlusExternalSubOwnerExample.sol | 17 +++++--- .../VRFV2PlusLoadTestWithMetrics.sol | 19 +++++---- .../VRFV2PlusMaliciousMigrator.sol | 10 ++--- .../testhelpers/VRFV2PlusRevertingExample.sol | 17 +++++--- .../VRFV2PlusSingleConsumerExample.sol | 17 +++++--- .../VRFV2PlusWrapperConsumerExample.sol | 8 +++- .../VRFV2PlusWrapperLoadTestConsumer.sol | 24 +++++++---- .../dev/v0_0_0/FunctionsBillingRegistry.sol | 1 - .../dev/v1_0_0/FunctionsCoordinator.sol | 1 - .../functions/dev/v1_0_0/FunctionsRouter.sol | 2 - .../dev/v1_0_0/FunctionsSubscriptions.sol | 3 -- .../v1_0_0/libraries/FunctionsResponse.sol | 2 - .../FunctionsBillingRegistryMigration.sol | 2 - .../FunctionsBillingRegistryOriginal.sol | 2 - .../interfaces/AggregatorV2V3Interface.sol | 4 +- .../v0.8/interfaces/FeedRegistryInterface.sol | 2 +- .../src/v0.8/interfaces/OperatorInterface.sol | 4 +- .../arbitrum/ArbitrumSequencerUptimeFeed.sol | 2 - .../optimism/OptimismSequencerUptimeFeed.sol | 1 - contracts/src/v0.8/libraries/ByteUtil.sol | 8 ++-- contracts/src/v0.8/libraries/Common.sol | 2 +- .../v0.8/libraries/test/ByteUtilTest.t.sol | 40 +++++++++--------- .../src/v0.8/llo-feeds/RewardManager.sol | 3 +- contracts/src/v0.8/llo-feeds/Verifier.sol | 2 +- .../test/fee-manager/BaseFeeManager.t.sol | 1 - .../test/fee-manager/FeeManager.general.t.sol | 3 -- .../FeeManager.getFeeAndReward.t.sol | 3 -- .../fee-manager/FeeManager.processFee.t.sol | 2 - .../FeeManager.processFeeBulk.t.sol | 3 -- .../llo-feeds/test/gas/Gas_VerifierTest.t.sol | 1 - .../RewardManager.general.t.sol | 1 - .../RewardManager.payRecipients.t.sol | 1 - .../RewardManager.setRecipients.t.sol | 1 - ...RewardManager.updateRewardRecipients.t.sol | 1 - .../verifier/VerifierActivateConfigTest.t.sol | 1 - .../verifier/VerifierDeactivateFeedTest.t.sol | 1 - .../VerifierProxyConstructorTest.t.sol | 1 - .../VerifierProxyInitializeVerifierTest.t.sol | 2 - .../VerifierProxySetVerifierTest.t.sol | 1 - .../test/verifier/VerifierProxyTest.t.sol | 4 -- .../VerifierProxyUnsetVerifierTest.t.sol | 1 - .../VerifierSetConfigFromSourceTest.t.sol | 2 - .../test/verifier/VerifierSetConfigTest.t.sol | 1 - .../test/verifier/VerifierTest.t.sol | 1 - .../verifier/VerifierTestBillingReport.t.sol | 3 -- .../verifier/VerifierUnsetConfigTest.t.sol | 3 +- .../src/v0.8/shared/access/ConfirmedOwner.sol | 2 +- .../access/ConfirmedOwnerWithProposal.sol | 6 ++- .../access/SimpleReadAccessController.sol | 3 +- .../access/SimpleWriteAccessController.sol | 17 ++++---- .../src/v0.8/shared/interfaces/IWERC20.sol | 2 +- .../src/v0.8/shared/mocks/WERC20Mock.sol | 7 ++-- .../src/v0.8/shared/ocr2/OCR2Abstract.sol | 3 ++ .../test/token/ERC677/BurnMintERC677.t.sol | 1 - .../token/ERC20/IOptimismMintableERC20.sol | 1 + .../shared/token/ERC677/BurnMintERC677.sol | 1 + .../src/v0.8/shared/token/ERC677/ERC677.sol | 2 +- .../src/v0.8/vrf/BatchBlockhashStore.sol | 6 ++- .../src/v0.8/vrf/BatchVRFCoordinatorV2.sol | 7 +++- contracts/src/v0.8/vrf/VRF.sol | 33 ++++++++++++++- contracts/src/v0.8/vrf/VRFConsumerBase.sol | 10 ++++- contracts/src/v0.8/vrf/VRFConsumerBaseV2.sol | 2 + contracts/src/v0.8/vrf/VRFCoordinatorV2.sol | 30 +++++++++----- contracts/src/v0.8/vrf/VRFOwner.sol | 7 +++- contracts/src/v0.8/vrf/VRFRequestIDBase.sol | 2 + contracts/src/v0.8/vrf/VRFV2Wrapper.sol | 40 ++++++++++++------ .../src/v0.8/vrf/VRFV2WrapperConsumerBase.sol | 9 +++- .../vrfv2plus_malicious_migrator.go | 16 ++++---- ...rapper-dependency-versions-do-not-edit.txt | 2 +- 108 files changed, 531 insertions(+), 285 deletions(-) diff --git a/.github/workflows/solidity.yml b/.github/workflows/solidity.yml index 0e7ff30545d..6e0233962ef 100644 --- a/.github/workflows/solidity.yml +++ b/.github/workflows/solidity.yml @@ -106,6 +106,8 @@ jobs: uses: ./.github/actions/setup-nodejs - name: Run pnpm lint run: pnpm lint + - name: Run solhint + run: pnpm solhint - name: Collect Metrics id: collect-gha-metrics uses: smartcontractkit/push-gha-metrics-action@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec diff --git a/CODEOWNERS b/CODEOWNERS index e922010aefd..c49affb8aab 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -67,12 +67,12 @@ core/scripts/gateway @bolekk @pinebit /operator-ui/ @DeividasK @jkongie # Contracts -/contracts/ @se3000 @connorwstein +/contracts/ @se3000 @connorwstein @RensR /contracts/**/*Keeper* @smartcontractkit/keepers /contracts/**/*Upkeep* @smartcontractkit/keepers /contracts/**/*Functions* @smartcontractkit/functions /contracts/src/v0.8/functions @smartcontractkit/functions -contracts/test/v0.8/functions @smartcontractkit/functions +/contracts/test/v0.8/functions @smartcontractkit/functions /contracts/src/v0.8/llo-feeds @austinborn @Fletch153 # Tests diff --git a/contracts/.solhint.json b/contracts/.solhint.json index ad3ab97846d..3b69ca6a7f2 100644 --- a/contracts/.solhint.json +++ b/contracts/.solhint.json @@ -1,7 +1,42 @@ { "extends": "solhint:recommended", - "plugins": ["prettier"], + "plugins": ["prettier", "chainlink-solidity"], "rules": { - "prettier/prettier": "error" + "compiler-version": ["off", "^0.8.0"], + "const-name-snakecase": "off", + "constructor-syntax": "error", + "var-name-mixedcase": "off", + "func-named-parameters": "off", + "immutable-vars-naming": "off", + "no-inline-assembly": "off", + "no-unused-import": "error", + "func-visibility": [ + "error", + { + "ignoreConstructors": true + } + ], + "not-rely-on-time": "off", + "prettier/prettier": [ + "off", + { + "endOfLine": "auto" + } + ], + "no-empty-blocks": "off", + "quotes": ["error", "double"], + "reason-string": [ + "warn", + { + "maxLength": 64 + } + ], + "chainlink-solidity/prefix-internal-functions-with-underscore": "warn", + "chainlink-solidity/prefix-private-functions-with-underscore": "warn", + "chainlink-solidity/prefix-storage-variables-with-s-underscore": "warn", + "chainlink-solidity/prefix-immutable-variables-with-i": "warn", + "chainlink-solidity/all-caps-constant-storage-variables": "warn", + "chainlink-solidity/no-hardhat-imports": "warn", + "chainlink-solidity/inherited-constructor-args-not-in-contract-definition": "warn" } } diff --git a/contracts/.solhintignore b/contracts/.solhintignore index c2658d7d1b3..88ad92c6b87 100644 --- a/contracts/.solhintignore +++ b/contracts/.solhintignore @@ -1 +1,32 @@ -node_modules/ +# 368 warnings +#./src/v0.8/automation +# 302 warnings +#./src/v0.8/dev +# 91 warnings +#./src/v0.8/functions +# 91 warnings +#./src/v0.8/l2ep/dev +# 116 warnings +#./src/v0.8/vrf + +# Temp ignore the following files as they contain issues. +./src/v0.8/ChainlinkClient.sol +./src/v0.8/Flags.sol +./src/v0.8/KeepersVRFConsumer.sol +./src/v0.8/PermissionedForwardProxy.sol +./src/v0.8/ValidatorProxy.sol +./src/v0.8/Chainlink.sol +./src/v0.8/ChainSpecificUtil.sol + + +# Ignore tests, this should not be the long term plan but is OK in the short term +./src/v0.8/**/*.t.sol +./src/v0.8/mocks +./src/v0.8/tests +./src/v0.8/llo-feeds/test +./src/v0.8/vrf/testhelpers +./src/v0.8/functions/tests + +# Always ignore vendor +./src/v0.8/vendor +./node_modules/ \ No newline at end of file diff --git a/contracts/package.json b/contracts/package.json index dbe47be5221..65cc873f34f 100644 --- a/contracts/package.json +++ b/contracts/package.json @@ -17,7 +17,8 @@ "coverage": "hardhat coverage", "prepublishOnly": "pnpm compile && ./scripts/prepublish_generate_abi_folder", "publish-beta": "pnpm publish --tag beta", - "publish-prod": "npm dist-tag add @chainlink/contracts@0.8.0 latest" + "publish-prod": "npm dist-tag add @chainlink/contracts@0.8.0 latest", + "solhint": "solhint --max-warnings 593 \"./src/v0.8/**/*.sol\"" }, "files": [ "src/", @@ -73,6 +74,7 @@ "prettier-plugin-solidity": "1.1.3", "rlp": "^2.2.7", "solhint": "^3.6.2", + "solhint-plugin-chainlink-solidity": "git+https://github.com/smartcontractkit/chainlink-solhint-rules.git", "solhint-plugin-prettier": "^0.0.5", "solidity-coverage": "^0.8.4", "ts-node": "^10.9.1", diff --git a/contracts/pnpm-lock.yaml b/contracts/pnpm-lock.yaml index b7179be4c60..33b8099a86d 100644 --- a/contracts/pnpm-lock.yaml +++ b/contracts/pnpm-lock.yaml @@ -148,6 +148,9 @@ devDependencies: solhint: specifier: ^3.6.2 version: 3.6.2 + solhint-plugin-chainlink-solidity: + specifier: git+https://github.com/smartcontractkit/chainlink-solhint-rules.git + version: github.com/smartcontractkit/chainlink-solhint-rules/6229ce5d3cc3e4a2454411bebc887c5ca240dcf2 solhint-plugin-prettier: specifier: ^0.0.5 version: 0.0.5(prettier-plugin-solidity@1.1.3)(prettier@3.0.3) @@ -12600,3 +12603,9 @@ packages: bn.js: 4.12.0 ethereumjs-util: 6.2.1 dev: true + + github.com/smartcontractkit/chainlink-solhint-rules/6229ce5d3cc3e4a2454411bebc887c5ca240dcf2: + resolution: {tarball: https://codeload.github.com/smartcontractkit/chainlink-solhint-rules/tar.gz/6229ce5d3cc3e4a2454411bebc887c5ca240dcf2} + name: '@chainlink/solhint-plugin-chainlink-solidity' + version: 1.0.1 + dev: true diff --git a/contracts/scripts/native_solc_compile_all_vrf b/contracts/scripts/native_solc_compile_all_vrf index 49666bde7f6..fd9f1b91539 100755 --- a/contracts/scripts/native_solc_compile_all_vrf +++ b/contracts/scripts/native_solc_compile_all_vrf @@ -54,6 +54,7 @@ compileContract vrf/testhelpers/VRFCoordinatorV2TestHelper.sol compileContractAltOpts vrf/VRFCoordinatorV2.sol 10000 compileContract mocks/VRFCoordinatorV2Mock.sol compileContract vrf/VRFOwner.sol +compileContract dev/VRFSubscriptionBalanceMonitor.sol # VRF V2Plus compileContract dev/interfaces/IVRFCoordinatorV2PlusInternal.sol diff --git a/contracts/src/v0.8/automation/KeeperBase.sol b/contracts/src/v0.8/automation/KeeperBase.sol index 448d4deacea..0e050d4aff3 100644 --- a/contracts/src/v0.8/automation/KeeperBase.sol +++ b/contracts/src/v0.8/automation/KeeperBase.sol @@ -3,4 +3,5 @@ * @notice This is a deprecated interface. Please use AutomationBase directly. */ pragma solidity ^0.8.0; +// solhint-disable-next-line no-unused-import import {AutomationBase as KeeperBase} from "./AutomationBase.sol"; diff --git a/contracts/src/v0.8/automation/KeeperCompatible.sol b/contracts/src/v0.8/automation/KeeperCompatible.sol index f5263eda7b9..6379fe526be 100644 --- a/contracts/src/v0.8/automation/KeeperCompatible.sol +++ b/contracts/src/v0.8/automation/KeeperCompatible.sol @@ -3,6 +3,9 @@ * @notice This is a deprecated interface. Please use AutomationCompatible directly. */ pragma solidity ^0.8.0; +// solhint-disable-next-line no-unused-import import {AutomationCompatible as KeeperCompatible} from "./AutomationCompatible.sol"; +// solhint-disable-next-line no-unused-import import {AutomationBase as KeeperBase} from "./AutomationBase.sol"; +// solhint-disable-next-line no-unused-import import {AutomationCompatibleInterface as KeeperCompatibleInterface} from "./interfaces/AutomationCompatibleInterface.sol"; diff --git a/contracts/src/v0.8/automation/interfaces/KeeperCompatibleInterface.sol b/contracts/src/v0.8/automation/interfaces/KeeperCompatibleInterface.sol index d316722313e..b5ba8196c74 100644 --- a/contracts/src/v0.8/automation/interfaces/KeeperCompatibleInterface.sol +++ b/contracts/src/v0.8/automation/interfaces/KeeperCompatibleInterface.sol @@ -3,4 +3,5 @@ * @notice This is a deprecated interface. Please use AutomationCompatibleInterface directly. */ pragma solidity ^0.8.0; +// solhint-disable-next-line no-unused-import import {AutomationCompatibleInterface as KeeperCompatibleInterface} from "./AutomationCompatibleInterface.sol"; diff --git a/contracts/src/v0.8/automation/interfaces/v1_2/KeeperRegistryInterface1_2.sol b/contracts/src/v0.8/automation/interfaces/v1_2/KeeperRegistryInterface1_2.sol index 124e279ab40..01f70ae9c7d 100644 --- a/contracts/src/v0.8/automation/interfaces/v1_2/KeeperRegistryInterface1_2.sol +++ b/contracts/src/v0.8/automation/interfaces/v1_2/KeeperRegistryInterface1_2.sol @@ -3,7 +3,11 @@ * @notice This is a deprecated interface. Please use AutomationRegistryInterface1_2 directly. */ pragma solidity ^0.8.0; +// solhint-disable-next-line no-unused-import import {Config, State} from "./AutomationRegistryInterface1_2.sol"; +// solhint-disable-next-line no-unused-import import {AutomationRegistryBaseInterface as KeeperRegistryBaseInterface} from "./AutomationRegistryInterface1_2.sol"; +// solhint-disable-next-line no-unused-import import {AutomationRegistryInterface as KeeperRegistryInterface} from "./AutomationRegistryInterface1_2.sol"; +// solhint-disable-next-line no-unused-import import {AutomationRegistryExecutableInterface as KeeperRegistryExecutableInterface} from "./AutomationRegistryInterface1_2.sol"; diff --git a/contracts/src/v0.8/automation/v1_3/KeeperRegistry1_3.sol b/contracts/src/v0.8/automation/v1_3/KeeperRegistry1_3.sol index c40f79f85b4..dbef8d77d19 100644 --- a/contracts/src/v0.8/automation/v1_3/KeeperRegistry1_3.sol +++ b/contracts/src/v0.8/automation/v1_3/KeeperRegistry1_3.sol @@ -6,7 +6,7 @@ import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; import "@openzeppelin/contracts/utils/Address.sol"; import "./KeeperRegistryBase1_3.sol"; import "./KeeperRegistryLogic1_3.sol"; -import {AutomationRegistryExecutableInterface} from "../interfaces/v1_3/AutomationRegistryInterface1_3.sol"; +import {AutomationRegistryExecutableInterface, State} from "../interfaces/v1_3/AutomationRegistryInterface1_3.sol"; import "../interfaces/MigratableKeeperRegistryInterface.sol"; import "../../interfaces/TypeAndVersionInterface.sol"; import "../../shared/interfaces/IERC677Receiver.sol"; diff --git a/contracts/src/v0.8/automation/v1_3/KeeperRegistryBase1_3.sol b/contracts/src/v0.8/automation/v1_3/KeeperRegistryBase1_3.sol index d63f6f40e88..6328b651671 100644 --- a/contracts/src/v0.8/automation/v1_3/KeeperRegistryBase1_3.sol +++ b/contracts/src/v0.8/automation/v1_3/KeeperRegistryBase1_3.sol @@ -6,7 +6,7 @@ import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; import "../../vendor/@arbitrum/nitro-contracts/src/precompiles/ArbGasInfo.sol"; import "../../vendor/@eth-optimism/contracts/v0.8.6/contracts/L2/predeploys/OVM_GasPriceOracle.sol"; import "../ExecutionPrevention.sol"; -import {Config, State, Upkeep} from "../interfaces/v1_3/AutomationRegistryInterface1_3.sol"; +import {Config, Upkeep} from "../interfaces/v1_3/AutomationRegistryInterface1_3.sol"; import "../../shared/access/ConfirmedOwner.sol"; import "../../interfaces/AggregatorV3Interface.sol"; import "../../shared/interfaces/LinkTokenInterface.sol"; diff --git a/contracts/src/v0.8/automation/v2_0/KeeperRegistry2_0.sol b/contracts/src/v0.8/automation/v2_0/KeeperRegistry2_0.sol index 34781f18258..7db02e72e73 100644 --- a/contracts/src/v0.8/automation/v2_0/KeeperRegistry2_0.sol +++ b/contracts/src/v0.8/automation/v2_0/KeeperRegistry2_0.sol @@ -5,7 +5,7 @@ import "../../vendor/openzeppelin-solidity/v4.7.3/contracts/proxy/Proxy.sol"; import "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol"; import "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol"; import "./KeeperRegistryBase2_0.sol"; -import {AutomationRegistryExecutableInterface, UpkeepInfo} from "../interfaces/v2_0/AutomationRegistryInterface2_0.sol"; +import {AutomationRegistryExecutableInterface, UpkeepInfo, State, OnchainConfig, UpkeepFailureReason} from "../interfaces/v2_0/AutomationRegistryInterface2_0.sol"; import "../interfaces/MigratableKeeperRegistryInterface.sol"; import "../interfaces/MigratableKeeperRegistryInterfaceV2.sol"; import "../../shared/interfaces/IERC677Receiver.sol"; diff --git a/contracts/src/v0.8/automation/v2_0/KeeperRegistryBase2_0.sol b/contracts/src/v0.8/automation/v2_0/KeeperRegistryBase2_0.sol index c1e9a279f84..14e9b204475 100644 --- a/contracts/src/v0.8/automation/v2_0/KeeperRegistryBase2_0.sol +++ b/contracts/src/v0.8/automation/v2_0/KeeperRegistryBase2_0.sol @@ -6,7 +6,6 @@ import "../../vendor/@arbitrum/nitro-contracts/src/precompiles/ArbGasInfo.sol"; import "../../vendor/@eth-optimism/contracts/v0.8.6/contracts/L2/predeploys/OVM_GasPriceOracle.sol"; import {ArbSys} from "../../vendor/@arbitrum/nitro-contracts/src/precompiles/ArbSys.sol"; import "../ExecutionPrevention.sol"; -import {OnchainConfig, State, UpkeepFailureReason} from "../interfaces/v2_0/AutomationRegistryInterface2_0.sol"; import "../../shared/access/ConfirmedOwner.sol"; import "../../interfaces/AggregatorV3Interface.sol"; import "../../shared/interfaces/LinkTokenInterface.sol"; diff --git a/contracts/src/v0.8/automation/v2_0/KeeperRegistryLogic2_0.sol b/contracts/src/v0.8/automation/v2_0/KeeperRegistryLogic2_0.sol index 7e6134a178f..7eacc3cb61e 100644 --- a/contracts/src/v0.8/automation/v2_0/KeeperRegistryLogic2_0.sol +++ b/contracts/src/v0.8/automation/v2_0/KeeperRegistryLogic2_0.sol @@ -4,6 +4,7 @@ pragma solidity 0.8.6; import "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol"; import "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol"; import "./KeeperRegistryBase2_0.sol"; +import {UpkeepFailureReason} from "../interfaces/v2_0/AutomationRegistryInterface2_0.sol"; import "../interfaces/MigratableKeeperRegistryInterfaceV2.sol"; import "../interfaces/UpkeepTranscoderInterfaceV2.sol"; diff --git a/contracts/src/v0.8/automation/v2_1/AutomationUtils2_1.sol b/contracts/src/v0.8/automation/v2_1/AutomationUtils2_1.sol index ed19b450d8b..f6ba913b2fb 100644 --- a/contracts/src/v0.8/automation/v2_1/AutomationUtils2_1.sol +++ b/contracts/src/v0.8/automation/v2_1/AutomationUtils2_1.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.16; import {KeeperRegistryBase2_1} from "./KeeperRegistryBase2_1.sol"; -import {ILogAutomation, Log} from "../interfaces/ILogAutomation.sol"; +import {Log} from "../interfaces/ILogAutomation.sol"; /** * @notice this file exposes structs that are otherwise internal to the automation registry diff --git a/contracts/src/v0.8/automation/v2_1/KeeperRegistry2_1.sol b/contracts/src/v0.8/automation/v2_1/KeeperRegistry2_1.sol index bb287c3c731..2f96df6d572 100644 --- a/contracts/src/v0.8/automation/v2_1/KeeperRegistry2_1.sol +++ b/contracts/src/v0.8/automation/v2_1/KeeperRegistry2_1.sol @@ -3,7 +3,6 @@ pragma solidity 0.8.16; import {EnumerableSet} from "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol"; import {Address} from "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol"; -import {Proxy} from "../../vendor/openzeppelin-solidity/v4.7.3/contracts/proxy/Proxy.sol"; import {KeeperRegistryBase2_1} from "./KeeperRegistryBase2_1.sol"; import {KeeperRegistryLogicB2_1} from "./KeeperRegistryLogicB2_1.sol"; import {Chainable} from "../Chainable.sol"; diff --git a/contracts/src/v0.8/automation/v2_1/KeeperRegistryBase2_1.sol b/contracts/src/v0.8/automation/v2_1/KeeperRegistryBase2_1.sol index 86942f3108d..f5d89de5467 100644 --- a/contracts/src/v0.8/automation/v2_1/KeeperRegistryBase2_1.sol +++ b/contracts/src/v0.8/automation/v2_1/KeeperRegistryBase2_1.sol @@ -14,7 +14,7 @@ import {ConfirmedOwner} from "../../shared/access/ConfirmedOwner.sol"; import {AggregatorV3Interface} from "../../interfaces/AggregatorV3Interface.sol"; import {LinkTokenInterface} from "../../shared/interfaces/LinkTokenInterface.sol"; import {KeeperCompatibleInterface} from "../interfaces/KeeperCompatibleInterface.sol"; -import {UpkeepTranscoderInterface, UpkeepFormat} from "../interfaces/UpkeepTranscoderInterface.sol"; +import {UpkeepFormat} from "../interfaces/UpkeepTranscoderInterface.sol"; /** * @notice Base Keeper Registry contract, contains shared logic between diff --git a/contracts/src/v0.8/automation/v2_1/UpkeepTranscoder4_0.sol b/contracts/src/v0.8/automation/v2_1/UpkeepTranscoder4_0.sol index 727a3dd33ad..53b681d4cc1 100644 --- a/contracts/src/v0.8/automation/v2_1/UpkeepTranscoder4_0.sol +++ b/contracts/src/v0.8/automation/v2_1/UpkeepTranscoder4_0.sol @@ -6,7 +6,6 @@ import {UpkeepTranscoderInterfaceV2} from "../interfaces/UpkeepTranscoderInterfa import {TypeAndVersionInterface} from "../../interfaces/TypeAndVersionInterface.sol"; import {KeeperRegistryBase2_1 as R21} from "./KeeperRegistryBase2_1.sol"; import {IAutomationForwarder} from "../interfaces/IAutomationForwarder.sol"; -import {AutomationRegistryBaseInterface, UpkeepInfo} from "../interfaces/v2_0/AutomationRegistryInterface2_0.sol"; enum RegistryVersion { V12, diff --git a/contracts/src/v0.8/dev/BlockhashStore.sol b/contracts/src/v0.8/dev/BlockhashStore.sol index 74a4fc0ce47..4104be77ed7 100644 --- a/contracts/src/v0.8/dev/BlockhashStore.sol +++ b/contracts/src/v0.8/dev/BlockhashStore.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.6; -import "../ChainSpecificUtil.sol"; +import {ChainSpecificUtil} from "../ChainSpecificUtil.sol"; /** * @title BlockhashStore @@ -14,7 +14,7 @@ import "../ChainSpecificUtil.sol"; * would have to be deployed. */ contract BlockhashStore { - mapping(uint => bytes32) internal s_blockhashes; + mapping(uint256 => bytes32) internal s_blockhashes; /** * @notice stores blockhash of a given block, assuming it is available through BLOCKHASH @@ -22,6 +22,7 @@ contract BlockhashStore { */ function store(uint256 n) public { bytes32 h = ChainSpecificUtil.getBlockhash(uint64(n)); + // solhint-disable-next-line custom-errors require(h != 0x0, "blockhash(n) failed"); s_blockhashes[n] = h; } @@ -40,6 +41,7 @@ contract BlockhashStore { * that it hashes to a stored blockhash, and then extract parentHash to get the n-th blockhash. */ function storeVerifyHeader(uint256 n, bytes memory header) public { + // solhint-disable-next-line custom-errors require(keccak256(header) == s_blockhashes[n + 1], "header has unknown blockhash"); // At this point, we know that header is the correct blockheader for block n+1. @@ -72,6 +74,7 @@ contract BlockhashStore { */ function getBlockhash(uint256 n) external view returns (bytes32) { bytes32 h = s_blockhashes[n]; + // solhint-disable-next-line custom-errors require(h != 0x0, "blockhash not found in store"); return h; } diff --git a/contracts/src/v0.8/dev/VRFConsumerBaseV2Upgradeable.sol b/contracts/src/v0.8/dev/VRFConsumerBaseV2Upgradeable.sol index b9666eb6a14..81840d26a3e 100644 --- a/contracts/src/v0.8/dev/VRFConsumerBaseV2Upgradeable.sol +++ b/contracts/src/v0.8/dev/VRFConsumerBaseV2Upgradeable.sol @@ -96,7 +96,7 @@ pragma solidity ^0.8.4; * @dev and so remains effective only in the case of unmodified oracle software). */ -import "@openzeppelin/contracts-upgradeable-4.7.3/proxy/utils/Initializable.sol"; +import {Initializable} from "@openzeppelin/contracts-upgradeable-4.7.3/proxy/utils/Initializable.sol"; /** * @dev The VRFConsumerBaseV2Upgradable is an upgradable variant of VRFConsumerBaseV2 @@ -106,10 +106,12 @@ import "@openzeppelin/contracts-upgradeable-4.7.3/proxy/utils/Initializable.sol" */ abstract contract VRFConsumerBaseV2Upgradeable is Initializable { error OnlyCoordinatorCanFulfill(address have, address want); + // solhint-disable-next-line chainlink-solidity/prefix-storage-variables-with-s-underscore address private vrfCoordinator; // See https://github.com/OpenZeppelin/openzeppelin-sdk/issues/37. // Each uint256 covers a single storage slot, see https://docs.soliditylang.org/en/latest/internals/layout_in_storage.html. + // solhint-disable-next-line chainlink-solidity/prefix-storage-variables-with-s-underscore uint256[49] private __gap; /** @@ -117,8 +119,10 @@ abstract contract VRFConsumerBaseV2Upgradeable is Initializable { * @dev See https://docs.chain.link/docs/vrf/v2/supported-networks/ for coordinator * @dev addresses on your preferred network. */ + // solhint-disable-next-line func-name-mixedcase function __VRFConsumerBaseV2_init(address _vrfCoordinator) internal onlyInitializing { if (_vrfCoordinator == address(0)) { + // solhint-disable-next-line custom-errors revert("must give valid coordinator address"); } @@ -139,6 +143,7 @@ abstract contract VRFConsumerBaseV2Upgradeable is Initializable { * @param requestId The Id initially returned by requestRandomness * @param randomWords the VRF output expanded to the requested number of words */ + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function fulfillRandomWords(uint256 requestId, uint256[] memory randomWords) internal virtual; // rawFulfillRandomness is called by VRFCoordinator when it receives a valid VRF diff --git a/contracts/src/v0.8/dev/VRFSubscriptionBalanceMonitor.sol b/contracts/src/v0.8/dev/VRFSubscriptionBalanceMonitor.sol index 91124709742..958ecdc1bad 100644 --- a/contracts/src/v0.8/dev/VRFSubscriptionBalanceMonitor.sol +++ b/contracts/src/v0.8/dev/VRFSubscriptionBalanceMonitor.sol @@ -2,11 +2,11 @@ pragma solidity 0.8.6; -import "../shared/access/ConfirmedOwner.sol"; -import "../automation/interfaces/KeeperCompatibleInterface.sol"; -import "../interfaces/VRFCoordinatorV2Interface.sol"; -import "../shared/interfaces/LinkTokenInterface.sol"; -import "@openzeppelin/contracts/security/Pausable.sol"; +import {ConfirmedOwner} from "../shared/access/ConfirmedOwner.sol"; +import {AutomationCompatibleInterface as KeeperCompatibleInterface} from "../automation/interfaces/AutomationCompatibleInterface.sol"; +import {VRFCoordinatorV2Interface} from "../interfaces/VRFCoordinatorV2Interface.sol"; +import {LinkTokenInterface} from "../shared/interfaces/LinkTokenInterface.sol"; +import {Pausable} from "@openzeppelin/contracts/security/Pausable.sol"; /** * @title The VRFSubscriptionBalanceMonitor contract. @@ -197,6 +197,7 @@ contract VRFSubscriptionBalanceMonitor is ConfirmedOwner, Pausable, KeeperCompat * @param payee the address to pay */ function withdraw(uint256 amount, address payable payee) external onlyOwner { + // solhint-disable-next-line custom-errors, reason-string require(payee != address(0)); emit FundsWithdrawn(amount, payee); LINKTOKEN.transfer(payee, amount); @@ -206,6 +207,7 @@ contract VRFSubscriptionBalanceMonitor is ConfirmedOwner, Pausable, KeeperCompat * @notice Sets the LINK token address. */ function setLinkTokenAddress(address linkTokenAddress) public onlyOwner { + // solhint-disable-next-line custom-errors, reason-string require(linkTokenAddress != address(0)); emit LinkTokenAddressUpdated(address(LINKTOKEN), linkTokenAddress); LINKTOKEN = LinkTokenInterface(linkTokenAddress); @@ -215,6 +217,7 @@ contract VRFSubscriptionBalanceMonitor is ConfirmedOwner, Pausable, KeeperCompat * @notice Sets the VRF coordinator address. */ function setVRFCoordinatorV2Address(address coordinatorAddress) public onlyOwner { + // solhint-disable-next-line custom-errors, reason-string require(coordinatorAddress != address(0)); emit VRFCoordinatorV2AddressUpdated(address(COORDINATOR), coordinatorAddress); COORDINATOR = VRFCoordinatorV2Interface(coordinatorAddress); @@ -224,6 +227,7 @@ contract VRFSubscriptionBalanceMonitor is ConfirmedOwner, Pausable, KeeperCompat * @notice Sets the keeper registry address. */ function setKeeperRegistryAddress(address keeperRegistryAddress) public onlyOwner { + // solhint-disable-next-line custom-errors, reason-string require(keeperRegistryAddress != address(0)); emit KeeperRegistryAddressUpdated(s_keeperRegistryAddress, keeperRegistryAddress); s_keeperRegistryAddress = keeperRegistryAddress; diff --git a/contracts/src/v0.8/dev/interfaces/IVRFCoordinatorV2Plus.sol b/contracts/src/v0.8/dev/interfaces/IVRFCoordinatorV2Plus.sol index 0608340e674..20c60b593da 100644 --- a/contracts/src/v0.8/dev/interfaces/IVRFCoordinatorV2Plus.sol +++ b/contracts/src/v0.8/dev/interfaces/IVRFCoordinatorV2Plus.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import "../vrf/libraries/VRFV2PlusClient.sol"; -import "./IVRFSubscriptionV2Plus.sol"; +import {VRFV2PlusClient} from "../vrf/libraries/VRFV2PlusClient.sol"; +import {IVRFSubscriptionV2Plus} from "./IVRFSubscriptionV2Plus.sol"; // Interface that enables consumers of VRFCoordinatorV2Plus to be future-proof for upgrades // This interface is supported by subsequent versions of VRFCoordinatorV2Plus diff --git a/contracts/src/v0.8/dev/interfaces/IVRFCoordinatorV2PlusInternal.sol b/contracts/src/v0.8/dev/interfaces/IVRFCoordinatorV2PlusInternal.sol index 9892b88e691..e8fba69fc45 100644 --- a/contracts/src/v0.8/dev/interfaces/IVRFCoordinatorV2PlusInternal.sol +++ b/contracts/src/v0.8/dev/interfaces/IVRFCoordinatorV2PlusInternal.sol @@ -1,6 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import "./IVRFCoordinatorV2Plus.sol"; + +import {IVRFCoordinatorV2Plus} from "./IVRFCoordinatorV2Plus.sol"; // IVRFCoordinatorV2PlusInternal is the interface used by chainlink core and should // not be used by consumer conracts @@ -51,9 +52,11 @@ interface IVRFCoordinatorV2PlusInternal is IVRFCoordinatorV2Plus { uint256 zInv; } + // solhint-disable-next-line func-name-mixedcase function s_requestCommitments(uint256 requestID) external view returns (bytes32); function fulfillRandomWords(Proof memory proof, RequestCommitment memory rc) external returns (uint96); + // solhint-disable-next-line func-name-mixedcase function LINK_NATIVE_FEED() external view returns (address); } diff --git a/contracts/src/v0.8/dev/vrf/BatchVRFCoordinatorV2Plus.sol b/contracts/src/v0.8/dev/vrf/BatchVRFCoordinatorV2Plus.sol index c08ac5dd0a4..9247cc21dd5 100644 --- a/contracts/src/v0.8/dev/vrf/BatchVRFCoordinatorV2Plus.sol +++ b/contracts/src/v0.8/dev/vrf/BatchVRFCoordinatorV2Plus.sol @@ -1,7 +1,8 @@ // SPDX-License-Identifier: MIT +// solhint-disable-next-line one-contract-per-file pragma solidity 0.8.6; -import "../../vrf/VRFTypes.sol"; +import {VRFTypes} from "../../vrf/VRFTypes.sol"; /** * @title BatchVRFCoordinatorV2Plus @@ -9,6 +10,7 @@ import "../../vrf/VRFTypes.sol"; * @notice provided VRFCoordinatorV2Plus contract efficiently in a single transaction. */ contract BatchVRFCoordinatorV2Plus { + // solhint-disable-next-line chainlink-solidity/prefix-immutable-variables-with-i IVRFCoordinatorV2Plus public immutable COORDINATOR; event ErrorReturned(uint256 indexed requestId, string reason); @@ -24,6 +26,7 @@ contract BatchVRFCoordinatorV2Plus { * @param rcs the request commitments corresponding to the randomness proofs. */ function fulfillRandomWords(VRFTypes.Proof[] memory proofs, VRFTypes.RequestCommitmentV2Plus[] memory rcs) external { + // solhint-disable-next-line custom-errors require(proofs.length == rcs.length, "input array arg lengths mismatch"); for (uint256 i = 0; i < proofs.length; i++) { try COORDINATOR.fulfillRandomWords(proofs[i], rcs[i]) returns (uint96 /* payment */) { @@ -42,6 +45,7 @@ contract BatchVRFCoordinatorV2Plus { * @notice Returns the proving key hash associated with this public key. * @param publicKey the key to return the hash of. */ + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function hashOfKey(uint256[2] memory publicKey) internal pure returns (bytes32) { return keccak256(abi.encode(publicKey)); } @@ -50,6 +54,7 @@ contract BatchVRFCoordinatorV2Plus { * @notice Returns the request ID of the request associated with the given proof. * @param proof the VRF proof provided by the VRF oracle. */ + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function getRequestIdFromProof(VRFTypes.Proof memory proof) internal pure returns (uint256) { bytes32 keyHash = hashOfKey(proof.pk); return uint256(keccak256(abi.encode(keyHash, proof.seed))); diff --git a/contracts/src/v0.8/dev/vrf/BlockhashStore.sol b/contracts/src/v0.8/dev/vrf/BlockhashStore.sol index 107746f8019..ad445595ff8 100644 --- a/contracts/src/v0.8/dev/vrf/BlockhashStore.sol +++ b/contracts/src/v0.8/dev/vrf/BlockhashStore.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.6; -import "../../ChainSpecificUtil.sol"; +import {ChainSpecificUtil} from "../../ChainSpecificUtil.sol"; /** * @title BlockhashStore @@ -14,7 +14,7 @@ import "../../ChainSpecificUtil.sol"; * would have to be deployed. */ contract BlockhashStore { - mapping(uint => bytes32) internal s_blockhashes; + mapping(uint256 => bytes32) internal s_blockhashes; /** * @notice stores blockhash of a given block, assuming it is available through BLOCKHASH @@ -22,6 +22,7 @@ contract BlockhashStore { */ function store(uint256 n) public { bytes32 h = ChainSpecificUtil.getBlockhash(uint64(n)); + // solhint-disable-next-line custom-errors require(h != 0x0, "blockhash(n) failed"); s_blockhashes[n] = h; } @@ -40,6 +41,7 @@ contract BlockhashStore { * that it hashes to a stored blockhash, and then extract parentHash to get the n-th blockhash. */ function storeVerifyHeader(uint256 n, bytes memory header) public { + // solhint-disable-next-line custom-errors require(keccak256(header) == s_blockhashes[n + 1], "header has unknown blockhash"); // At this point, we know that header is the correct blockheader for block n+1. @@ -72,6 +74,7 @@ contract BlockhashStore { */ function getBlockhash(uint256 n) external view returns (bytes32) { bytes32 h = s_blockhashes[n]; + // solhint-disable-next-line custom-errors require(h != 0x0, "blockhash not found in store"); return h; } diff --git a/contracts/src/v0.8/dev/vrf/SubscriptionAPI.sol b/contracts/src/v0.8/dev/vrf/SubscriptionAPI.sol index c4781cbde8c..d79b6daf844 100644 --- a/contracts/src/v0.8/dev/vrf/SubscriptionAPI.sol +++ b/contracts/src/v0.8/dev/vrf/SubscriptionAPI.sol @@ -1,12 +1,12 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol"; -import "../../shared/interfaces/LinkTokenInterface.sol"; -import "../../shared/access/ConfirmedOwner.sol"; -import "../../interfaces/AggregatorV3Interface.sol"; -import "../../shared/interfaces/IERC677Receiver.sol"; -import "../interfaces/IVRFSubscriptionV2Plus.sol"; +import {EnumerableSet} from "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol"; +import {LinkTokenInterface} from "../../shared/interfaces/LinkTokenInterface.sol"; +import {ConfirmedOwner} from "../../shared/access/ConfirmedOwner.sol"; +import {AggregatorV3Interface} from "../../interfaces/AggregatorV3Interface.sol"; +import {IERC677Receiver} from "../../shared/interfaces/IERC677Receiver.sol"; +import {IVRFSubscriptionV2Plus} from "../interfaces/IVRFSubscriptionV2Plus.sol"; abstract contract SubscriptionAPI is ConfirmedOwner, IERC677Receiver, IVRFSubscriptionV2Plus { using EnumerableSet for EnumerableSet.UintSet; @@ -392,6 +392,7 @@ abstract contract SubscriptionAPI is ConfirmedOwner, IERC677Receiver, IVRFSubscr emit SubscriptionConsumerAdded(subId, consumer); } + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function deleteSubscription(uint256 subId) internal returns (uint96 balance, uint96 nativeBalance) { SubscriptionConfig memory subConfig = s_subscriptionConfigs[subId]; Subscription memory sub = s_subscriptions[subId]; @@ -410,6 +411,7 @@ abstract contract SubscriptionAPI is ConfirmedOwner, IERC677Receiver, IVRFSubscr return (balance, nativeBalance); } + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function cancelSubscriptionHelper(uint256 subId, address to) internal { (uint96 balance, uint96 nativeBalance) = deleteSubscription(subId); diff --git a/contracts/src/v0.8/dev/vrf/TrustedBlockhashStore.sol b/contracts/src/v0.8/dev/vrf/TrustedBlockhashStore.sol index bbbc08f3a22..d084ea5c8eb 100644 --- a/contracts/src/v0.8/dev/vrf/TrustedBlockhashStore.sol +++ b/contracts/src/v0.8/dev/vrf/TrustedBlockhashStore.sol @@ -1,9 +1,9 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.6; -import "../../ChainSpecificUtil.sol"; -import "../../shared/access/ConfirmedOwner.sol"; -import "./BlockhashStore.sol"; +import {ChainSpecificUtil} from "../../ChainSpecificUtil.sol"; +import {ConfirmedOwner} from "../../shared/access/ConfirmedOwner.sol"; +import {BlockhashStore} from "./BlockhashStore.sol"; contract TrustedBlockhashStore is ConfirmedOwner, BlockhashStore { error NotInWhitelist(); diff --git a/contracts/src/v0.8/dev/vrf/VRFConsumerBaseV2Plus.sol b/contracts/src/v0.8/dev/vrf/VRFConsumerBaseV2Plus.sol index 0e6e2b22016..c256630f7c6 100644 --- a/contracts/src/v0.8/dev/vrf/VRFConsumerBaseV2Plus.sol +++ b/contracts/src/v0.8/dev/vrf/VRFConsumerBaseV2Plus.sol @@ -1,9 +1,9 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.4; -import "../interfaces/IVRFCoordinatorV2Plus.sol"; -import "../interfaces/IVRFMigratableConsumerV2Plus.sol"; -import "../../shared/access/ConfirmedOwner.sol"; +import {IVRFCoordinatorV2Plus} from "../interfaces/IVRFCoordinatorV2Plus.sol"; +import {IVRFMigratableConsumerV2Plus} from "../interfaces/IVRFMigratableConsumerV2Plus.sol"; +import {ConfirmedOwner} from "../../shared/access/ConfirmedOwner.sol"; /** **************************************************************************** * @notice Interface for contracts using VRF randomness @@ -126,6 +126,7 @@ abstract contract VRFConsumerBaseV2Plus is IVRFMigratableConsumerV2Plus, Confirm * @param requestId The Id initially returned by requestRandomness * @param randomWords the VRF output expanded to the requested number of words */ + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function fulfillRandomWords(uint256 requestId, uint256[] memory randomWords) internal virtual; // rawFulfillRandomness is called by VRFCoordinator when it receives a valid VRF diff --git a/contracts/src/v0.8/dev/vrf/VRFCoordinatorV2_5.sol b/contracts/src/v0.8/dev/vrf/VRFCoordinatorV2_5.sol index 3cd5d05e6e8..d69fa38c096 100644 --- a/contracts/src/v0.8/dev/vrf/VRFCoordinatorV2_5.sol +++ b/contracts/src/v0.8/dev/vrf/VRFCoordinatorV2_5.sol @@ -1,19 +1,20 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.4; -import "../../shared/interfaces/LinkTokenInterface.sol"; -import "../../interfaces/BlockhashStoreInterface.sol"; -import "../../interfaces/TypeAndVersionInterface.sol"; -import "../../vrf/VRF.sol"; -import "./VRFConsumerBaseV2Plus.sol"; -import "../../ChainSpecificUtil.sol"; -import "./SubscriptionAPI.sol"; -import "./libraries/VRFV2PlusClient.sol"; -import "../interfaces/IVRFCoordinatorV2PlusMigration.sol"; -import "../interfaces/IVRFCoordinatorV2Plus.sol"; - +import {BlockhashStoreInterface} from "../../interfaces/BlockhashStoreInterface.sol"; +import {VRF} from "../../vrf/VRF.sol"; +import {VRFConsumerBaseV2Plus, IVRFMigratableConsumerV2Plus} from "./VRFConsumerBaseV2Plus.sol"; +import {ChainSpecificUtil} from "../../ChainSpecificUtil.sol"; +import {SubscriptionAPI} from "./SubscriptionAPI.sol"; +import {VRFV2PlusClient} from "./libraries/VRFV2PlusClient.sol"; +import {IVRFCoordinatorV2PlusMigration} from "../interfaces/IVRFCoordinatorV2PlusMigration.sol"; +// solhint-disable-next-line no-unused-import +import {IVRFCoordinatorV2Plus, IVRFSubscriptionV2Plus} from "../interfaces/IVRFCoordinatorV2Plus.sol"; + +// solhint-disable-next-line contract-name-camelcase contract VRFCoordinatorV2_5 is VRF, SubscriptionAPI, IVRFCoordinatorV2Plus { /// @dev should always be available + // solhint-disable-next-line chainlink-solidity/prefix-immutable-variables-with-i BlockhashStoreInterface public immutable BLOCKHASH_STORE; // Set this maximum to 200 to give us a 56 block window to fulfill @@ -299,6 +300,7 @@ contract VRFCoordinatorV2_5 is VRF, SubscriptionAPI, IVRFCoordinatorV2Plus { return requestId; } + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function computeRequestId( bytes32 keyHash, address sender, @@ -313,8 +315,8 @@ contract VRFCoordinatorV2_5 is VRF, SubscriptionAPI, IVRFCoordinatorV2Plus { * @dev calls target address with exactly gasAmount gas and data as calldata * or reverts if at least gasAmount gas is not available. */ + // solhint-disable-next-line chainlink-solidity/prefix-private-functions-with-underscore function callWithExactGas(uint256 gasAmount, address target, bytes memory data) private returns (bool success) { - // solhint-disable-next-line no-inline-assembly assembly { let g := gas() // Compute g -= GAS_FOR_CALL_EXACT_CHECK and check for underflow @@ -349,6 +351,7 @@ contract VRFCoordinatorV2_5 is VRF, SubscriptionAPI, IVRFCoordinatorV2Plus { uint256 randomness; } + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function getRandomnessFromProof( Proof memory proof, RequestCommitment memory rc @@ -452,6 +455,7 @@ contract VRFCoordinatorV2_5 is VRF, SubscriptionAPI, IVRFCoordinatorV2Plus { } } + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function calculatePaymentAmount( uint256 startGas, uint256 gasAfterPaymentCalculation, @@ -476,6 +480,7 @@ contract VRFCoordinatorV2_5 is VRF, SubscriptionAPI, IVRFCoordinatorV2Plus { ); } + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function calculatePaymentAmountNative( uint256 startGas, uint256 gasAfterPaymentCalculation, @@ -493,6 +498,7 @@ contract VRFCoordinatorV2_5 is VRF, SubscriptionAPI, IVRFCoordinatorV2Plus { } // Get the amount of gas used for fulfillment + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function calculatePaymentAmountLink( uint256 startGas, uint256 gasAfterPaymentCalculation, @@ -516,6 +522,7 @@ contract VRFCoordinatorV2_5 is VRF, SubscriptionAPI, IVRFCoordinatorV2Plus { return uint96(paymentNoFee + fee); } + // solhint-disable-next-line chainlink-solidity/prefix-private-functions-with-underscore function getFeedData() private view returns (int256) { uint32 stalenessSeconds = s_config.stalenessSeconds; bool staleFallback = stalenessSeconds > 0; @@ -620,6 +627,7 @@ contract VRFCoordinatorV2_5 is VRF, SubscriptionAPI, IVRFCoordinatorV2Plus { uint96 nativeBalance; } + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function isTargetRegistered(address target) internal view returns (bool) { for (uint256 i = 0; i < s_migrationTargets.length; i++) { if (s_migrationTargets[i] == target) { @@ -656,7 +664,9 @@ contract VRFCoordinatorV2_5 is VRF, SubscriptionAPI, IVRFCoordinatorV2Plus { revert CoordinatorNotRegistered(newCoordinator); } (uint96 balance, uint96 nativeBalance, , address owner, address[] memory consumers) = getSubscription(subId); + // solhint-disable-next-line custom-errors require(owner == msg.sender, "Not subscription owner"); + // solhint-disable-next-line custom-errors require(!pendingRequestExists(subId), "Pending request exists"); V1MigrationData memory migrationData = V1MigrationData({ @@ -673,6 +683,7 @@ contract VRFCoordinatorV2_5 is VRF, SubscriptionAPI, IVRFCoordinatorV2Plus { // Only transfer LINK if the token is active and there is a balance. if (address(LINK) != address(0) && balance != 0) { + // solhint-disable-next-line custom-errors require(LINK.transfer(address(newCoordinator), balance), "insufficient funds"); } diff --git a/contracts/src/v0.8/dev/vrf/VRFV2PlusWrapper.sol b/contracts/src/v0.8/dev/vrf/VRFV2PlusWrapper.sol index fb6d9ee0243..8021f048989 100644 --- a/contracts/src/v0.8/dev/vrf/VRFV2PlusWrapper.sol +++ b/contracts/src/v0.8/dev/vrf/VRFV2PlusWrapper.sol @@ -1,20 +1,21 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.6; -import "../../shared/access/ConfirmedOwner.sol"; -import "../../interfaces/TypeAndVersionInterface.sol"; -import "./VRFConsumerBaseV2Plus.sol"; -import "../../shared/interfaces/LinkTokenInterface.sol"; -import "../../interfaces/AggregatorV3Interface.sol"; -import "../interfaces/IVRFCoordinatorV2Plus.sol"; -import "../interfaces/IVRFV2PlusWrapper.sol"; -import "./VRFV2PlusWrapperConsumerBase.sol"; -import "../../ChainSpecificUtil.sol"; +import {ConfirmedOwner} from "../../shared/access/ConfirmedOwner.sol"; +import {TypeAndVersionInterface} from "../../interfaces/TypeAndVersionInterface.sol"; +import {VRFConsumerBaseV2Plus} from "./VRFConsumerBaseV2Plus.sol"; +import {LinkTokenInterface} from "../../shared/interfaces/LinkTokenInterface.sol"; +import {AggregatorV3Interface} from "../../interfaces/AggregatorV3Interface.sol"; +import {VRFV2PlusClient} from "./libraries/VRFV2PlusClient.sol"; +import {IVRFV2PlusWrapper} from "../interfaces/IVRFV2PlusWrapper.sol"; +import {VRFV2PlusWrapperConsumerBase} from "./VRFV2PlusWrapperConsumerBase.sol"; +import {ChainSpecificUtil} from "../../ChainSpecificUtil.sol"; /** * @notice A wrapper for VRFCoordinatorV2 that provides an interface better suited to one-off * @notice requests for randomness. */ +// solhint-disable-next-line max-states-count contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsumerBaseV2Plus, IVRFV2PlusWrapper { event WrapperFulfillmentFailed(uint256 indexed requestId, address indexed consumer); @@ -27,10 +28,11 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume /* Storage Slot 1: BEGIN */ // s_keyHash is the key hash to use when requesting randomness. Fees are paid based on current gas // fees, so this should be set to the highest gas lane on the network. - bytes32 s_keyHash; + bytes32 internal s_keyHash; /* Storage Slot 1: END */ /* Storage Slot 2: BEGIN */ + // solhint-disable-next-line chainlink-solidity/prefix-immutable-variables-with-i uint256 public immutable SUBSCRIPTION_ID; /* Storage Slot 2: END */ @@ -106,7 +108,7 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume uint8 private s_wrapperPremiumPercentage; // s_maxNumWords is the max number of words that can be requested in a single wrapped VRF request. - uint8 s_maxNumWords; + uint8 internal s_maxNumWords; uint16 private constant EXPECTED_MIN_LENGTH = 36; /* Storage Slot 8: END */ @@ -307,6 +309,7 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume return calculateRequestPriceNativeInternal(_callbackGasLimit, _requestGasPriceWei); } + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function calculateRequestPriceNativeInternal(uint256 _gas, uint256 _requestGasPrice) internal view returns (uint256) { // costWei is the base fee denominated in wei (native) // costWei takes into account the L1 posting costs of the VRF fulfillment @@ -325,6 +328,7 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume return feeWithFlatFee; } + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function calculateRequestPriceInternal( uint256 _gas, uint256 _requestGasPrice, @@ -361,6 +365,7 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume * uint16 requestConfirmations, and uint32 numWords. */ function onTokenTransfer(address _sender, uint256 _amount, bytes calldata _data) external onlyConfiguredNotDisabled { + // solhint-disable-next-line custom-errors require(msg.sender == address(s_link), "only callable from LINK"); (uint32 callbackGasLimit, uint16 requestConfirmations, uint32 numWords, bytes memory extraArgs) = abi.decode( @@ -371,7 +376,9 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume uint32 eip150Overhead = getEIP150Overhead(callbackGasLimit); int256 weiPerUnitLink = getFeedData(); uint256 price = calculateRequestPriceInternal(callbackGasLimit, tx.gasprice, weiPerUnitLink); + // solhint-disable-next-line custom-errors require(_amount >= price, "fee too low"); + // solhint-disable-next-line custom-errors require(numWords <= s_maxNumWords, "numWords too high"); VRFV2PlusClient.RandomWordsRequest memory req = VRFV2PlusClient.RandomWordsRequest({ keyHash: s_keyHash, @@ -424,7 +431,9 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume uint32 eip150Overhead = getEIP150Overhead(_callbackGasLimit); uint256 price = calculateRequestPriceNativeInternal(_callbackGasLimit, tx.gasprice); + // solhint-disable-next-line custom-errors require(msg.value >= price, "fee too low"); + // solhint-disable-next-line custom-errors require(_numWords <= s_maxNumWords, "numWords too high"); VRFV2PlusClient.RandomWordsRequest memory req = VRFV2PlusClient.RandomWordsRequest({ keyHash: s_keyHash, @@ -466,6 +475,7 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume */ function withdrawNative(address _recipient, uint256 _amount) external onlyOwner { (bool success, ) = payable(_recipient).call{value: _amount}(""); + // solhint-disable-next-line custom-errors require(success, "failed to withdraw native"); } @@ -484,9 +494,11 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume s_disabled = true; } + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function fulfillRandomWords(uint256 _requestId, uint256[] memory _randomWords) internal override { Callback memory callback = s_callbacks[_requestId]; delete s_callbacks[_requestId]; + // solhint-disable-next-line custom-errors require(callback.callbackAddress != address(0), "request not found"); // This should never happen VRFV2PlusWrapperConsumerBase c; @@ -498,6 +510,7 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume } } + // solhint-disable-next-line chainlink-solidity/prefix-private-functions-with-underscore function getFeedData() private view returns (int256) { bool staleFallback = s_stalenessSeconds > 0; uint256 timestamp; @@ -507,6 +520,7 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume if (staleFallback && s_stalenessSeconds < block.timestamp - timestamp) { weiPerUnitLink = s_fallbackWeiPerUnitLink; } + // solhint-disable-next-line custom-errors require(weiPerUnitLink >= 0, "Invalid LINK wei price"); return weiPerUnitLink; } @@ -514,6 +528,7 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume /** * @dev Calculates extra amount of gas required for running an assembly call() post-EIP150. */ + // solhint-disable-next-line chainlink-solidity/prefix-private-functions-with-underscore function getEIP150Overhead(uint32 gas) private pure returns (uint32) { return gas / 63 + 1; } @@ -522,8 +537,8 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume * @dev calls target address with exactly gasAmount gas and data as calldata * or reverts if at least gasAmount gas is not available. */ + // solhint-disable-next-line chainlink-solidity/prefix-private-functions-with-underscore function callWithExactGas(uint256 gasAmount, address target, bytes memory data) private returns (bool success) { - // solhint-disable-next-line no-inline-assembly assembly { let g := gas() // Compute g -= GAS_FOR_CALL_EXACT_CHECK and check for underflow @@ -557,7 +572,9 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume } modifier onlyConfiguredNotDisabled() { + // solhint-disable-next-line custom-errors require(s_configured, "wrapper is not configured"); + // solhint-disable-next-line custom-errors require(!s_disabled, "wrapper is disabled"); _; } diff --git a/contracts/src/v0.8/dev/vrf/VRFV2PlusWrapperConsumerBase.sol b/contracts/src/v0.8/dev/vrf/VRFV2PlusWrapperConsumerBase.sol index c96623d28ef..e800753af2b 100644 --- a/contracts/src/v0.8/dev/vrf/VRFV2PlusWrapperConsumerBase.sol +++ b/contracts/src/v0.8/dev/vrf/VRFV2PlusWrapperConsumerBase.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import "../../shared/interfaces/LinkTokenInterface.sol"; -import "../interfaces/IVRFV2PlusWrapper.sol"; +import {LinkTokenInterface} from "../../shared/interfaces/LinkTokenInterface.sol"; +import {IVRFV2PlusWrapper} from "../interfaces/IVRFV2PlusWrapper.sol"; /** * @@ -31,7 +31,9 @@ import "../interfaces/IVRFV2PlusWrapper.sol"; abstract contract VRFV2PlusWrapperConsumerBase { error LINKAlreadySet(); + // solhint-disable-next-line chainlink-solidity/prefix-storage-variables-with-s-underscore LinkTokenInterface internal LINK; + // solhint-disable-next-line chainlink-solidity/prefix-storage-variables-with-s-underscore IVRFV2PlusWrapper internal VRF_V2_PLUS_WRAPPER; /** @@ -70,6 +72,7 @@ abstract contract VRFV2PlusWrapperConsumerBase { * * @return requestId is the VRF V2+ request ID of the newly created randomness request. */ + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function requestRandomness( uint32 _callbackGasLimit, uint16 _requestConfirmations, @@ -84,6 +87,7 @@ abstract contract VRFV2PlusWrapperConsumerBase { return VRF_V2_PLUS_WRAPPER.lastRequestId(); } + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function requestRandomnessPayInNative( uint32 _callbackGasLimit, uint16 _requestConfirmations, @@ -107,9 +111,11 @@ abstract contract VRFV2PlusWrapperConsumerBase { * @param _requestId is the VRF V2 request ID. * @param _randomWords is the randomness result. */ + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function fulfillRandomWords(uint256 _requestId, uint256[] memory _randomWords) internal virtual; function rawFulfillRandomWords(uint256 _requestId, uint256[] memory _randomWords) external { + // solhint-disable-next-line custom-errors require(msg.sender == address(VRF_V2_PLUS_WRAPPER), "only VRF V2 Plus wrapper can fulfill"); fulfillRandomWords(_requestId, _randomWords); } diff --git a/contracts/src/v0.8/dev/vrf/testhelpers/ExposedVRFCoordinatorV2_5.sol b/contracts/src/v0.8/dev/vrf/testhelpers/ExposedVRFCoordinatorV2_5.sol index 5e54636bb17..f9c34b2b611 100644 --- a/contracts/src/v0.8/dev/vrf/testhelpers/ExposedVRFCoordinatorV2_5.sol +++ b/contracts/src/v0.8/dev/vrf/testhelpers/ExposedVRFCoordinatorV2_5.sol @@ -1,10 +1,10 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.4; -import "../../../vrf/VRF.sol"; import {VRFCoordinatorV2_5} from "../VRFCoordinatorV2_5.sol"; -import "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol"; +import {EnumerableSet} from "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol"; +// solhint-disable-next-line contract-name-camelcase contract ExposedVRFCoordinatorV2_5 is VRFCoordinatorV2_5 { using EnumerableSet for EnumerableSet.UintSet; diff --git a/contracts/src/v0.8/dev/vrf/testhelpers/VRFConsumerV2PlusUpgradeableExample.sol b/contracts/src/v0.8/dev/vrf/testhelpers/VRFConsumerV2PlusUpgradeableExample.sol index 7b34f96e376..1211014cd2f 100644 --- a/contracts/src/v0.8/dev/vrf/testhelpers/VRFConsumerV2PlusUpgradeableExample.sol +++ b/contracts/src/v0.8/dev/vrf/testhelpers/VRFConsumerV2PlusUpgradeableExample.sol @@ -1,10 +1,11 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import "../../../shared/interfaces/LinkTokenInterface.sol"; -import "../../interfaces/IVRFCoordinatorV2Plus.sol"; -import "../../VRFConsumerBaseV2Upgradeable.sol"; -import "@openzeppelin/contracts-upgradeable-4.7.3/proxy/utils/Initializable.sol"; +import {LinkTokenInterface} from "../../../shared/interfaces/LinkTokenInterface.sol"; +import {IVRFCoordinatorV2Plus} from "../../interfaces/IVRFCoordinatorV2Plus.sol"; +import {VRFConsumerBaseV2Upgradeable} from "../../VRFConsumerBaseV2Upgradeable.sol"; +import {Initializable} from "@openzeppelin/contracts-upgradeable-4.7.3/proxy/utils/Initializable.sol"; +import {VRFV2PlusClient} from "../libraries/VRFV2PlusClient.sol"; contract VRFConsumerV2PlusUpgradeableExample is Initializable, VRFConsumerBaseV2Upgradeable { uint256[] public s_randomWords; @@ -20,7 +21,9 @@ contract VRFConsumerV2PlusUpgradeableExample is Initializable, VRFConsumerBaseV2 LINKTOKEN = LinkTokenInterface(_link); } + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function fulfillRandomWords(uint256 requestId, uint256[] memory randomWords) internal override { + // solhint-disable-next-line custom-errors require(requestId == s_requestId, "request ID is incorrect"); s_gasAvailable = gasleft(); @@ -37,12 +40,14 @@ contract VRFConsumerV2PlusUpgradeableExample is Initializable, VRFConsumerBaseV2 } function topUpSubscription(uint96 amount) external { + // solhint-disable-next-line custom-errors require(s_subId != 0, "sub not set"); // Approve the link transfer. LINKTOKEN.transferAndCall(address(COORDINATOR), amount, abi.encode(s_subId)); } function updateSubscription(address[] memory consumers) external { + // solhint-disable-next-line custom-errors require(s_subId != 0, "subID not set"); for (uint256 i = 0; i < consumers.length; i++) { COORDINATOR.addConsumer(s_subId, consumers[i]); diff --git a/contracts/src/v0.8/dev/vrf/testhelpers/VRFCoordinatorV2PlusUpgradedVersion.sol b/contracts/src/v0.8/dev/vrf/testhelpers/VRFCoordinatorV2PlusUpgradedVersion.sol index 94017adde73..07b55388e10 100644 --- a/contracts/src/v0.8/dev/vrf/testhelpers/VRFCoordinatorV2PlusUpgradedVersion.sol +++ b/contracts/src/v0.8/dev/vrf/testhelpers/VRFCoordinatorV2PlusUpgradedVersion.sol @@ -1,17 +1,16 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.4; -import "../../../shared/interfaces/LinkTokenInterface.sol"; -import "../../../interfaces/BlockhashStoreInterface.sol"; -import "../../../interfaces/TypeAndVersionInterface.sol"; -import "../../interfaces/IVRFCoordinatorV2Plus.sol"; -import "../../../vrf/VRF.sol"; -import "../VRFConsumerBaseV2Plus.sol"; -import "../../../ChainSpecificUtil.sol"; -import "../SubscriptionAPI.sol"; -import "../libraries/VRFV2PlusClient.sol"; -import "../../interfaces/IVRFCoordinatorV2PlusMigration.sol"; -import "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol"; +import {BlockhashStoreInterface} from "../../../interfaces/BlockhashStoreInterface.sol"; +// solhint-disable-next-line no-unused-import +import {IVRFCoordinatorV2Plus, IVRFSubscriptionV2Plus} from "../../interfaces/IVRFCoordinatorV2Plus.sol"; +import {VRF} from "../../../vrf/VRF.sol"; +import {VRFConsumerBaseV2Plus, IVRFMigratableConsumerV2Plus} from "../VRFConsumerBaseV2Plus.sol"; +import {ChainSpecificUtil} from "../../../ChainSpecificUtil.sol"; +import {SubscriptionAPI} from "../SubscriptionAPI.sol"; +import {VRFV2PlusClient} from "../libraries/VRFV2PlusClient.sol"; +import {IVRFCoordinatorV2PlusMigration} from "../../interfaces/IVRFCoordinatorV2PlusMigration.sol"; +import {EnumerableSet} from "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol"; contract VRFCoordinatorV2PlusUpgradedVersion is VRF, @@ -21,6 +20,7 @@ contract VRFCoordinatorV2PlusUpgradedVersion is { using EnumerableSet for EnumerableSet.UintSet; /// @dev should always be available + // solhint-disable-next-line chainlink-solidity/prefix-immutable-variables-with-i BlockhashStoreInterface public immutable BLOCKHASH_STORE; // Set this maximum to 200 to give us a 56 block window to fulfill @@ -291,6 +291,7 @@ contract VRFCoordinatorV2PlusUpgradedVersion is return requestId; } + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function computeRequestId( bytes32 keyHash, address sender, @@ -305,8 +306,8 @@ contract VRFCoordinatorV2PlusUpgradedVersion is * @dev calls target address with exactly gasAmount gas and data as calldata * or reverts if at least gasAmount gas is not available. */ + // solhint-disable-next-line chainlink-solidity/prefix-private-functions-with-underscore function callWithExactGas(uint256 gasAmount, address target, bytes memory data) private returns (bool success) { - // solhint-disable-next-line no-inline-assembly assembly { let g := gas() // Compute g -= GAS_FOR_CALL_EXACT_CHECK and check for underflow @@ -341,6 +342,7 @@ contract VRFCoordinatorV2PlusUpgradedVersion is uint256 randomness; } + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function getRandomnessFromProof( Proof memory proof, RequestCommitment memory rc @@ -444,6 +446,7 @@ contract VRFCoordinatorV2PlusUpgradedVersion is } } + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function calculatePaymentAmount( uint256 startGas, uint256 gasAfterPaymentCalculation, @@ -468,6 +471,7 @@ contract VRFCoordinatorV2PlusUpgradedVersion is ); } + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function calculatePaymentAmountNative( uint256 startGas, uint256 gasAfterPaymentCalculation, @@ -485,6 +489,7 @@ contract VRFCoordinatorV2PlusUpgradedVersion is } // Get the amount of gas used for fulfillment + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function calculatePaymentAmountLink( uint256 startGas, uint256 gasAfterPaymentCalculation, @@ -508,6 +513,7 @@ contract VRFCoordinatorV2PlusUpgradedVersion is return uint96(paymentNoFee + fee); } + // solhint-disable-next-line chainlink-solidity/prefix-private-functions-with-underscore function getFeedData() private view returns (int256) { uint32 stalenessSeconds = s_config.stalenessSeconds; bool staleFallback = stalenessSeconds > 0; @@ -615,6 +621,7 @@ contract VRFCoordinatorV2PlusUpgradedVersion is uint96 nativeBalance; } + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function isTargetRegistered(address target) internal view returns (bool) { for (uint256 i = 0; i < s_migrationTargets.length; i++) { if (s_migrationTargets[i] == target) { @@ -637,7 +644,9 @@ contract VRFCoordinatorV2PlusUpgradedVersion is revert CoordinatorNotRegistered(newCoordinator); } (uint96 balance, uint96 nativeBalance, , address owner, address[] memory consumers) = getSubscription(subId); + // solhint-disable-next-line custom-errors require(owner == msg.sender, "Not subscription owner"); + // solhint-disable-next-line custom-errors require(!pendingRequestExists(subId), "Pending request exists"); V1MigrationData memory migrationData = V1MigrationData({ @@ -654,6 +663,7 @@ contract VRFCoordinatorV2PlusUpgradedVersion is // Only transfer LINK if the token is active and there is a balance. if (address(LINK) != address(0) && balance != 0) { + // solhint-disable-next-line custom-errors require(LINK.transfer(address(newCoordinator), balance), "insufficient funds"); } @@ -698,7 +708,7 @@ contract VRFCoordinatorV2PlusUpgradedVersion is revert SubscriptionIDCollisionFound(); } - for (uint i = 0; i < migrationData.consumers.length; i++) { + for (uint256 i = 0; i < migrationData.consumers.length; i++) { s_consumers[migrationData.consumers[i]][migrationData.subId] = 1; } diff --git a/contracts/src/v0.8/dev/vrf/testhelpers/VRFCoordinatorV2Plus_V2Example.sol b/contracts/src/v0.8/dev/vrf/testhelpers/VRFCoordinatorV2Plus_V2Example.sol index 52a5b864c6b..7306931570a 100644 --- a/contracts/src/v0.8/dev/vrf/testhelpers/VRFCoordinatorV2Plus_V2Example.sol +++ b/contracts/src/v0.8/dev/vrf/testhelpers/VRFCoordinatorV2Plus_V2Example.sol @@ -1,13 +1,13 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.4; -import "../../../shared/interfaces/LinkTokenInterface.sol"; -import "../../interfaces/IVRFCoordinatorV2PlusMigration.sol"; -import "../../interfaces/IVRFCoordinatorV2Plus.sol"; -import "../VRFConsumerBaseV2Plus.sol"; +import {IVRFCoordinatorV2PlusMigration} from "../../interfaces/IVRFCoordinatorV2PlusMigration.sol"; +import {VRFConsumerBaseV2Plus} from "../VRFConsumerBaseV2Plus.sol"; +import {VRFV2PlusClient} from "../libraries/VRFV2PlusClient.sol"; /// @dev this contract is only meant for testing migration /// @dev it is a simplified example of future version (V2) of VRFCoordinatorV2Plus +// solhint-disable-next-line contract-name-camelcase contract VRFCoordinatorV2Plus_V2Example is IVRFCoordinatorV2PlusMigration { error SubscriptionIDCollisionFound(); @@ -138,6 +138,7 @@ contract VRFCoordinatorV2Plus_V2Example is IVRFCoordinatorV2PlusMigration { return handleRequest(msg.sender); } + // solhint-disable-next-line chainlink-solidity/prefix-private-functions-with-underscore function handleRequest(address requester) private returns (uint256) { s_requestId = s_requestId + 1; uint256 requestId = s_requestId; diff --git a/contracts/src/v0.8/dev/vrf/testhelpers/VRFMaliciousConsumerV2Plus.sol b/contracts/src/v0.8/dev/vrf/testhelpers/VRFMaliciousConsumerV2Plus.sol index 11e899ae659..cc3e465bc0c 100644 --- a/contracts/src/v0.8/dev/vrf/testhelpers/VRFMaliciousConsumerV2Plus.sol +++ b/contracts/src/v0.8/dev/vrf/testhelpers/VRFMaliciousConsumerV2Plus.sol @@ -1,24 +1,28 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import "../../../shared/interfaces/LinkTokenInterface.sol"; -import "../../interfaces/IVRFCoordinatorV2Plus.sol"; -import "../VRFConsumerBaseV2Plus.sol"; +import {LinkTokenInterface} from "../../../shared/interfaces/LinkTokenInterface.sol"; +import {IVRFCoordinatorV2Plus} from "../../interfaces/IVRFCoordinatorV2Plus.sol"; +import {VRFConsumerBaseV2Plus} from "../VRFConsumerBaseV2Plus.sol"; +import {VRFV2PlusClient} from "../libraries/VRFV2PlusClient.sol"; contract VRFMaliciousConsumerV2Plus is VRFConsumerBaseV2Plus { uint256[] public s_randomWords; uint256 public s_requestId; - IVRFCoordinatorV2Plus COORDINATOR; - LinkTokenInterface LINKTOKEN; + // solhint-disable-next-line chainlink-solidity/prefix-storage-variables-with-s-underscore + IVRFCoordinatorV2Plus internal COORDINATOR; + // solhint-disable-next-line chainlink-solidity/prefix-storage-variables-with-s-underscore + LinkTokenInterface internal LINKTOKEN; uint256 public s_gasAvailable; - uint256 s_subId; - bytes32 s_keyHash; + uint256 internal s_subId; + bytes32 internal s_keyHash; constructor(address vrfCoordinator, address link) VRFConsumerBaseV2Plus(vrfCoordinator) { COORDINATOR = IVRFCoordinatorV2Plus(vrfCoordinator); LINKTOKEN = LinkTokenInterface(link); } + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function fulfillRandomWords(uint256 requestId, uint256[] memory randomWords) internal override { s_gasAvailable = gasleft(); s_randomWords = randomWords; @@ -45,6 +49,7 @@ contract VRFMaliciousConsumerV2Plus is VRFConsumerBaseV2Plus { } function updateSubscription(address[] memory consumers) external { + // solhint-disable-next-line custom-errors require(s_subId != 0, "subID not set"); for (uint256 i = 0; i < consumers.length; i++) { COORDINATOR.addConsumer(s_subId, consumers[i]); diff --git a/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusConsumerExample.sol b/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusConsumerExample.sol index 948cc17b3f3..8acc0ce6d0b 100644 --- a/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusConsumerExample.sol +++ b/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusConsumerExample.sol @@ -1,10 +1,11 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import "../../../shared/interfaces/LinkTokenInterface.sol"; -import "../../interfaces/IVRFCoordinatorV2Plus.sol"; -import "../VRFConsumerBaseV2Plus.sol"; -import "../../../shared/access/ConfirmedOwner.sol"; +import {LinkTokenInterface} from "../../../shared/interfaces/LinkTokenInterface.sol"; +import {IVRFCoordinatorV2Plus} from "../../interfaces/IVRFCoordinatorV2Plus.sol"; +import {VRFConsumerBaseV2Plus} from "../VRFConsumerBaseV2Plus.sol"; +import {ConfirmedOwner} from "../../../shared/access/ConfirmedOwner.sol"; +import {VRFV2PlusClient} from "../libraries/VRFV2PlusClient.sol"; /// @notice This contract is used for testing only and should not be used for production. contract VRFV2PlusConsumerExample is ConfirmedOwner, VRFConsumerBaseV2Plus { @@ -28,10 +29,12 @@ contract VRFV2PlusConsumerExample is ConfirmedOwner, VRFConsumerBaseV2Plus { function getRandomness(uint256 requestId, uint256 idx) public view returns (uint256 randomWord) { Response memory resp = s_requests[requestId]; + // solhint-disable-next-line custom-errors require(resp.requestId != 0, "request ID is incorrect"); return resp.randomWords[idx]; } + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function subscribe() internal returns (uint256) { if (s_subId == 0) { s_subId = s_vrfCoordinatorApiV1.createSubscription(); @@ -52,16 +55,20 @@ contract VRFV2PlusConsumerExample is ConfirmedOwner, VRFConsumerBaseV2Plus { } function topUpSubscription(uint96 amount) external { + // solhint-disable-next-line custom-errors require(s_subId != 0, "sub not set"); s_linkToken.transferAndCall(address(s_vrfCoordinator), amount, abi.encode(s_subId)); } function topUpSubscriptionNative() external payable { + // solhint-disable-next-line custom-errors require(s_subId != 0, "sub not set"); s_vrfCoordinatorApiV1.fundSubscriptionWithNative{value: msg.value}(s_subId); } + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function fulfillRandomWords(uint256 requestId, uint256[] memory randomWords) internal override { + // solhint-disable-next-line custom-errors require(requestId == s_recentRequestId, "request ID is incorrect"); s_requests[requestId].randomWords = randomWords; s_requests[requestId].fulfilled = true; @@ -94,6 +101,7 @@ contract VRFV2PlusConsumerExample is ConfirmedOwner, VRFConsumerBaseV2Plus { } function updateSubscription(address[] memory consumers) external { + // solhint-disable-next-line custom-errors require(s_subId != 0, "subID not set"); for (uint256 i = 0; i < consumers.length; i++) { s_vrfCoordinatorApiV1.addConsumer(s_subId, consumers[i]); diff --git a/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusExternalSubOwnerExample.sol b/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusExternalSubOwnerExample.sol index 2b9ac5713cc..384a5890018 100644 --- a/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusExternalSubOwnerExample.sol +++ b/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusExternalSubOwnerExample.sol @@ -1,18 +1,21 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import "../../../shared/interfaces/LinkTokenInterface.sol"; -import "../../interfaces/IVRFCoordinatorV2Plus.sol"; -import "../VRFConsumerBaseV2Plus.sol"; +import {LinkTokenInterface} from "../../../shared/interfaces/LinkTokenInterface.sol"; +import {IVRFCoordinatorV2Plus} from "../../interfaces/IVRFCoordinatorV2Plus.sol"; +import {VRFConsumerBaseV2Plus} from "../VRFConsumerBaseV2Plus.sol"; +import {VRFV2PlusClient} from "../libraries/VRFV2PlusClient.sol"; /// @notice This contract is used for testing only and should not be used for production. contract VRFV2PlusExternalSubOwnerExample is VRFConsumerBaseV2Plus { - IVRFCoordinatorV2Plus COORDINATOR; - LinkTokenInterface LINKTOKEN; + // solhint-disable-next-line chainlink-solidity/prefix-storage-variables-with-s-underscore + IVRFCoordinatorV2Plus internal COORDINATOR; + // solhint-disable-next-line chainlink-solidity/prefix-storage-variables-with-s-underscore + LinkTokenInterface internal LINKTOKEN; uint256[] public s_randomWords; uint256 public s_requestId; - address s_owner; + address internal s_owner; constructor(address vrfCoordinator, address link) VRFConsumerBaseV2Plus(vrfCoordinator) { COORDINATOR = IVRFCoordinatorV2Plus(vrfCoordinator); @@ -20,7 +23,9 @@ contract VRFV2PlusExternalSubOwnerExample is VRFConsumerBaseV2Plus { s_owner = msg.sender; } + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function fulfillRandomWords(uint256 requestId, uint256[] memory randomWords) internal override { + // solhint-disable-next-line custom-errors require(requestId == s_requestId, "request ID is incorrect"); s_randomWords = randomWords; } diff --git a/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusLoadTestWithMetrics.sol b/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusLoadTestWithMetrics.sol index 42296ae6bf4..ad09f88fd2f 100644 --- a/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusLoadTestWithMetrics.sol +++ b/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusLoadTestWithMetrics.sol @@ -1,10 +1,9 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import "../../../ChainSpecificUtil.sol"; -import "../../interfaces/IVRFCoordinatorV2Plus.sol"; -import "../VRFConsumerBaseV2Plus.sol"; -import "../../../shared/access/ConfirmedOwner.sol"; +import {ChainSpecificUtil} from "../../../ChainSpecificUtil.sol"; +import {VRFConsumerBaseV2Plus} from "../VRFConsumerBaseV2Plus.sol"; +import {VRFV2PlusClient} from "../libraries/VRFV2PlusClient.sol"; /** * @title The VRFLoadTestExternalSubOwner contract. @@ -17,13 +16,14 @@ contract VRFV2PlusLoadTestWithMetrics is VRFConsumerBaseV2Plus { uint256 public s_slowestFulfillment = 0; uint256 public s_fastestFulfillment = 999; uint256 public s_lastRequestId; - mapping(uint256 => uint256) requestHeights; // requestIds to block number when rand request was made + // solhint-disable-next-line chainlink-solidity/prefix-storage-variables-with-s-underscore + mapping(uint256 => uint256) internal requestHeights; // requestIds to block number when rand request was made struct RequestStatus { bool fulfilled; uint256[] randomWords; - uint requestTimestamp; - uint fulfilmentTimestamp; + uint256 requestTimestamp; + uint256 fulfilmentTimestamp; uint256 requestBlockNumber; uint256 fulfilmentBlockNumber; } @@ -32,6 +32,7 @@ contract VRFV2PlusLoadTestWithMetrics is VRFConsumerBaseV2Plus { constructor(address _vrfCoordinator) VRFConsumerBaseV2Plus(_vrfCoordinator) {} + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function fulfillRandomWords(uint256 _requestId, uint256[] memory _randomWords) internal override { uint256 fulfilmentBlockNumber = ChainSpecificUtil.getBlockNumber(); uint256 requestDelay = fulfilmentBlockNumber - requestHeights[_requestId]; @@ -105,8 +106,8 @@ contract VRFV2PlusLoadTestWithMetrics is VRFConsumerBaseV2Plus { returns ( bool fulfilled, uint256[] memory randomWords, - uint requestTimestamp, - uint fulfilmentTimestamp, + uint256 requestTimestamp, + uint256 fulfilmentTimestamp, uint256 requestBlockNumber, uint256 fulfilmentBlockNumber ) diff --git a/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusMaliciousMigrator.sol b/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusMaliciousMigrator.sol index b1dca81ebdf..2be0024ae71 100644 --- a/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusMaliciousMigrator.sol +++ b/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusMaliciousMigrator.sol @@ -1,12 +1,12 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.0; -import "../../interfaces/IVRFMigratableConsumerV2Plus.sol"; -import "../../interfaces/IVRFCoordinatorV2Plus.sol"; -import "../libraries/VRFV2PlusClient.sol"; +import {IVRFMigratableConsumerV2Plus} from "../../interfaces/IVRFMigratableConsumerV2Plus.sol"; +import {IVRFCoordinatorV2Plus} from "../../interfaces/IVRFCoordinatorV2Plus.sol"; +import {VRFV2PlusClient} from "../libraries/VRFV2PlusClient.sol"; contract VRFV2PlusMaliciousMigrator is IVRFMigratableConsumerV2Plus { - IVRFCoordinatorV2Plus s_vrfCoordinator; + IVRFCoordinatorV2Plus internal s_vrfCoordinator; constructor(address _vrfCoordinator) { s_vrfCoordinator = IVRFCoordinatorV2Plus(_vrfCoordinator); @@ -15,7 +15,7 @@ contract VRFV2PlusMaliciousMigrator is IVRFMigratableConsumerV2Plus { /** * @inheritdoc IVRFMigratableConsumerV2Plus */ - function setCoordinator(address _vrfCoordinator) public override { + function setCoordinator(address /* _vrfCoordinator */) public override { // try to re-enter, should revert // args don't really matter s_vrfCoordinator.requestRandomWords( diff --git a/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusRevertingExample.sol b/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusRevertingExample.sol index 36063533586..170ff9dd6e9 100644 --- a/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusRevertingExample.sol +++ b/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusRevertingExample.sol @@ -1,16 +1,19 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import "../../../shared/interfaces/LinkTokenInterface.sol"; -import "../../interfaces/IVRFCoordinatorV2Plus.sol"; -import "../VRFConsumerBaseV2Plus.sol"; +import {LinkTokenInterface} from "../../../shared/interfaces/LinkTokenInterface.sol"; +import {IVRFCoordinatorV2Plus} from "../../interfaces/IVRFCoordinatorV2Plus.sol"; +import {VRFConsumerBaseV2Plus} from "../VRFConsumerBaseV2Plus.sol"; +import {VRFV2PlusClient} from "../libraries/VRFV2PlusClient.sol"; // VRFV2RevertingExample will always revert. Used for testing only, useless in prod. contract VRFV2PlusRevertingExample is VRFConsumerBaseV2Plus { uint256[] public s_randomWords; uint256 public s_requestId; - IVRFCoordinatorV2Plus COORDINATOR; - LinkTokenInterface LINKTOKEN; + // solhint-disable-next-line chainlink-solidity/prefix-storage-variables-with-s-underscore + IVRFCoordinatorV2Plus internal COORDINATOR; + // solhint-disable-next-line chainlink-solidity/prefix-storage-variables-with-s-underscore + LinkTokenInterface internal LINKTOKEN; uint256 public s_subId; uint256 public s_gasAvailable; @@ -19,7 +22,9 @@ contract VRFV2PlusRevertingExample is VRFConsumerBaseV2Plus { LINKTOKEN = LinkTokenInterface(link); } + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function fulfillRandomWords(uint256, uint256[] memory) internal pure override { + // solhint-disable-next-line custom-errors, reason-string revert(); } @@ -33,12 +38,14 @@ contract VRFV2PlusRevertingExample is VRFConsumerBaseV2Plus { } function topUpSubscription(uint96 amount) external { + // solhint-disable-next-line custom-errors require(s_subId != 0, "sub not set"); // Approve the link transfer. LINKTOKEN.transferAndCall(address(COORDINATOR), amount, abi.encode(s_subId)); } function updateSubscription(address[] memory consumers) external { + // solhint-disable-next-line custom-errors require(s_subId != 0, "subID not set"); for (uint256 i = 0; i < consumers.length; i++) { COORDINATOR.addConsumer(s_subId, consumers[i]); diff --git a/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusSingleConsumerExample.sol b/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusSingleConsumerExample.sol index e4cd9ae29ad..b190ebc8715 100644 --- a/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusSingleConsumerExample.sol +++ b/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusSingleConsumerExample.sol @@ -2,14 +2,17 @@ // Example of a single consumer contract which owns the subscription. pragma solidity ^0.8.0; -import "../../../shared/interfaces/LinkTokenInterface.sol"; -import "../../interfaces/IVRFCoordinatorV2Plus.sol"; -import "../VRFConsumerBaseV2Plus.sol"; +import {LinkTokenInterface} from "../../../shared/interfaces/LinkTokenInterface.sol"; +import {IVRFCoordinatorV2Plus} from "../../interfaces/IVRFCoordinatorV2Plus.sol"; +import {VRFConsumerBaseV2Plus} from "../VRFConsumerBaseV2Plus.sol"; +import {VRFV2PlusClient} from "../libraries/VRFV2PlusClient.sol"; /// @notice This contract is used for testing only and should not be used for production. contract VRFV2PlusSingleConsumerExample is VRFConsumerBaseV2Plus { - IVRFCoordinatorV2Plus COORDINATOR; - LinkTokenInterface LINKTOKEN; + // solhint-disable-next-line chainlink-solidity/prefix-storage-variables-with-s-underscore + IVRFCoordinatorV2Plus internal COORDINATOR; + // solhint-disable-next-line chainlink-solidity/prefix-storage-variables-with-s-underscore + LinkTokenInterface internal LINKTOKEN; struct RequestConfig { uint256 subId; @@ -22,7 +25,7 @@ contract VRFV2PlusSingleConsumerExample is VRFConsumerBaseV2Plus { RequestConfig public s_requestConfig; uint256[] public s_randomWords; uint256 public s_requestId; - address s_owner; + address internal s_owner; constructor( address vrfCoordinator, @@ -47,7 +50,9 @@ contract VRFV2PlusSingleConsumerExample is VRFConsumerBaseV2Plus { subscribe(); } + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function fulfillRandomWords(uint256 requestId, uint256[] memory randomWords) internal override { + // solhint-disable-next-line custom-errors require(requestId == s_requestId, "request ID is incorrect"); s_randomWords = randomWords; } diff --git a/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusWrapperConsumerExample.sol b/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusWrapperConsumerExample.sol index 206d56ea321..5285eee9463 100644 --- a/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusWrapperConsumerExample.sol +++ b/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusWrapperConsumerExample.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.6; -import "../VRFV2PlusWrapperConsumerBase.sol"; -import "../../../shared/access/ConfirmedOwner.sol"; +import {VRFV2PlusWrapperConsumerBase} from "../VRFV2PlusWrapperConsumerBase.sol"; +import {ConfirmedOwner} from "../../../shared/access/ConfirmedOwner.sol"; import {VRFV2PlusClient} from "../libraries/VRFV2PlusClient.sol"; contract VRFV2PlusWrapperConsumerExample is VRFV2PlusWrapperConsumerBase, ConfirmedOwner { @@ -49,7 +49,9 @@ contract VRFV2PlusWrapperConsumerExample is VRFV2PlusWrapperConsumerBase, Confir return requestId; } + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function fulfillRandomWords(uint256 _requestId, uint256[] memory _randomWords) internal override { + // solhint-disable-next-line custom-errors require(s_requests[_requestId].paid > 0, "request not found"); s_requests[_requestId].fulfilled = true; s_requests[_requestId].randomWords = _randomWords; @@ -59,6 +61,7 @@ contract VRFV2PlusWrapperConsumerExample is VRFV2PlusWrapperConsumerBase, Confir function getRequestStatus( uint256 _requestId ) external view returns (uint256 paid, bool fulfilled, uint256[] memory randomWords) { + // solhint-disable-next-line custom-errors require(s_requests[_requestId].paid > 0, "request not found"); RequestStatus memory request = s_requests[_requestId]; return (request.paid, request.fulfilled, request.randomWords); @@ -74,6 +77,7 @@ contract VRFV2PlusWrapperConsumerExample is VRFV2PlusWrapperConsumerBase, Confir /// @param amount the amount to withdraw, in wei function withdrawNative(uint256 amount) external onlyOwner { (bool success, ) = payable(owner()).call{value: amount}(""); + // solhint-disable-next-line custom-errors require(success, "withdrawNative failed"); } } diff --git a/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusWrapperLoadTestConsumer.sol b/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusWrapperLoadTestConsumer.sol index 0656f621799..7b6df2c563e 100644 --- a/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusWrapperLoadTestConsumer.sol +++ b/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusWrapperLoadTestConsumer.sol @@ -1,10 +1,11 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.6; -import "../VRFV2PlusWrapperConsumerBase.sol"; -import "../../../shared/access/ConfirmedOwner.sol"; -import "../../../ChainSpecificUtil.sol"; +import {VRFV2PlusWrapperConsumerBase} from "../VRFV2PlusWrapperConsumerBase.sol"; +import {ConfirmedOwner} from "../../../shared/access/ConfirmedOwner.sol"; +import {ChainSpecificUtil} from "../../../ChainSpecificUtil.sol"; import {VRFV2PlusClient} from "../libraries/VRFV2PlusClient.sol"; +import {IVRFV2PlusWrapper} from "../../interfaces/IVRFV2PlusWrapper.sol"; contract VRFV2PlusWrapperLoadTestConsumer is VRFV2PlusWrapperConsumerBase, ConfirmedOwner { uint256 public s_responseCount; @@ -13,7 +14,8 @@ contract VRFV2PlusWrapperLoadTestConsumer is VRFV2PlusWrapperConsumerBase, Confi uint256 public s_slowestFulfillment = 0; uint256 public s_fastestFulfillment = 999; uint256 public s_lastRequestId; - mapping(uint256 => uint256) requestHeights; // requestIds to block number when rand request was made + // solhint-disable-next-line chainlink-solidity/prefix-storage-variables-with-s-underscore + mapping(uint256 => uint256) internal requestHeights; // requestIds to block number when rand request was made event WrappedRequestFulfilled(uint256 requestId, uint256[] randomWords, uint256 payment); event WrapperRequestMade(uint256 indexed requestId, uint256 paid); @@ -22,8 +24,8 @@ contract VRFV2PlusWrapperLoadTestConsumer is VRFV2PlusWrapperConsumerBase, Confi uint256 paid; bool fulfilled; uint256[] randomWords; - uint requestTimestamp; - uint fulfilmentTimestamp; + uint256 requestTimestamp; + uint256 fulfilmentTimestamp; uint256 requestBlockNumber; uint256 fulfilmentBlockNumber; bool native; @@ -94,7 +96,9 @@ contract VRFV2PlusWrapperLoadTestConsumer is VRFV2PlusWrapperConsumerBase, Confi } } + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function fulfillRandomWords(uint256 _requestId, uint256[] memory _randomWords) internal override { + // solhint-disable-next-line custom-errors require(s_requests[_requestId].paid > 0, "request not found"); uint256 fulfilmentBlockNumber = ChainSpecificUtil.getBlockNumber(); uint256 requestDelay = fulfilmentBlockNumber - requestHeights[_requestId]; @@ -126,12 +130,13 @@ contract VRFV2PlusWrapperLoadTestConsumer is VRFV2PlusWrapperConsumerBase, Confi uint256 paid, bool fulfilled, uint256[] memory randomWords, - uint requestTimestamp, - uint fulfilmentTimestamp, + uint256 requestTimestamp, + uint256 fulfilmentTimestamp, uint256 requestBlockNumber, uint256 fulfilmentBlockNumber ) { + // solhint-disable-next-line custom-errors require(s_requests[_requestId].paid > 0, "request not found"); RequestStatus memory request = s_requests[_requestId]; return ( @@ -163,6 +168,7 @@ contract VRFV2PlusWrapperLoadTestConsumer is VRFV2PlusWrapperConsumerBase, Confi /// @param amount the amount to withdraw, in wei function withdrawNative(uint256 amount) external onlyOwner { (bool success, ) = payable(owner()).call{value: amount}(""); + // solhint-disable-next-line custom-errors require(success, "withdrawNative failed"); } @@ -172,7 +178,7 @@ contract VRFV2PlusWrapperLoadTestConsumer is VRFV2PlusWrapperConsumerBase, Confi receive() external payable {} - function getBalance() public view returns (uint) { + function getBalance() public view returns (uint256) { return address(this).balance; } } diff --git a/contracts/src/v0.8/functions/dev/v0_0_0/FunctionsBillingRegistry.sol b/contracts/src/v0.8/functions/dev/v0_0_0/FunctionsBillingRegistry.sol index 3488af55cca..19dba693671 100644 --- a/contracts/src/v0.8/functions/dev/v0_0_0/FunctionsBillingRegistry.sol +++ b/contracts/src/v0.8/functions/dev/v0_0_0/FunctionsBillingRegistry.sol @@ -377,7 +377,6 @@ contract FunctionsBillingRegistry is * or reverts if at least gasAmount gas is not available. */ function callWithExactGas(uint256 gasAmount, address target, bytes memory data) private returns (bool success) { - // solhint-disable-next-line no-inline-assembly assembly { let g := gas() // GAS_FOR_CALL_EXACT_CHECK = 5000 diff --git a/contracts/src/v0.8/functions/dev/v1_0_0/FunctionsCoordinator.sol b/contracts/src/v0.8/functions/dev/v1_0_0/FunctionsCoordinator.sol index 540b382d652..daafe593a7b 100644 --- a/contracts/src/v0.8/functions/dev/v1_0_0/FunctionsCoordinator.sol +++ b/contracts/src/v0.8/functions/dev/v1_0_0/FunctionsCoordinator.sol @@ -2,7 +2,6 @@ pragma solidity ^0.8.19; import {IFunctionsCoordinator} from "./interfaces/IFunctionsCoordinator.sol"; -import {IFunctionsBilling} from "./interfaces/IFunctionsBilling.sol"; import {ITypeAndVersion} from "../../../shared/interfaces/ITypeAndVersion.sol"; import {FunctionsBilling} from "./FunctionsBilling.sol"; diff --git a/contracts/src/v0.8/functions/dev/v1_0_0/FunctionsRouter.sol b/contracts/src/v0.8/functions/dev/v1_0_0/FunctionsRouter.sol index 41cd90341f3..9051fd26d44 100644 --- a/contracts/src/v0.8/functions/dev/v1_0_0/FunctionsRouter.sol +++ b/contracts/src/v0.8/functions/dev/v1_0_0/FunctionsRouter.sol @@ -402,7 +402,6 @@ contract FunctionsRouter is IFunctionsRouter, FunctionsSubscriptions, Pausable, address client ) private returns (CallbackResult memory) { bool destinationNoLongerExists; - // solhint-disable-next-line no-inline-assembly assembly { // solidity calls check that a contract actually exists at the destination, so we do the same destinationNoLongerExists := iszero(extcodesize(client)) @@ -432,7 +431,6 @@ contract FunctionsRouter is IFunctionsRouter, FunctionsSubscriptions, Pausable, // allocate return data memory ahead of time bytes memory returnData = new bytes(MAX_CALLBACK_RETURN_BYTES); - // solhint-disable-next-line no-inline-assembly assembly { let g := gas() // Compute g -= gasForCallExactCheck and check for underflow diff --git a/contracts/src/v0.8/functions/dev/v1_0_0/FunctionsSubscriptions.sol b/contracts/src/v0.8/functions/dev/v1_0_0/FunctionsSubscriptions.sol index 864225fd38c..9a390a93fce 100644 --- a/contracts/src/v0.8/functions/dev/v1_0_0/FunctionsSubscriptions.sol +++ b/contracts/src/v0.8/functions/dev/v1_0_0/FunctionsSubscriptions.sol @@ -3,15 +3,12 @@ pragma solidity ^0.8.19; import {IFunctionsSubscriptions} from "./interfaces/IFunctionsSubscriptions.sol"; import {IERC677Receiver} from "../../../shared/interfaces/IERC677Receiver.sol"; -import {LinkTokenInterface} from "../../../shared/interfaces/LinkTokenInterface.sol"; import {IFunctionsBilling} from "./interfaces/IFunctionsBilling.sol"; -import {IFunctionsRouter} from "./interfaces/IFunctionsRouter.sol"; import {FunctionsResponse} from "./libraries/FunctionsResponse.sol"; import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/IERC20.sol"; import {SafeERC20} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/utils/SafeERC20.sol"; -import {SafeCast} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/utils/math/SafeCast.sol"; /// @title Functions Subscriptions contract /// @notice Contract that coordinates payment from users to the nodes of the Decentralized Oracle Network (DON). diff --git a/contracts/src/v0.8/functions/dev/v1_0_0/libraries/FunctionsResponse.sol b/contracts/src/v0.8/functions/dev/v1_0_0/libraries/FunctionsResponse.sol index 31a33169226..65fad665d69 100644 --- a/contracts/src/v0.8/functions/dev/v1_0_0/libraries/FunctionsResponse.sol +++ b/contracts/src/v0.8/functions/dev/v1_0_0/libraries/FunctionsResponse.sol @@ -1,8 +1,6 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.19; -import {IFunctionsSubscriptions} from "../interfaces/IFunctionsSubscriptions.sol"; - /// @title Library of types that are used for fulfillment of a Functions request library FunctionsResponse { // Used to send request information from the Router to the Coordinator diff --git a/contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/mocks/FunctionsBillingRegistryMigration.sol b/contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/mocks/FunctionsBillingRegistryMigration.sol index f9e6649d026..d70fd3645e9 100644 --- a/contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/mocks/FunctionsBillingRegistryMigration.sol +++ b/contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/mocks/FunctionsBillingRegistryMigration.sol @@ -6,7 +6,6 @@ import {AggregatorV3Interface} from "../../../../../interfaces/AggregatorV3Inter import {FunctionsBillingRegistryInterface} from "./FunctionsBillingRegistryInterface.sol"; import {FunctionsOracleInterface} from "./FunctionsOracleInterface.sol"; import {FunctionsClientInterface} from "./FunctionsClientInterface.sol"; -import {TypeAndVersionInterface} from "../../../../../interfaces/TypeAndVersionInterface.sol"; import {IERC677Receiver} from "../../../../../shared/interfaces/IERC677Receiver.sol"; import {AuthorizedOriginReceiverInterface} from "./AuthorizedOriginReceiverInterface.sol"; import {ConfirmedOwnerUpgradeable} from "./ConfirmedOwnerUpgradeable.sol"; @@ -372,7 +371,6 @@ contract FunctionsBillingRegistryMigration is * or reverts if at least gasAmount gas is not available. */ function callWithExactGas(uint256 gasAmount, address target, bytes memory data) private returns (bool success) { - // solhint-disable-next-line no-inline-assembly assembly { let g := gas() // GAS_FOR_CALL_EXACT_CHECK = 5000 diff --git a/contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/mocks/FunctionsBillingRegistryOriginal.sol b/contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/mocks/FunctionsBillingRegistryOriginal.sol index 39bff270401..a11d57f90e2 100644 --- a/contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/mocks/FunctionsBillingRegistryOriginal.sol +++ b/contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/mocks/FunctionsBillingRegistryOriginal.sol @@ -6,7 +6,6 @@ import {AggregatorV3Interface} from "../../../../../interfaces/AggregatorV3Inter import {FunctionsOracleInterface} from "./FunctionsOracleInterface.sol"; import {FunctionsBillingRegistryInterface} from "./FunctionsBillingRegistryInterface.sol"; import {FunctionsClientInterface} from "./FunctionsClientInterface.sol"; -import {TypeAndVersionInterface} from "../../../../../interfaces/TypeAndVersionInterface.sol"; import {IERC677Receiver} from "../../../../../shared/interfaces/IERC677Receiver.sol"; import {AuthorizedOriginReceiverInterface} from "./AuthorizedOriginReceiverInterface.sol"; import {ConfirmedOwnerUpgradeable} from "./ConfirmedOwnerUpgradeable.sol"; @@ -372,7 +371,6 @@ contract FunctionsBillingRegistryOriginal is * or reverts if at least gasAmount gas is not available. */ function callWithExactGas(uint256 gasAmount, address target, bytes memory data) private returns (bool success) { - // solhint-disable-next-line no-inline-assembly assembly { let g := gas() // GAS_FOR_CALL_EXACT_CHECK = 5000 diff --git a/contracts/src/v0.8/interfaces/AggregatorV2V3Interface.sol b/contracts/src/v0.8/interfaces/AggregatorV2V3Interface.sol index 4cb40c104e1..c023e3d2f90 100644 --- a/contracts/src/v0.8/interfaces/AggregatorV2V3Interface.sol +++ b/contracts/src/v0.8/interfaces/AggregatorV2V3Interface.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import "./AggregatorInterface.sol"; -import "./AggregatorV3Interface.sol"; +import {AggregatorInterface} from "./AggregatorInterface.sol"; +import {AggregatorV3Interface} from "./AggregatorV3Interface.sol"; interface AggregatorV2V3Interface is AggregatorInterface, AggregatorV3Interface {} diff --git a/contracts/src/v0.8/interfaces/FeedRegistryInterface.sol b/contracts/src/v0.8/interfaces/FeedRegistryInterface.sol index 512939b38fe..1d2367d82a8 100644 --- a/contracts/src/v0.8/interfaces/FeedRegistryInterface.sol +++ b/contracts/src/v0.8/interfaces/FeedRegistryInterface.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.0; pragma abicoder v2; -import "./AggregatorV2V3Interface.sol"; +import {AggregatorV2V3Interface} from "./AggregatorV2V3Interface.sol"; interface FeedRegistryInterface { struct Phase { diff --git a/contracts/src/v0.8/interfaces/OperatorInterface.sol b/contracts/src/v0.8/interfaces/OperatorInterface.sol index 14922649159..668c167cf4b 100644 --- a/contracts/src/v0.8/interfaces/OperatorInterface.sol +++ b/contracts/src/v0.8/interfaces/OperatorInterface.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import "./OracleInterface.sol"; -import "./ChainlinkRequestInterface.sol"; +import {OracleInterface} from "./OracleInterface.sol"; +import {ChainlinkRequestInterface} from "./ChainlinkRequestInterface.sol"; interface OperatorInterface is OracleInterface, ChainlinkRequestInterface { function operatorRequest( diff --git a/contracts/src/v0.8/l2ep/dev/arbitrum/ArbitrumSequencerUptimeFeed.sol b/contracts/src/v0.8/l2ep/dev/arbitrum/ArbitrumSequencerUptimeFeed.sol index 3c09fb9acad..5c9b3268c7f 100644 --- a/contracts/src/v0.8/l2ep/dev/arbitrum/ArbitrumSequencerUptimeFeed.sol +++ b/contracts/src/v0.8/l2ep/dev/arbitrum/ArbitrumSequencerUptimeFeed.sol @@ -2,7 +2,6 @@ pragma solidity ^0.8.4; import {AddressAliasHelper} from "../../../vendor/arb-bridge-eth/v0.8.0-custom/contracts/libraries/AddressAliasHelper.sol"; -import {ForwarderInterface} from "./../interfaces/ForwarderInterface.sol"; import {AggregatorInterface} from "../../../interfaces/AggregatorInterface.sol"; import {AggregatorV3Interface} from "../../../interfaces/AggregatorV3Interface.sol"; import {AggregatorV2V3Interface} from "../../../interfaces/AggregatorV2V3Interface.sol"; @@ -10,7 +9,6 @@ import {TypeAndVersionInterface} from "../../../interfaces/TypeAndVersionInterfa import {FlagsInterface} from "./../../../dev/interfaces/FlagsInterface.sol"; import {ArbitrumSequencerUptimeFeedInterface} from "../interfaces/ArbitrumSequencerUptimeFeedInterface.sol"; import {SimpleReadAccessController} from "../../../shared/access/SimpleReadAccessController.sol"; -import {ConfirmedOwner} from "../../../shared/access/ConfirmedOwner.sol"; /** * @title ArbitrumSequencerUptimeFeed - L2 sequencer uptime status aggregator diff --git a/contracts/src/v0.8/l2ep/dev/optimism/OptimismSequencerUptimeFeed.sol b/contracts/src/v0.8/l2ep/dev/optimism/OptimismSequencerUptimeFeed.sol index a4ef57505b5..af7ccc90574 100644 --- a/contracts/src/v0.8/l2ep/dev/optimism/OptimismSequencerUptimeFeed.sol +++ b/contracts/src/v0.8/l2ep/dev/optimism/OptimismSequencerUptimeFeed.sol @@ -7,7 +7,6 @@ import {AggregatorV2V3Interface} from "../../../interfaces/AggregatorV2V3Interfa import {TypeAndVersionInterface} from "../../../interfaces/TypeAndVersionInterface.sol"; import {OptimismSequencerUptimeFeedInterface} from "./../interfaces/OptimismSequencerUptimeFeedInterface.sol"; import {SimpleReadAccessController} from "../../../shared/access/SimpleReadAccessController.sol"; -import {ConfirmedOwner} from "../../../shared/access/ConfirmedOwner.sol"; import {IL2CrossDomainMessenger} from "@eth-optimism/contracts/L2/messaging/IL2CrossDomainMessenger.sol"; /** diff --git a/contracts/src/v0.8/libraries/ByteUtil.sol b/contracts/src/v0.8/libraries/ByteUtil.sol index 906fef3fa77..9691cfb7fea 100644 --- a/contracts/src/v0.8/libraries/ByteUtil.sol +++ b/contracts/src/v0.8/libraries/ByteUtil.sol @@ -16,7 +16,7 @@ library ByteUtil { * @param offset Position to start reading from. * @return result The uint256 read from the byte array. */ - function readUint256(bytes memory data, uint256 offset) internal pure returns (uint256 result) { + function _readUint256(bytes memory data, uint256 offset) internal pure returns (uint256 result) { //bounds check if (offset + 32 > data.length) revert MalformedData(); @@ -32,7 +32,7 @@ library ByteUtil { * @param offset Position to start reading from. * @return result The uint192 read from the byte array. */ - function readUint192(bytes memory data, uint256 offset) internal pure returns (uint256 result) { + function _readUint192(bytes memory data, uint256 offset) internal pure returns (uint256 result) { //bounds check if (offset + 24 > data.length) revert MalformedData(); @@ -50,7 +50,7 @@ library ByteUtil { * @param offset Position to start reading from. * @return result The uint32 read from the byte array. */ - function readUint32(bytes memory data, uint256 offset) internal pure returns (uint256 result) { + function _readUint32(bytes memory data, uint256 offset) internal pure returns (uint256 result) { //bounds check if (offset + 4 > data.length) revert MalformedData(); @@ -68,7 +68,7 @@ library ByteUtil { * @param offset Position to start reading from. * @return result The uint32 read from the byte array. */ - function readAddress(bytes memory data, uint256 offset) internal pure returns (address result) { + function _readAddress(bytes memory data, uint256 offset) internal pure returns (address result) { //bounds check if (offset + 20 > data.length) revert MalformedData(); diff --git a/contracts/src/v0.8/libraries/Common.sol b/contracts/src/v0.8/libraries/Common.sol index 5bb8275c72e..fe04a9af71b 100644 --- a/contracts/src/v0.8/libraries/Common.sol +++ b/contracts/src/v0.8/libraries/Common.sol @@ -24,7 +24,7 @@ library Common { * @param recipients The array of AddressAndWeight to check * @return bool True if there are duplicates, false otherwise */ - function hasDuplicateAddresses(Common.AddressAndWeight[] memory recipients) internal pure returns (bool) { + function _hasDuplicateAddresses(Common.AddressAndWeight[] memory recipients) internal pure returns (bool) { for (uint256 i = 0; i < recipients.length; ) { for (uint256 j = i + 1; j < recipients.length; ) { if (recipients[i].addr == recipients[j].addr) { diff --git a/contracts/src/v0.8/libraries/test/ByteUtilTest.t.sol b/contracts/src/v0.8/libraries/test/ByteUtilTest.t.sol index eabae4f5729..0629d0235ee 100644 --- a/contracts/src/v0.8/libraries/test/ByteUtilTest.t.sol +++ b/contracts/src/v0.8/libraries/test/ByteUtilTest.t.sol @@ -17,7 +17,7 @@ contract ByteUtilTest is Test { function test_readUint256Max() public { //read the first 32 bytes - uint256 result = B_512.readUint256(0); + uint256 result = B_512._readUint256(0); //the result should be the max value of a uint256 assertEq(result, type(uint256).max); @@ -25,7 +25,7 @@ contract ByteUtilTest is Test { function test_readUint192Max() public { //read the first 24 bytes - uint256 result = B_512.readUint192(0); + uint256 result = B_512._readUint192(0); //the result should be the max value of a uint192 assertEq(result, type(uint192).max); @@ -33,7 +33,7 @@ contract ByteUtilTest is Test { function test_readUint32Max() public { //read the first 4 bytes - uint256 result = B_512.readUint32(0); + uint256 result = B_512._readUint32(0); //the result should be the max value of a uint32 assertEq(result, type(uint32).max); @@ -41,7 +41,7 @@ contract ByteUtilTest is Test { function test_readUint256Min() public { //read the second 32 bytes - uint256 result = B_512.readUint256(32); + uint256 result = B_512._readUint256(32); //the result should be the min value of a uint256 assertEq(result, type(uint256).min); @@ -49,7 +49,7 @@ contract ByteUtilTest is Test { function test_readUint192Min() public { //read the second 24 bytes - uint256 result = B_512.readUint192(32); + uint256 result = B_512._readUint192(32); //the result should be the min value of a uint192 assertEq(result, type(uint192).min); @@ -57,7 +57,7 @@ contract ByteUtilTest is Test { function test_readUint32Min() public { //read the second 4 bytes - uint256 result = B_512.readUint32(32); + uint256 result = B_512._readUint32(32); //the result should be the min value of a uint32 assertEq(result, type(uint32).min); @@ -65,7 +65,7 @@ contract ByteUtilTest is Test { function test_readUint256MultiWord() public { //read the first 32 bytes - uint256 result = B_512.readUint256(31); + uint256 result = B_512._readUint256(31); //the result should be the last byte from the first word (ff), and 31 bytes from the second word (0000) (0xFF...0000) assertEq(result, type(uint256).max << 248); @@ -73,7 +73,7 @@ contract ByteUtilTest is Test { function test_readUint192MultiWord() public { //read the first 24 bytes - uint256 result = B_512.readUint192(31); + uint256 result = B_512._readUint192(31); //the result should be the last byte from the first word (ff), and 23 bytes from the second word (0000) (0xFF...0000) assertEq(result, type(uint192).max << 184); @@ -81,7 +81,7 @@ contract ByteUtilTest is Test { function test_readUint32MultiWord() public { //read the first 4 bytes - uint256 result = B_512.readUint32(31); + uint256 result = B_512._readUint32(31); //the result should be the last byte from the first word (ff), and 3 bytes from the second word (0000) (0xFF...0000) assertEq(result, type(uint32).max << 24); @@ -92,7 +92,7 @@ contract ByteUtilTest is Test { vm.expectRevert(MALFORMED_ERROR_SELECTOR); //try and read 32 bytes from a 16 byte number - B_128.readUint256(0); + B_128._readUint256(0); } function test_readUint192WithNotEnoughBytes() public { @@ -100,7 +100,7 @@ contract ByteUtilTest is Test { vm.expectRevert(MALFORMED_ERROR_SELECTOR); //try and read 24 bytes from a 16 byte number - B_128.readUint192(0); + B_128._readUint192(0); } function test_readUint32WithNotEnoughBytes() public { @@ -108,7 +108,7 @@ contract ByteUtilTest is Test { vm.expectRevert(MALFORMED_ERROR_SELECTOR); //try and read 4 bytes from a 2 byte number - B_16.readUint32(0); + B_16._readUint32(0); } function test_readUint256WithEmptyArray() public { @@ -116,7 +116,7 @@ contract ByteUtilTest is Test { vm.expectRevert(MALFORMED_ERROR_SELECTOR); //read 20 bytes from an empty array - B_EMPTY.readUint256(0); + B_EMPTY._readUint256(0); } function test_readUint192WithEmptyArray() public { @@ -124,7 +124,7 @@ contract ByteUtilTest is Test { vm.expectRevert(MALFORMED_ERROR_SELECTOR); //read 20 bytes from an empty array - B_EMPTY.readUint192(0); + B_EMPTY._readUint192(0); } function test_readUint32WithEmptyArray() public { @@ -132,12 +132,12 @@ contract ByteUtilTest is Test { vm.expectRevert(MALFORMED_ERROR_SELECTOR); //read 20 bytes from an empty array - B_EMPTY.readUint32(0); + B_EMPTY._readUint32(0); } function test_readAddress() public { //read the first 20 bytes - address result = B_512.readAddress(0); + address result = B_512._readAddress(0); //the result should be the max value of a uint256 assertEq(result, address(type(uint160).max)); @@ -145,7 +145,7 @@ contract ByteUtilTest is Test { function test_readZeroAddress() public { //read the first 32 bytes after the first word - address result = B_512.readAddress(32); + address result = B_512._readAddress(32); //the result should be 0x00...0 assertEq(result, address(type(uint160).min)); @@ -153,7 +153,7 @@ contract ByteUtilTest is Test { function test_readAddressMultiWord() public { //read the first 20 bytes after byte 13 - address result = B_512.readAddress(13); + address result = B_512._readAddress(13); //the result should be the value last 19 bytes of the first word (ffff..) and the first byte of the second word (00) (0xFFFF..00) assertEq(result, address(type(uint160).max << 8)); @@ -164,7 +164,7 @@ contract ByteUtilTest is Test { vm.expectRevert(MALFORMED_ERROR_SELECTOR); //read 20 bytes from a 16 byte array - B_128.readAddress(0); + B_128._readAddress(0); } function test_readAddressWithEmptyArray() public { @@ -172,6 +172,6 @@ contract ByteUtilTest is Test { vm.expectRevert(MALFORMED_ERROR_SELECTOR); //read the first 20 bytes of an empty array - B_EMPTY.readAddress(0); + B_EMPTY._readAddress(0); } } diff --git a/contracts/src/v0.8/llo-feeds/RewardManager.sol b/contracts/src/v0.8/llo-feeds/RewardManager.sol index f4bd835c256..e064bff8b67 100644 --- a/contracts/src/v0.8/llo-feeds/RewardManager.sol +++ b/contracts/src/v0.8/llo-feeds/RewardManager.sol @@ -5,7 +5,6 @@ import {ConfirmedOwner} from "../shared/access/ConfirmedOwner.sol"; import {IRewardManager} from "./interfaces/IRewardManager.sol"; import {IERC20} from "../vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/IERC20.sol"; import {TypeAndVersionInterface} from "../interfaces/TypeAndVersionInterface.sol"; -import {IERC165} from "../vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/IERC165.sol"; import {Common} from "../libraries/Common.sol"; import {SafeERC20} from "../vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/utils/SafeERC20.sol"; @@ -200,7 +199,7 @@ contract RewardManager is IRewardManager, ConfirmedOwner, TypeAndVersionInterfac uint256 expectedWeight ) internal { //we can't update the weights if it contains duplicates - if (Common.hasDuplicateAddresses(rewardRecipientAndWeights)) revert InvalidAddress(); + if (Common._hasDuplicateAddresses(rewardRecipientAndWeights)) revert InvalidAddress(); //loop all the reward recipients and validate the weight and address uint256 totalWeight; diff --git a/contracts/src/v0.8/llo-feeds/Verifier.sol b/contracts/src/v0.8/llo-feeds/Verifier.sol index dbd5fc73abc..cd7e3d2bad6 100644 --- a/contracts/src/v0.8/llo-feeds/Verifier.sol +++ b/contracts/src/v0.8/llo-feeds/Verifier.sol @@ -173,7 +173,7 @@ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface { address private immutable i_verifierProxyAddr; /// @notice Verifier states keyed on Feed ID - mapping(bytes32 => VerifierState) s_feedVerifierStates; + mapping(bytes32 => VerifierState) internal s_feedVerifierStates; /// @param verifierProxyAddr The address of the VerifierProxy contract constructor(address verifierProxyAddr) ConfirmedOwner(msg.sender) { diff --git a/contracts/src/v0.8/llo-feeds/test/fee-manager/BaseFeeManager.t.sol b/contracts/src/v0.8/llo-feeds/test/fee-manager/BaseFeeManager.t.sol index ef46ad37853..c446150406e 100644 --- a/contracts/src/v0.8/llo-feeds/test/fee-manager/BaseFeeManager.t.sol +++ b/contracts/src/v0.8/llo-feeds/test/fee-manager/BaseFeeManager.t.sol @@ -3,7 +3,6 @@ pragma solidity 0.8.16; import {Test} from "forge-std/Test.sol"; import {FeeManager} from "../../FeeManager.sol"; -import {IFeeManager} from "../../interfaces/IFeeManager.sol"; import {RewardManager} from "../../RewardManager.sol"; import {Common} from "../../../libraries/Common.sol"; import {ERC20Mock} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/mocks/ERC20Mock.sol"; diff --git a/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.general.t.sol b/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.general.t.sol index 105c140b73a..e2c9916f663 100644 --- a/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.general.t.sol +++ b/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.general.t.sol @@ -1,9 +1,6 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.16; -import {Test} from "forge-std/Test.sol"; -import {FeeManager} from "../../FeeManager.sol"; -import {Common} from "../../../libraries/Common.sol"; import "./BaseFeeManager.t.sol"; /** diff --git a/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.getFeeAndReward.t.sol b/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.getFeeAndReward.t.sol index dcabe6e5f9d..801a1e39925 100644 --- a/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.getFeeAndReward.t.sol +++ b/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.getFeeAndReward.t.sol @@ -1,9 +1,6 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.16; -import {Test} from "forge-std/Test.sol"; -import {FeeManager} from "../../FeeManager.sol"; -import {IFeeManager} from "../../interfaces/IFeeManager.sol"; import {Common} from "../../../libraries/Common.sol"; import "./BaseFeeManager.t.sol"; diff --git a/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.processFee.t.sol b/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.processFee.t.sol index 91fb42a500f..9c2bd711ed5 100644 --- a/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.processFee.t.sol +++ b/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.processFee.t.sol @@ -1,8 +1,6 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.16; -import {Test} from "forge-std/Test.sol"; -import {FeeManager} from "../../FeeManager.sol"; import {Common} from "../../../libraries/Common.sol"; import "./BaseFeeManager.t.sol"; import {IRewardManager} from "../../interfaces/IRewardManager.sol"; diff --git a/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.processFeeBulk.t.sol b/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.processFeeBulk.t.sol index 25fb804630d..3570b8824a8 100644 --- a/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.processFeeBulk.t.sol +++ b/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.processFeeBulk.t.sol @@ -1,9 +1,6 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.16; -import {Test} from "forge-std/Test.sol"; -import {FeeManager} from "../../FeeManager.sol"; -import {Common} from "../../../libraries/Common.sol"; import "./BaseFeeManager.t.sol"; import {IRewardManager} from "../../interfaces/IRewardManager.sol"; diff --git a/contracts/src/v0.8/llo-feeds/test/gas/Gas_VerifierTest.t.sol b/contracts/src/v0.8/llo-feeds/test/gas/Gas_VerifierTest.t.sol index 5e601034bb8..3198576e8aa 100644 --- a/contracts/src/v0.8/llo-feeds/test/gas/Gas_VerifierTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/test/gas/Gas_VerifierTest.t.sol @@ -2,7 +2,6 @@ pragma solidity 0.8.16; import {BaseTest, BaseTestWithConfiguredVerifierAndFeeManager} from "../verifier/BaseVerifierTest.t.sol"; -import {Verifier} from "../../Verifier.sol"; import {SimpleWriteAccessController} from "../../../shared/access/SimpleWriteAccessController.sol"; import {Common} from "../../../libraries/Common.sol"; import {IRewardManager} from "../../interfaces/IRewardManager.sol"; diff --git a/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.general.t.sol b/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.general.t.sol index befe6bfce93..9cee5b05c57 100644 --- a/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.general.t.sol +++ b/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.general.t.sol @@ -2,7 +2,6 @@ pragma solidity 0.8.16; import {BaseRewardManagerTest} from "./BaseRewardManager.t.sol"; -import {Common} from "../../../libraries/Common.sol"; import {RewardManager} from "../../RewardManager.sol"; import {ERC20Mock} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/mocks/ERC20Mock.sol"; import {IRewardManager} from "../../interfaces/IRewardManager.sol"; diff --git a/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.payRecipients.t.sol b/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.payRecipients.t.sol index 5dcf1eeae4f..0f94805da69 100644 --- a/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.payRecipients.t.sol +++ b/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.payRecipients.t.sol @@ -2,7 +2,6 @@ pragma solidity 0.8.16; import {BaseRewardManagerTest} from "./BaseRewardManager.t.sol"; -import {Common} from "../../../libraries/Common.sol"; import {IRewardManager} from "../../interfaces/IRewardManager.sol"; /** diff --git a/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.setRecipients.t.sol b/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.setRecipients.t.sol index 58cce9a9154..0e45ba00da4 100644 --- a/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.setRecipients.t.sol +++ b/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.setRecipients.t.sol @@ -3,7 +3,6 @@ pragma solidity 0.8.16; import {BaseRewardManagerTest} from "./BaseRewardManager.t.sol"; import {Common} from "../../../libraries/Common.sol"; -import {RewardManager} from "../../RewardManager.sol"; /** * @title BaseRewardManagerTest diff --git a/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.updateRewardRecipients.t.sol b/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.updateRewardRecipients.t.sol index e6f964f9f9f..4b3063ac016 100644 --- a/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.updateRewardRecipients.t.sol +++ b/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.updateRewardRecipients.t.sol @@ -3,7 +3,6 @@ pragma solidity 0.8.16; import {BaseRewardManagerTest} from "./BaseRewardManager.t.sol"; import {Common} from "../../../libraries/Common.sol"; -import {RewardManager} from "../../RewardManager.sol"; /** * @title BaseRewardManagerTest diff --git a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierActivateConfigTest.t.sol b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierActivateConfigTest.t.sol index 641d2772595..8838beded9d 100644 --- a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierActivateConfigTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierActivateConfigTest.t.sol @@ -3,7 +3,6 @@ pragma solidity 0.8.16; import {BaseTestWithConfiguredVerifierAndFeeManager, BaseTestWithMultipleConfiguredDigests} from "./BaseVerifierTest.t.sol"; import {Verifier} from "../../Verifier.sol"; -import {VerifierProxy} from "../../VerifierProxy.sol"; contract VerifierActivateConfigTest is BaseTestWithConfiguredVerifierAndFeeManager { function test_revertsIfNotOwner() public { diff --git a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierDeactivateFeedTest.t.sol b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierDeactivateFeedTest.t.sol index fc6814d3bfe..70e65a60300 100644 --- a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierDeactivateFeedTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierDeactivateFeedTest.t.sol @@ -3,7 +3,6 @@ pragma solidity 0.8.16; import {BaseTestWithConfiguredVerifierAndFeeManager, BaseTestWithMultipleConfiguredDigests} from "./BaseVerifierTest.t.sol"; import {Verifier} from "../../Verifier.sol"; -import {VerifierProxy} from "../../VerifierProxy.sol"; contract VerifierActivateFeedTest is BaseTestWithConfiguredVerifierAndFeeManager { function test_revertsIfNotOwnerActivateFeed() public { diff --git a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyConstructorTest.t.sol b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyConstructorTest.t.sol index 7de7dea03d1..8410d655897 100644 --- a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyConstructorTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyConstructorTest.t.sol @@ -2,7 +2,6 @@ pragma solidity 0.8.16; import {BaseTest} from "./BaseVerifierTest.t.sol"; -import {IVerifier} from "../../interfaces/IVerifier.sol"; import {VerifierProxy} from "../../VerifierProxy.sol"; import {AccessControllerInterface} from "../../../shared/interfaces/AccessControllerInterface.sol"; diff --git a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyInitializeVerifierTest.t.sol b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyInitializeVerifierTest.t.sol index 66ddb4bf3c3..f73d93af18c 100644 --- a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyInitializeVerifierTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyInitializeVerifierTest.t.sol @@ -2,9 +2,7 @@ pragma solidity 0.8.16; import {BaseTest} from "./BaseVerifierTest.t.sol"; -import {IVerifier} from "../../interfaces/IVerifier.sol"; import {VerifierProxy} from "../../VerifierProxy.sol"; -import {AccessControllerInterface} from "../../../shared/interfaces/AccessControllerInterface.sol"; contract VerifierProxyInitializeVerifierTest is BaseTest { bytes32 latestDigest; diff --git a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxySetVerifierTest.t.sol b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxySetVerifierTest.t.sol index 9fa2f16d900..3699aaf420d 100644 --- a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxySetVerifierTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxySetVerifierTest.t.sol @@ -4,7 +4,6 @@ pragma solidity 0.8.16; import {BaseTestWithConfiguredVerifierAndFeeManager} from "./BaseVerifierTest.t.sol"; import {IVerifier} from "../../interfaces/IVerifier.sol"; import {VerifierProxy} from "../../VerifierProxy.sol"; -import {AccessControllerInterface} from "../../../shared/interfaces/AccessControllerInterface.sol"; import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/IERC165.sol"; import {Common} from "../../../libraries/Common.sol"; diff --git a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyTest.t.sol b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyTest.t.sol index 5aa3e791ed8..9b5f94acd4b 100644 --- a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyTest.t.sol @@ -2,11 +2,7 @@ pragma solidity 0.8.16; import {BaseTestWithConfiguredVerifierAndFeeManager} from "./BaseVerifierTest.t.sol"; -import {IVerifier} from "../../interfaces/IVerifier.sol"; import {VerifierProxy} from "../../VerifierProxy.sol"; -import {AccessControllerInterface} from "../../../shared/interfaces/AccessControllerInterface.sol"; -import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/IERC165.sol"; -import {Common} from "../../../libraries/Common.sol"; import {FeeManager} from "../../FeeManager.sol"; contract VerifierProxyInitializeVerifierTest is BaseTestWithConfiguredVerifierAndFeeManager { diff --git a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyUnsetVerifierTest.t.sol b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyUnsetVerifierTest.t.sol index a64d6ee0f78..95a42e52edc 100644 --- a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyUnsetVerifierTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyUnsetVerifierTest.t.sol @@ -2,7 +2,6 @@ pragma solidity 0.8.16; import {BaseTest, BaseTestWithConfiguredVerifierAndFeeManager} from "./BaseVerifierTest.t.sol"; -import {IVerifier} from "../../interfaces/IVerifier.sol"; import {VerifierProxy} from "../../VerifierProxy.sol"; contract VerifierProxyUnsetVerifierTest is BaseTest { diff --git a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierSetConfigFromSourceTest.t.sol b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierSetConfigFromSourceTest.t.sol index 57c98622f5b..6c5eac9b6dd 100644 --- a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierSetConfigFromSourceTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierSetConfigFromSourceTest.t.sol @@ -2,8 +2,6 @@ pragma solidity 0.8.16; import {BaseTest, BaseTestWithMultipleConfiguredDigests} from "./BaseVerifierTest.t.sol"; -import {Verifier} from "../../Verifier.sol"; -import {VerifierProxy} from "../../VerifierProxy.sol"; import {Common} from "../../../libraries/Common.sol"; contract VerifierSetConfigFromSourceTest is BaseTest { diff --git a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierSetConfigTest.t.sol b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierSetConfigTest.t.sol index faa1f98bc30..f0b045e7f30 100644 --- a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierSetConfigTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierSetConfigTest.t.sol @@ -3,7 +3,6 @@ pragma solidity 0.8.16; import {BaseTest, BaseTestWithMultipleConfiguredDigests} from "./BaseVerifierTest.t.sol"; import {Verifier} from "../../Verifier.sol"; -import {VerifierProxy} from "../../VerifierProxy.sol"; import {Common} from "../../../libraries/Common.sol"; contract VerifierSetConfigTest is BaseTest { diff --git a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierTest.t.sol b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierTest.t.sol index 1b4340495fc..290eaa1d568 100644 --- a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierTest.t.sol @@ -3,7 +3,6 @@ pragma solidity 0.8.16; import {BaseTest} from "./BaseVerifierTest.t.sol"; import {Verifier} from "../../Verifier.sol"; -import {VerifierProxy} from "../../VerifierProxy.sol"; contract VerifierConstructorTest is BaseTest { function test_revertsIfInitializedWithEmptyVerifierProxy() public { diff --git a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierTestBillingReport.t.sol b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierTestBillingReport.t.sol index fffa291b0d8..52281298d48 100644 --- a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierTestBillingReport.t.sol +++ b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierTestBillingReport.t.sol @@ -2,9 +2,6 @@ pragma solidity 0.8.16; import {BaseTestWithConfiguredVerifierAndFeeManager} from "./BaseVerifierTest.t.sol"; -import {Verifier} from "../../Verifier.sol"; -import {VerifierProxy} from "../../VerifierProxy.sol"; -import {Common} from "../../../libraries/Common.sol"; contract VerifierTestWithConfiguredVerifierAndFeeManager is BaseTestWithConfiguredVerifierAndFeeManager { uint256 internal constant DEFAULT_LINK_MINT_QUANTITY = 100 ether; diff --git a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierUnsetConfigTest.t.sol b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierUnsetConfigTest.t.sol index 467c5072d55..41c484a8787 100644 --- a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierUnsetConfigTest.t.sol +++ b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierUnsetConfigTest.t.sol @@ -1,9 +1,8 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.16; -import {BaseTestWithConfiguredVerifierAndFeeManager, BaseTestWithMultipleConfiguredDigests} from "./BaseVerifierTest.t.sol"; +import {BaseTestWithMultipleConfiguredDigests} from "./BaseVerifierTest.t.sol"; import {Verifier} from "../../Verifier.sol"; -import {VerifierProxy} from "../../VerifierProxy.sol"; contract VerificationdeactivateConfigWhenThereAreMultipleDigestsTest is BaseTestWithMultipleConfiguredDigests { function test_revertsIfCalledByNonOwner() public { diff --git a/contracts/src/v0.8/shared/access/ConfirmedOwner.sol b/contracts/src/v0.8/shared/access/ConfirmedOwner.sol index a33cff10bc9..a25d92ffd67 100644 --- a/contracts/src/v0.8/shared/access/ConfirmedOwner.sol +++ b/contracts/src/v0.8/shared/access/ConfirmedOwner.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import "./ConfirmedOwnerWithProposal.sol"; +import {ConfirmedOwnerWithProposal} from "./ConfirmedOwnerWithProposal.sol"; /** * @title The ConfirmedOwner contract diff --git a/contracts/src/v0.8/shared/access/ConfirmedOwnerWithProposal.sol b/contracts/src/v0.8/shared/access/ConfirmedOwnerWithProposal.sol index c2a01cfca18..a6757c38869 100644 --- a/contracts/src/v0.8/shared/access/ConfirmedOwnerWithProposal.sol +++ b/contracts/src/v0.8/shared/access/ConfirmedOwnerWithProposal.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import "../interfaces/IOwnable.sol"; +import {IOwnable} from "../interfaces/IOwnable.sol"; /** * @title The ConfirmedOwner contract @@ -15,6 +15,7 @@ contract ConfirmedOwnerWithProposal is IOwnable { event OwnershipTransferred(address indexed from, address indexed to); constructor(address newOwner, address pendingOwner) { + // solhint-disable-next-line custom-errors require(newOwner != address(0), "Cannot set owner to zero"); s_owner = newOwner; @@ -35,6 +36,7 @@ contract ConfirmedOwnerWithProposal is IOwnable { * @notice Allows an ownership transfer to be completed by the recipient. */ function acceptOwnership() external override { + // solhint-disable-next-line custom-errors require(msg.sender == s_pendingOwner, "Must be proposed owner"); address oldOwner = s_owner; @@ -55,6 +57,7 @@ contract ConfirmedOwnerWithProposal is IOwnable { * @notice validate, transfer ownership, and emit relevant events */ function _transferOwnership(address to) private { + // solhint-disable-next-line custom-errors require(to != msg.sender, "Cannot transfer to self"); s_pendingOwner = to; @@ -66,6 +69,7 @@ contract ConfirmedOwnerWithProposal is IOwnable { * @notice validate access */ function _validateOwnership() internal view { + // solhint-disable-next-line custom-errors require(msg.sender == s_owner, "Only callable by owner"); } diff --git a/contracts/src/v0.8/shared/access/SimpleReadAccessController.sol b/contracts/src/v0.8/shared/access/SimpleReadAccessController.sol index ade1c15c86b..b36fa4e4b60 100644 --- a/contracts/src/v0.8/shared/access/SimpleReadAccessController.sol +++ b/contracts/src/v0.8/shared/access/SimpleReadAccessController.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import "./SimpleWriteAccessController.sol"; +import {SimpleWriteAccessController} from "./SimpleWriteAccessController.sol"; /** * @title SimpleReadAccessController @@ -20,6 +20,7 @@ contract SimpleReadAccessController is SimpleWriteAccessController { * @param _user The address to query */ function hasAccess(address _user, bytes memory _calldata) public view virtual override returns (bool) { + // solhint-disable-next-line avoid-tx-origin return super.hasAccess(_user, _calldata) || _user == tx.origin; } } diff --git a/contracts/src/v0.8/shared/access/SimpleWriteAccessController.sol b/contracts/src/v0.8/shared/access/SimpleWriteAccessController.sol index c73dec470b2..117d2e77dd6 100644 --- a/contracts/src/v0.8/shared/access/SimpleWriteAccessController.sol +++ b/contracts/src/v0.8/shared/access/SimpleWriteAccessController.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import "./ConfirmedOwner.sol"; -import "../interfaces/AccessControllerInterface.sol"; +import {ConfirmedOwner} from "./ConfirmedOwner.sol"; +import {AccessControllerInterface} from "../interfaces/AccessControllerInterface.sol"; /** * @title SimpleWriteAccessController @@ -13,7 +13,7 @@ import "../interfaces/AccessControllerInterface.sol"; */ contract SimpleWriteAccessController is AccessControllerInterface, ConfirmedOwner { bool public checkEnabled; - mapping(address => bool) internal accessList; + mapping(address => bool) internal s_accessList; event AddedAccess(address user); event RemovedAccess(address user); @@ -29,7 +29,7 @@ contract SimpleWriteAccessController is AccessControllerInterface, ConfirmedOwne * @param _user The address to query */ function hasAccess(address _user, bytes memory) public view virtual override returns (bool) { - return accessList[_user] || !checkEnabled; + return s_accessList[_user] || !checkEnabled; } /** @@ -37,8 +37,8 @@ contract SimpleWriteAccessController is AccessControllerInterface, ConfirmedOwne * @param _user The address to add */ function addAccess(address _user) external onlyOwner { - if (!accessList[_user]) { - accessList[_user] = true; + if (!s_accessList[_user]) { + s_accessList[_user] = true; emit AddedAccess(_user); } @@ -49,8 +49,8 @@ contract SimpleWriteAccessController is AccessControllerInterface, ConfirmedOwne * @param _user The address to remove */ function removeAccess(address _user) external onlyOwner { - if (accessList[_user]) { - accessList[_user] = false; + if (s_accessList[_user]) { + s_accessList[_user] = false; emit RemovedAccess(_user); } @@ -82,6 +82,7 @@ contract SimpleWriteAccessController is AccessControllerInterface, ConfirmedOwne * @dev reverts if the caller does not have access */ modifier checkAccess() { + // solhint-disable-next-line custom-errors require(hasAccess(msg.sender, msg.data), "No access"); _; } diff --git a/contracts/src/v0.8/shared/interfaces/IWERC20.sol b/contracts/src/v0.8/shared/interfaces/IWERC20.sol index e79712a593d..96073530482 100644 --- a/contracts/src/v0.8/shared/interfaces/IWERC20.sol +++ b/contracts/src/v0.8/shared/interfaces/IWERC20.sol @@ -4,5 +4,5 @@ pragma solidity ^0.8.0; interface IWERC20 { function deposit() external payable; - function withdraw(uint) external; + function withdraw(uint256) external; } diff --git a/contracts/src/v0.8/shared/mocks/WERC20Mock.sol b/contracts/src/v0.8/shared/mocks/WERC20Mock.sol index 11bdb790c02..02c13be9937 100644 --- a/contracts/src/v0.8/shared/mocks/WERC20Mock.sol +++ b/contracts/src/v0.8/shared/mocks/WERC20Mock.sol @@ -6,8 +6,8 @@ import {ERC20} from "../../vendor/openzeppelin-solidity/v4.8.0/contracts/token/E contract WERC20Mock is ERC20 { constructor() ERC20("WERC20Mock", "WERC") {} - event Deposit(address indexed dst, uint wad); - event Withdrawal(address indexed src, uint wad); + event Deposit(address indexed dst, uint256 wad); + event Withdrawal(address indexed src, uint256 wad); receive() external payable { deposit(); @@ -18,7 +18,8 @@ contract WERC20Mock is ERC20 { emit Deposit(msg.sender, msg.value); } - function withdraw(uint wad) public { + function withdraw(uint256 wad) public { + // solhint-disable-next-line custom-errors, reason-string require(balanceOf(msg.sender) >= wad); _burn(msg.sender, wad); payable(msg.sender).transfer(wad); diff --git a/contracts/src/v0.8/shared/ocr2/OCR2Abstract.sol b/contracts/src/v0.8/shared/ocr2/OCR2Abstract.sol index 5031a528b3d..1f19d0de54e 100644 --- a/contracts/src/v0.8/shared/ocr2/OCR2Abstract.sol +++ b/contracts/src/v0.8/shared/ocr2/OCR2Abstract.sol @@ -5,8 +5,11 @@ import {ITypeAndVersion} from "../interfaces/ITypeAndVersion.sol"; abstract contract OCR2Abstract is ITypeAndVersion { // Maximum number of oracles the offchain reporting protocol is designed for + // solhint-disable-next-line chainlink-solidity/all-caps-constant-storage-variables uint256 internal constant maxNumOracles = 31; + // solhint-disable-next-line chainlink-solidity/all-caps-constant-storage-variables uint256 private constant prefixMask = type(uint256).max << (256 - 16); // 0xFFFF00..00 + // solhint-disable-next-line chainlink-solidity/all-caps-constant-storage-variables uint256 private constant prefix = 0x0001 << (256 - 16); // 0x000100..00 /** diff --git a/contracts/src/v0.8/shared/test/token/ERC677/BurnMintERC677.t.sol b/contracts/src/v0.8/shared/test/token/ERC677/BurnMintERC677.t.sol index 6b223f51236..6b13f390009 100644 --- a/contracts/src/v0.8/shared/test/token/ERC677/BurnMintERC677.t.sol +++ b/contracts/src/v0.8/shared/test/token/ERC677/BurnMintERC677.t.sol @@ -8,7 +8,6 @@ import {BaseTest} from "../../BaseTest.t.sol"; import {BurnMintERC677} from "../../../token/ERC677/BurnMintERC677.sol"; import {IERC20} from "../../../../vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/IERC20.sol"; -import {Strings} from "../../../../vendor/openzeppelin-solidity/v4.8.0/contracts/utils/Strings.sol"; import {IERC165} from "../../../../vendor/openzeppelin-solidity/v4.8.0/contracts/utils/introspection/IERC165.sol"; contract BurnMintERC677Setup is BaseTest { diff --git a/contracts/src/v0.8/shared/token/ERC20/IOptimismMintableERC20.sol b/contracts/src/v0.8/shared/token/ERC20/IOptimismMintableERC20.sol index 79441cf89f7..6362d9e78ac 100644 --- a/contracts/src/v0.8/shared/token/ERC20/IOptimismMintableERC20.sol +++ b/contracts/src/v0.8/shared/token/ERC20/IOptimismMintableERC20.sol @@ -1,4 +1,5 @@ // SPDX-License-Identifier: MIT +// solhint-disable one-contract-per-file pragma solidity ^0.8.0; import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/utils/introspection/IERC165.sol"; diff --git a/contracts/src/v0.8/shared/token/ERC677/BurnMintERC677.sol b/contracts/src/v0.8/shared/token/ERC677/BurnMintERC677.sol index 0d78581b13c..775d5fb3d94 100644 --- a/contracts/src/v0.8/shared/token/ERC677/BurnMintERC677.sol +++ b/contracts/src/v0.8/shared/token/ERC677/BurnMintERC677.sol @@ -91,6 +91,7 @@ contract BurnMintERC677 is IBurnMintERC20, ERC677, IERC165, ERC20Burnable, Owner /// @dev Reverts with an empty revert to be compatible with the existing link token when /// the recipient is this contract address. modifier validAddress(address recipient) virtual { + // solhint-disable-next-line reason-string, custom-errors if (recipient == address(this)) revert(); _; } diff --git a/contracts/src/v0.8/shared/token/ERC677/ERC677.sol b/contracts/src/v0.8/shared/token/ERC677/ERC677.sol index de124d53c55..c9a2996e8e9 100644 --- a/contracts/src/v0.8/shared/token/ERC677/ERC677.sol +++ b/contracts/src/v0.8/shared/token/ERC677/ERC677.sol @@ -13,7 +13,7 @@ contract ERC677 is IERC677, ERC20 { constructor(string memory name, string memory symbol) ERC20(name, symbol) {} /// @inheritdoc IERC677 - function transferAndCall(address to, uint amount, bytes memory data) public returns (bool success) { + function transferAndCall(address to, uint256 amount, bytes memory data) public returns (bool success) { super.transfer(to, amount); emit Transfer(msg.sender, to, amount, data); if (to.isContract()) { diff --git a/contracts/src/v0.8/vrf/BatchBlockhashStore.sol b/contracts/src/v0.8/vrf/BatchBlockhashStore.sol index c6c3a888289..bdd906897fa 100644 --- a/contracts/src/v0.8/vrf/BatchBlockhashStore.sol +++ b/contracts/src/v0.8/vrf/BatchBlockhashStore.sol @@ -1,7 +1,8 @@ // SPDX-License-Identifier: MIT +// solhint-disable-next-line one-contract-per-file pragma solidity 0.8.6; -import "../ChainSpecificUtil.sol"; +import {ChainSpecificUtil} from "../ChainSpecificUtil.sol"; /** * @title BatchBlockhashStore @@ -11,6 +12,7 @@ import "../ChainSpecificUtil.sol"; * in times of high network congestion. */ contract BatchBlockhashStore { + // solhint-disable-next-line chainlink-solidity/prefix-immutable-variables-with-i BlockhashStore public immutable BHS; constructor(address blockhashStoreAddr) { @@ -40,6 +42,7 @@ contract BatchBlockhashStore { * @param headers the rlp-encoded block headers of blockNumbers[i] + 1. */ function storeVerifyHeader(uint256[] memory blockNumbers, bytes[] memory headers) public { + // solhint-disable-next-line custom-errors require(blockNumbers.length == headers.length, "input array arg lengths mismatch"); for (uint256 i = 0; i < blockNumbers.length; i++) { BHS.storeVerifyHeader(blockNumbers[i], headers[i]); @@ -70,6 +73,7 @@ contract BatchBlockhashStore { * using the blockhash() instruction. * @param blockNumber the block number to check if it's storeable with blockhash() */ + // solhint-disable-next-line chainlink-solidity/prefix-private-functions-with-underscore function storeableBlock(uint256 blockNumber) private view returns (bool) { // handle edge case on simulated chains which possibly have < 256 blocks total. return ChainSpecificUtil.getBlockNumber() <= 256 ? true : blockNumber >= (ChainSpecificUtil.getBlockNumber() - 256); diff --git a/contracts/src/v0.8/vrf/BatchVRFCoordinatorV2.sol b/contracts/src/v0.8/vrf/BatchVRFCoordinatorV2.sol index 83f0a78359d..1072289e88e 100644 --- a/contracts/src/v0.8/vrf/BatchVRFCoordinatorV2.sol +++ b/contracts/src/v0.8/vrf/BatchVRFCoordinatorV2.sol @@ -1,7 +1,8 @@ // SPDX-License-Identifier: MIT +// solhint-disable-next-line one-contract-per-file pragma solidity 0.8.6; -import "./VRFTypes.sol"; +import {VRFTypes} from "./VRFTypes.sol"; /** * @title BatchVRFCoordinatorV2 @@ -9,6 +10,7 @@ import "./VRFTypes.sol"; * provided VRFCoordinatorV2 contract efficiently in a single transaction. */ contract BatchVRFCoordinatorV2 { + // solhint-disable-next-line chainlink-solidity/prefix-immutable-variables-with-i VRFCoordinatorV2 public immutable COORDINATOR; event ErrorReturned(uint256 indexed requestId, string reason); @@ -24,6 +26,7 @@ contract BatchVRFCoordinatorV2 { * @param rcs the request commitments corresponding to the randomness proofs. */ function fulfillRandomWords(VRFTypes.Proof[] memory proofs, VRFTypes.RequestCommitment[] memory rcs) external { + // solhint-disable-next-line custom-errors require(proofs.length == rcs.length, "input array arg lengths mismatch"); for (uint256 i = 0; i < proofs.length; i++) { try COORDINATOR.fulfillRandomWords(proofs[i], rcs[i]) returns (uint96 /* payment */) { @@ -42,6 +45,7 @@ contract BatchVRFCoordinatorV2 { * @notice Returns the proving key hash associated with this public key. * @param publicKey the key to return the hash of. */ + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function hashOfKey(uint256[2] memory publicKey) internal pure returns (bytes32) { return keccak256(abi.encode(publicKey)); } @@ -50,6 +54,7 @@ contract BatchVRFCoordinatorV2 { * @notice Returns the request ID of the request associated with the given proof. * @param proof the VRF proof provided by the VRF oracle. */ + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function getRequestIdFromProof(VRFTypes.Proof memory proof) internal pure returns (uint256) { bytes32 keyHash = hashOfKey(proof.pk); return uint256(keccak256(abi.encode(keyHash, proof.seed))); diff --git a/contracts/src/v0.8/vrf/VRF.sol b/contracts/src/v0.8/vrf/VRF.sol index a6c35c79043..7ec5f2d5a60 100644 --- a/contracts/src/v0.8/vrf/VRF.sol +++ b/contracts/src/v0.8/vrf/VRF.sol @@ -142,6 +142,7 @@ contract VRF { // (base^exponent) % FIELD_SIZE // Cribbed from https://medium.com/@rbkhmrcr/precompiles-solidity-e5d29bd428c4 + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function bigModExp(uint256 base, uint256 exponent) internal view returns (uint256 exponentiation) { uint256 callResult; uint256[6] memory bigModExpContractInputs; @@ -153,7 +154,6 @@ contract VRF { bigModExpContractInputs[5] = FIELD_SIZE; uint256[1] memory output; assembly { - // solhint-disable-line no-inline-assembly callResult := staticcall( not(0), // Gas cost: no limit 0x05, // Bigmodexp contract address @@ -164,6 +164,7 @@ contract VRF { ) } if (callResult == 0) { + // solhint-disable-next-line custom-errors revert("bigModExp failure!"); } return output[0]; @@ -174,11 +175,13 @@ contract VRF { uint256 private constant SQRT_POWER = (FIELD_SIZE + 1) >> 2; // Computes a s.t. a^2 = x in the field. Assumes a exists + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function squareRoot(uint256 x) internal view returns (uint256) { return bigModExp(x, SQRT_POWER); } // The value of y^2 given that (x,y) is on secp256k1. + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function ySquared(uint256 x) internal pure returns (uint256) { // Curve is y^2=x^3+7. See section 2.4.1 of https://www.secg.org/sec2-v2.pdf uint256 xCubed = mulmod(x, mulmod(x, x, FIELD_SIZE), FIELD_SIZE); @@ -186,15 +189,19 @@ contract VRF { } // True iff p is on secp256k1 + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function isOnCurve(uint256[2] memory p) internal pure returns (bool) { // Section 2.3.6. in https://www.secg.org/sec1-v2.pdf // requires each ordinate to be in [0, ..., FIELD_SIZE-1] + // solhint-disable-next-line custom-errors require(p[0] < FIELD_SIZE, "invalid x-ordinate"); + // solhint-disable-next-line custom-errors require(p[1] < FIELD_SIZE, "invalid y-ordinate"); return ySquared(p[0]) == mulmod(p[1], p[1], FIELD_SIZE); } // Hash x uniformly into {0, ..., FIELD_SIZE-1}. + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function fieldHash(bytes memory b) internal pure returns (uint256 x_) { x_ = uint256(keccak256(b)); // Rejecting if x >= FIELD_SIZE corresponds to step 2.1 in section 2.3.4 of @@ -211,6 +218,7 @@ contract VRF { // step 5.C, which references arbitrary_string_to_point, defined in // https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vrf-05#section-5.5 as // returning the point with given x ordinate, and even y ordinate. + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function newCandidateSecp256k1Point(bytes memory b) internal view returns (uint256[2] memory p) { unchecked { p[0] = fieldHash(b); @@ -241,6 +249,7 @@ contract VRF { // // This would greatly simplify the analysis in "OTHER SECURITY CONSIDERATIONS" // https://www.pivotaltracker.com/story/show/171120900 + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function hashToCurve(uint256[2] memory pk, uint256 input) internal view returns (uint256[2] memory rv) { rv = newCandidateSecp256k1Point(abi.encodePacked(HASH_TO_CURVE_HASH_PREFIX, pk, input)); while (!isOnCurve(rv)) { @@ -258,11 +267,13 @@ contract VRF { * @param product: secp256k1 expected to be multiplier * multiplicand * @return verifies true iff product==scalar*multiplicand, with cryptographically high probability */ + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function ecmulVerify( uint256[2] memory multiplicand, uint256 scalar, uint256[2] memory product ) internal pure returns (bool verifies) { + // solhint-disable-next-line custom-errors require(scalar != 0, "zero scalar"); // Rules out an ecrecover failure case uint256 x = multiplicand[0]; // x ordinate of multiplicand uint8 v = multiplicand[1] % 2 == 0 ? 27 : 28; // parity of y ordinate @@ -278,6 +289,7 @@ contract VRF { } // Returns x1/z1-x2/z2=(x1z2-x2z1)/(z1z2) in projective coordinates on P¹(𝔽ₙ) + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function projectiveSub( uint256 x1, uint256 z1, @@ -294,6 +306,7 @@ contract VRF { } // Returns x1/z1*x2/z2=(x1x2)/(z1z2), in projective coordinates on P¹(𝔽ₙ) + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function projectiveMul( uint256 x1, uint256 z1, @@ -335,6 +348,7 @@ contract VRF { @return sy @return sz */ + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function projectiveECAdd( uint256 px, uint256 py, @@ -391,6 +405,7 @@ contract VRF { // // p1 and p2 must be distinct, because projectiveECAdd doesn't handle // point doubling. + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function affineECAdd( uint256[2] memory p1, uint256[2] memory p2, @@ -400,6 +415,7 @@ contract VRF { uint256 y; uint256 z; (x, y, z) = projectiveECAdd(p1[0], p1[1], p2[0], p2[1]); + // solhint-disable-next-line custom-errors require(mulmod(z, invZ, FIELD_SIZE) == 1, "invZ must be inverse of z"); // Clear the z ordinate of the projective representation by dividing through // by it, to obtain the affine representation @@ -408,6 +424,7 @@ contract VRF { // True iff address(c*p+s*g) == lcWitness, where g is generator. (With // cryptographically high probability.) + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function verifyLinearCombinationWithGenerator( uint256 c, uint256[2] memory p, @@ -416,6 +433,7 @@ contract VRF { ) internal pure returns (bool) { // Rule out ecrecover failure modes which return address 0. unchecked { + // solhint-disable-next-line custom-errors require(lcWitness != address(0), "bad witness"); uint8 v = (p[1] % 2 == 0) ? 27 : 28; // parity of y-ordinate of p // Note this cannot wrap (X - Y % X), but we use unchecked to save @@ -440,6 +458,7 @@ contract VRF { // a proof with equal c*p1 and s*p2, they should retry with a different // proof nonce.) Assumes that all points are on secp256k1 // (which is checked in verifyVRFProof below.) + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function linearCombination( uint256 c, uint256[2] memory p1, @@ -451,8 +470,11 @@ contract VRF { ) internal pure returns (uint256[2] memory) { unchecked { // Note we are relying on the wrap around here + // solhint-disable-next-line custom-errors require((cp1Witness[0] % FIELD_SIZE) != (sp2Witness[0] % FIELD_SIZE), "points in sum must be distinct"); + // solhint-disable-next-line custom-errors require(ecmulVerify(p1, c, cp1Witness), "First mul check failed"); + // solhint-disable-next-line custom-errors require(ecmulVerify(p2, s, sp2Witness), "Second mul check failed"); return affineECAdd(cp1Witness, sp2Witness, zInv); } @@ -473,6 +495,7 @@ contract VRF { // using the compressed representation of the points, if we collated the y // parities into a single bytes32. // https://www.pivotaltracker.com/story/show/171120588 + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function scalarFromCurvePoints( uint256[2] memory hash, uint256[2] memory pk, @@ -492,6 +515,7 @@ contract VRF { // the x ordinate, and the parity of the y ordinate in the top bit of uWitness // (which I could make a uint256 without using any extra space.) Would save // about 2000 gas. https://www.pivotaltracker.com/story/show/170828567 + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function verifyVRFProof( uint256[2] memory pk, uint256[2] memory gamma, @@ -504,15 +528,20 @@ contract VRF { uint256 zInv ) internal view { unchecked { + // solhint-disable-next-line custom-errors require(isOnCurve(pk), "public key is not on curve"); + // solhint-disable-next-line custom-errors require(isOnCurve(gamma), "gamma is not on curve"); + // solhint-disable-next-line custom-errors require(isOnCurve(cGammaWitness), "cGammaWitness is not on curve"); + // solhint-disable-next-line custom-errors require(isOnCurve(sHashWitness), "sHashWitness is not on curve"); // Step 5. of IETF draft section 5.3 (pk corresponds to 5.3's Y, and here // we use the address of u instead of u itself. Also, here we add the // terms instead of taking the difference, and in the proof construction in // vrf.GenerateProof, we correspondingly take the difference instead of // taking the sum as they do in step 7 of section 5.1.) + // solhint-disable-next-line custom-errors require(verifyLinearCombinationWithGenerator(c, pk, s, uWitness), "addr(c*pk+s*g)!=_uWitness"); // Step 4. of IETF draft section 5.3 (pk corresponds to Y, seed to alpha_string) uint256[2] memory hash = hashToCurve(pk, seed); @@ -520,6 +549,7 @@ contract VRF { uint256[2] memory v = linearCombination(c, gamma, cGammaWitness, s, hash, sHashWitness, zInv); // Steps 7. and 8. of IETF draft section 5.3 uint256 derivedC = scalarFromCurvePoints(hash, pk, gamma, uWitness, v); + // solhint-disable-next-line custom-errors require(c == derivedC, "invalid proof"); } } @@ -550,6 +580,7 @@ contract VRF { * @return output i.e., the random output implied by the proof * *************************************************************************** */ + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function randomValueFromVRFProof(Proof memory proof, uint256 seed) internal view returns (uint256 output) { verifyVRFProof( proof.pk, diff --git a/contracts/src/v0.8/vrf/VRFConsumerBase.sol b/contracts/src/v0.8/vrf/VRFConsumerBase.sol index 983a5b23cb7..7661ad40a30 100644 --- a/contracts/src/v0.8/vrf/VRFConsumerBase.sol +++ b/contracts/src/v0.8/vrf/VRFConsumerBase.sol @@ -1,9 +1,9 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import "../shared/interfaces/LinkTokenInterface.sol"; +import {LinkTokenInterface} from "../shared/interfaces/LinkTokenInterface.sol"; -import "./VRFRequestIDBase.sol"; +import {VRFRequestIDBase} from "./VRFRequestIDBase.sol"; /** **************************************************************************** * @notice Interface for contracts using VRF randomness @@ -113,6 +113,7 @@ abstract contract VRFConsumerBase is VRFRequestIDBase { * @param requestId The Id initially returned by requestRandomness * @param randomness the VRF output */ + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function fulfillRandomness(bytes32 requestId, uint256 randomness) internal virtual; /** @@ -149,6 +150,7 @@ abstract contract VRFConsumerBase is VRFRequestIDBase { * @dev concurrent requests. It is passed as the first argument to * @dev fulfillRandomness. */ + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function requestRandomness(bytes32 _keyHash, uint256 _fee) internal returns (bytes32 requestId) { LINK.transferAndCall(vrfCoordinator, _fee, abi.encode(_keyHash, USER_SEED_PLACEHOLDER)); // This is the seed passed to VRFCoordinator. The oracle will mix this with @@ -165,12 +167,15 @@ abstract contract VRFConsumerBase is VRFRequestIDBase { return makeRequestId(_keyHash, vRFSeed); } + // solhint-disable-next-line chainlink-solidity/prefix-immutable-variables-with-i LinkTokenInterface internal immutable LINK; + // solhint-disable-next-line chainlink-solidity/prefix-immutable-variables-with-i address private immutable vrfCoordinator; // Nonces for each VRF key from which randomness has been requested. // // Must stay in sync with VRFCoordinator[_keyHash][this] + // solhint-disable-next-line chainlink-solidity/prefix-storage-variables-with-s-underscore mapping(bytes32 => uint256) /* keyHash */ /* nonce */ private nonces; /** @@ -188,6 +193,7 @@ abstract contract VRFConsumerBase is VRFRequestIDBase { // proof. rawFulfillRandomness then calls fulfillRandomness, after validating // the origin of the call function rawFulfillRandomness(bytes32 requestId, uint256 randomness) external { + // solhint-disable-next-line custom-errors require(msg.sender == vrfCoordinator, "Only VRFCoordinator can fulfill"); fulfillRandomness(requestId, randomness); } diff --git a/contracts/src/v0.8/vrf/VRFConsumerBaseV2.sol b/contracts/src/v0.8/vrf/VRFConsumerBaseV2.sol index e023373ab0f..ad7025fc980 100644 --- a/contracts/src/v0.8/vrf/VRFConsumerBaseV2.sol +++ b/contracts/src/v0.8/vrf/VRFConsumerBaseV2.sol @@ -96,6 +96,7 @@ pragma solidity ^0.8.4; */ abstract contract VRFConsumerBaseV2 { error OnlyCoordinatorCanFulfill(address have, address want); + // solhint-disable-next-line chainlink-solidity/prefix-immutable-variables-with-i address private immutable vrfCoordinator; /** @@ -119,6 +120,7 @@ abstract contract VRFConsumerBaseV2 { * @param requestId The Id initially returned by requestRandomness * @param randomWords the VRF output expanded to the requested number of words */ + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function fulfillRandomWords(uint256 requestId, uint256[] memory randomWords) internal virtual; // rawFulfillRandomness is called by VRFCoordinator when it receives a valid VRF diff --git a/contracts/src/v0.8/vrf/VRFCoordinatorV2.sol b/contracts/src/v0.8/vrf/VRFCoordinatorV2.sol index bed0d361b35..92cb0cdb324 100644 --- a/contracts/src/v0.8/vrf/VRFCoordinatorV2.sol +++ b/contracts/src/v0.8/vrf/VRFCoordinatorV2.sol @@ -1,20 +1,23 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.4; -import "../shared/interfaces/LinkTokenInterface.sol"; -import "../interfaces/BlockhashStoreInterface.sol"; -import "../interfaces/AggregatorV3Interface.sol"; -import "../interfaces/VRFCoordinatorV2Interface.sol"; -import "../interfaces/TypeAndVersionInterface.sol"; -import "../shared/interfaces/IERC677Receiver.sol"; -import "./VRF.sol"; -import "../shared/access/ConfirmedOwner.sol"; -import "./VRFConsumerBaseV2.sol"; -import "../ChainSpecificUtil.sol"; +import {LinkTokenInterface} from "../shared/interfaces/LinkTokenInterface.sol"; +import {BlockhashStoreInterface} from "../interfaces/BlockhashStoreInterface.sol"; +import {AggregatorV3Interface} from "../interfaces/AggregatorV3Interface.sol"; +import {VRFCoordinatorV2Interface} from "../interfaces/VRFCoordinatorV2Interface.sol"; +import {TypeAndVersionInterface} from "../interfaces/TypeAndVersionInterface.sol"; +import {IERC677Receiver} from "../shared/interfaces/IERC677Receiver.sol"; +import {VRF} from "./VRF.sol"; +import {ConfirmedOwner} from "../shared/access/ConfirmedOwner.sol"; +import {VRFConsumerBaseV2} from "./VRFConsumerBaseV2.sol"; +import {ChainSpecificUtil} from "../ChainSpecificUtil.sol"; contract VRFCoordinatorV2 is VRF, ConfirmedOwner, TypeAndVersionInterface, VRFCoordinatorV2Interface, IERC677Receiver { + // solhint-disable-next-line chainlink-solidity/prefix-immutable-variables-with-i LinkTokenInterface public immutable LINK; + // solhint-disable-next-line chainlink-solidity/prefix-immutable-variables-with-i AggregatorV3Interface public immutable LINK_ETH_FEED; + // solhint-disable-next-line chainlink-solidity/prefix-immutable-variables-with-i BlockhashStoreInterface public immutable BLOCKHASH_STORE; // We need to maintain a list of consuming addresses. @@ -413,6 +416,7 @@ contract VRFCoordinatorV2 is VRF, ConfirmedOwner, TypeAndVersionInterface, VRFCo return s_requestCommitments[requestId]; } + // solhint-disable-next-line chainlink-solidity/prefix-private-functions-with-underscore function computeRequestId( bytes32 keyHash, address sender, @@ -427,8 +431,8 @@ contract VRFCoordinatorV2 is VRF, ConfirmedOwner, TypeAndVersionInterface, VRFCo * @dev calls target address with exactly gasAmount gas and data as calldata * or reverts if at least gasAmount gas is not available. */ + // solhint-disable-next-line chainlink-solidity/prefix-private-functions-with-underscore function callWithExactGas(uint256 gasAmount, address target, bytes memory data) private returns (bool success) { - // solhint-disable-next-line no-inline-assembly assembly { let g := gas() // Compute g -= GAS_FOR_CALL_EXACT_CHECK and check for underflow @@ -457,6 +461,7 @@ contract VRFCoordinatorV2 is VRF, ConfirmedOwner, TypeAndVersionInterface, VRFCo return success; } + // solhint-disable-next-line chainlink-solidity/prefix-private-functions-with-underscore function getRandomnessFromProof( Proof memory proof, RequestCommitment memory rc @@ -569,6 +574,7 @@ contract VRFCoordinatorV2 is VRF, ConfirmedOwner, TypeAndVersionInterface, VRFCo } // Get the amount of gas used for fulfillment + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function calculatePaymentAmount( uint256 startGas, uint256 gasAfterPaymentCalculation, @@ -592,6 +598,7 @@ contract VRFCoordinatorV2 is VRF, ConfirmedOwner, TypeAndVersionInterface, VRFCo return uint96(paymentNoFee + fee); } + // solhint-disable-next-line chainlink-solidity/prefix-private-functions-with-underscore function getFeedData() private view returns (int256) { uint32 stalenessSeconds = s_config.stalenessSeconds; bool staleFallback = stalenessSeconds > 0; @@ -766,6 +773,7 @@ contract VRFCoordinatorV2 is VRF, ConfirmedOwner, TypeAndVersionInterface, VRFCo cancelSubscriptionHelper(subId, to); } + // solhint-disable-next-line chainlink-solidity/prefix-private-functions-with-underscore function cancelSubscriptionHelper(uint64 subId, address to) private nonReentrant { SubscriptionConfig memory subConfig = s_subscriptionConfigs[subId]; Subscription memory sub = s_subscriptions[subId]; diff --git a/contracts/src/v0.8/vrf/VRFOwner.sol b/contracts/src/v0.8/vrf/VRFOwner.sol index 2c4adf36e8c..055308cac42 100644 --- a/contracts/src/v0.8/vrf/VRFOwner.sol +++ b/contracts/src/v0.8/vrf/VRFOwner.sol @@ -1,9 +1,10 @@ // SPDX-License-Identifier: MIT +// solhint-disable-next-line one-contract-per-file pragma solidity ^0.8.6; import {ConfirmedOwner} from "../shared/access/ConfirmedOwner.sol"; import {AuthorizedReceiver} from "./AuthorizedReceiver.sol"; -import "./VRFTypes.sol"; +import {VRFTypes} from "./VRFTypes.sol"; // Taken from VRFCoordinatorV2.sol // Must be abi-compatible with what's there @@ -109,6 +110,7 @@ contract VRFOwner is ConfirmedOwner, AuthorizedReceiver { event RandomWordsForced(uint256 indexed requestId, uint64 indexed subId, address indexed sender); constructor(address _vrfCoordinator) ConfirmedOwner(msg.sender) { + // solhint-disable-next-line custom-errors require(_vrfCoordinator != address(0), "vrf coordinator address must be non-zero"); s_vrfCoordinator = IVRFCoordinatorV2(_vrfCoordinator); } @@ -192,6 +194,7 @@ contract VRFOwner is ConfirmedOwner, AuthorizedReceiver { * @param fallbackWeiPerUnitLink fallback eth/link price in the case of a stale feed * @param feeConfig fee tier configuration */ + // solhint-disable-next-line chainlink-solidity/prefix-private-functions-with-underscore function setConfigPrivate( uint16 minimumRequestConfirmations, uint32 maxGasLimit, @@ -233,6 +236,7 @@ contract VRFOwner is ConfirmedOwner, AuthorizedReceiver { * @dev when too many local variables are in the same scope. * @return Config struct containing all relevant configs from the VRF coordinator. */ + // solhint-disable-next-line chainlink-solidity/prefix-private-functions-with-underscore function getConfigs() private view returns (Config memory) { ( uint16 minimumRequestConfirmations, @@ -338,6 +342,7 @@ contract VRFOwner is ConfirmedOwner, AuthorizedReceiver { * @param proofSeed the proof seed * @dev Refer to VRFCoordinatorV2.getRandomnessFromProof for original implementation. */ + // solhint-disable-next-line chainlink-solidity/prefix-private-functions-with-underscore function requestIdFromProof(uint256[2] memory publicKey, uint256 proofSeed) private view returns (uint256) { bytes32 keyHash = s_vrfCoordinator.hashOfKey(publicKey); uint256 requestId = uint256(keccak256(abi.encode(keyHash, proofSeed))); diff --git a/contracts/src/v0.8/vrf/VRFRequestIDBase.sol b/contracts/src/v0.8/vrf/VRFRequestIDBase.sol index 7770640550e..ce0f6b1547a 100644 --- a/contracts/src/v0.8/vrf/VRFRequestIDBase.sol +++ b/contracts/src/v0.8/vrf/VRFRequestIDBase.sol @@ -16,6 +16,7 @@ contract VRFRequestIDBase { * @param _requester Address of the requesting contract * @param _nonce User-specific nonce at the time of the request */ + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function makeVRFInputSeed( bytes32 _keyHash, uint256 _userSeed, @@ -34,6 +35,7 @@ contract VRFRequestIDBase { * @dev Note that _vRFInputSeed is not the seed passed by the consuming * @dev contract, but the one generated by makeVRFInputSeed */ + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function makeRequestId(bytes32 _keyHash, uint256 _vRFInputSeed) internal pure returns (bytes32) { return keccak256(abi.encodePacked(_keyHash, _vRFInputSeed)); } diff --git a/contracts/src/v0.8/vrf/VRFV2Wrapper.sol b/contracts/src/v0.8/vrf/VRFV2Wrapper.sol index 101e1bdfe20..3573b972276 100644 --- a/contracts/src/v0.8/vrf/VRFV2Wrapper.sol +++ b/contracts/src/v0.8/vrf/VRFV2Wrapper.sol @@ -1,15 +1,16 @@ // SPDX-License-Identifier: MIT +// solhint-disable-next-line one-contract-per-file pragma solidity ^0.8.6; -import "../shared/access/ConfirmedOwner.sol"; -import "../interfaces/TypeAndVersionInterface.sol"; -import "./VRFConsumerBaseV2.sol"; -import "../shared/interfaces/LinkTokenInterface.sol"; -import "../interfaces/AggregatorV3Interface.sol"; -import "../interfaces/VRFCoordinatorV2Interface.sol"; -import "../interfaces/VRFV2WrapperInterface.sol"; -import "./VRFV2WrapperConsumerBase.sol"; -import "../ChainSpecificUtil.sol"; +import {ConfirmedOwner} from "../shared/access/ConfirmedOwner.sol"; +import {TypeAndVersionInterface} from "../interfaces/TypeAndVersionInterface.sol"; +import {VRFConsumerBaseV2} from "./VRFConsumerBaseV2.sol"; +import {LinkTokenInterface} from "../shared/interfaces/LinkTokenInterface.sol"; +import {AggregatorV3Interface} from "../interfaces/AggregatorV3Interface.sol"; +import {VRFCoordinatorV2Interface} from "../interfaces/VRFCoordinatorV2Interface.sol"; +import {VRFV2WrapperInterface} from "../interfaces/VRFV2WrapperInterface.sol"; +import {VRFV2WrapperConsumerBase} from "./VRFV2WrapperConsumerBase.sol"; +import {ChainSpecificUtil} from "../ChainSpecificUtil.sol"; /** * @notice A wrapper for VRFCoordinatorV2 that provides an interface better suited to one-off @@ -18,9 +19,13 @@ import "../ChainSpecificUtil.sol"; contract VRFV2Wrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsumerBaseV2, VRFV2WrapperInterface { event WrapperFulfillmentFailed(uint256 indexed requestId, address indexed consumer); + // solhint-disable-next-line chainlink-solidity/prefix-immutable-variables-with-i LinkTokenInterface public immutable LINK; + // solhint-disable-next-line chainlink-solidity/prefix-immutable-variables-with-i AggregatorV3Interface public immutable LINK_ETH_FEED; + // solhint-disable-next-line chainlink-solidity/prefix-immutable-variables-with-i ExtendedVRFCoordinatorV2Interface public immutable COORDINATOR; + // solhint-disable-next-line chainlink-solidity/prefix-immutable-variables-with-i uint64 public immutable SUBSCRIPTION_ID; /// @dev this is the size of a VRF v2 fulfillment's calldata abi-encoded in bytes. /// @dev proofSize = 13 words = 13 * 256 = 3328 bits @@ -78,10 +83,10 @@ contract VRFV2Wrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsumerBas // s_keyHash is the key hash to use when requesting randomness. Fees are paid based on current gas // fees, so this should be set to the highest gas lane on the network. - bytes32 s_keyHash; + bytes32 internal s_keyHash; // s_maxNumWords is the max number of words that can be requested in a single wrapped VRF request. - uint8 s_maxNumWords; + uint8 internal s_maxNumWords; struct Callback { address callbackAddress; @@ -237,6 +242,7 @@ contract VRFV2Wrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsumerBas return calculateRequestPriceInternal(_callbackGasLimit, _requestGasPriceWei, weiPerUnitLink); } + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function calculateRequestPriceInternal( uint256 _gas, uint256 _requestGasPrice, @@ -273,6 +279,7 @@ contract VRFV2Wrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsumerBas * uint16 requestConfirmations, and uint32 numWords. */ function onTokenTransfer(address _sender, uint256 _amount, bytes calldata _data) external onlyConfiguredNotDisabled { + // solhint-disable-next-line custom-errors require(msg.sender == address(LINK), "only callable from LINK"); (uint32 callbackGasLimit, uint16 requestConfirmations, uint32 numWords) = abi.decode( @@ -282,7 +289,9 @@ contract VRFV2Wrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsumerBas uint32 eip150Overhead = getEIP150Overhead(callbackGasLimit); int256 weiPerUnitLink = getFeedData(); uint256 price = calculateRequestPriceInternal(callbackGasLimit, tx.gasprice, weiPerUnitLink); + // solhint-disable-next-line custom-errors require(_amount >= price, "fee too low"); + // solhint-disable-next-line custom-errors require(numWords <= s_maxNumWords, "numWords too high"); uint256 requestId = COORDINATOR.requestRandomWords( @@ -328,9 +337,11 @@ contract VRFV2Wrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsumerBas s_disabled = true; } + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function fulfillRandomWords(uint256 _requestId, uint256[] memory _randomWords) internal override { Callback memory callback = s_callbacks[_requestId]; delete s_callbacks[_requestId]; + // solhint-disable-next-line custom-errors require(callback.callbackAddress != address(0), "request not found"); // This should never happen VRFV2WrapperConsumerBase c; @@ -342,6 +353,7 @@ contract VRFV2Wrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsumerBas } } + // solhint-disable-next-line chainlink-solidity/prefix-private-functions-with-underscore function getFeedData() private view returns (int256) { bool staleFallback = s_stalenessSeconds > 0; uint256 timestamp; @@ -351,6 +363,7 @@ contract VRFV2Wrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsumerBas if (staleFallback && s_stalenessSeconds < block.timestamp - timestamp) { weiPerUnitLink = s_fallbackWeiPerUnitLink; } + // solhint-disable-next-line custom-errors require(weiPerUnitLink >= 0, "Invalid LINK wei price"); return weiPerUnitLink; } @@ -358,6 +371,7 @@ contract VRFV2Wrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsumerBas /** * @dev Calculates extra amount of gas required for running an assembly call() post-EIP150. */ + // solhint-disable-next-line chainlink-solidity/prefix-private-functions-with-underscore function getEIP150Overhead(uint32 gas) private pure returns (uint32) { return gas / 63 + 1; } @@ -366,8 +380,8 @@ contract VRFV2Wrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsumerBas * @dev calls target address with exactly gasAmount gas and data as calldata * or reverts if at least gasAmount gas is not available. */ + // solhint-disable-next-line chainlink-solidity/prefix-private-functions-with-underscore function callWithExactGas(uint256 gasAmount, address target, bytes memory data) private returns (bool success) { - // solhint-disable-next-line no-inline-assembly assembly { let g := gas() // Compute g -= GAS_FOR_CALL_EXACT_CHECK and check for underflow @@ -401,7 +415,9 @@ contract VRFV2Wrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsumerBas } modifier onlyConfiguredNotDisabled() { + // solhint-disable-next-line custom-errors require(s_configured, "wrapper is not configured"); + // solhint-disable-next-line custom-errors require(!s_disabled, "wrapper is disabled"); _; } diff --git a/contracts/src/v0.8/vrf/VRFV2WrapperConsumerBase.sol b/contracts/src/v0.8/vrf/VRFV2WrapperConsumerBase.sol index 4c7918e8b7a..a9c8e5568a9 100644 --- a/contracts/src/v0.8/vrf/VRFV2WrapperConsumerBase.sol +++ b/contracts/src/v0.8/vrf/VRFV2WrapperConsumerBase.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import "../shared/interfaces/LinkTokenInterface.sol"; -import "../interfaces/VRFV2WrapperInterface.sol"; +import {LinkTokenInterface} from "../shared/interfaces/LinkTokenInterface.sol"; +import {VRFV2WrapperInterface} from "../interfaces/VRFV2WrapperInterface.sol"; /** ******************************************************************************* * @notice Interface for contracts using VRF randomness through the VRF V2 wrapper @@ -28,7 +28,9 @@ import "../interfaces/VRFV2WrapperInterface.sol"; * @dev fulfillment with the randomness result. */ abstract contract VRFV2WrapperConsumerBase { + // solhint-disable-next-line chainlink-solidity/prefix-immutable-variables-with-i LinkTokenInterface internal immutable LINK; + // solhint-disable-next-line chainlink-solidity/prefix-immutable-variables-with-i VRFV2WrapperInterface internal immutable VRF_V2_WRAPPER; /** @@ -52,6 +54,7 @@ abstract contract VRFV2WrapperConsumerBase { * * @return requestId is the VRF V2 request ID of the newly created randomness request. */ + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function requestRandomness( uint32 _callbackGasLimit, uint16 _requestConfirmations, @@ -72,9 +75,11 @@ abstract contract VRFV2WrapperConsumerBase { * @param _requestId is the VRF V2 request ID. * @param _randomWords is the randomness result. */ + // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function fulfillRandomWords(uint256 _requestId, uint256[] memory _randomWords) internal virtual; function rawFulfillRandomWords(uint256 _requestId, uint256[] memory _randomWords) external { + // solhint-disable-next-line custom-errors require(msg.sender == address(VRF_V2_WRAPPER), "only VRF V2 wrapper can fulfill"); fulfillRandomWords(_requestId, _randomWords); } diff --git a/core/gethwrappers/generated/vrfv2plus_malicious_migrator/vrfv2plus_malicious_migrator.go b/core/gethwrappers/generated/vrfv2plus_malicious_migrator/vrfv2plus_malicious_migrator.go index 043ee6e303f..c0c19a1134c 100644 --- a/core/gethwrappers/generated/vrfv2plus_malicious_migrator/vrfv2plus_malicious_migrator.go +++ b/core/gethwrappers/generated/vrfv2plus_malicious_migrator/vrfv2plus_malicious_migrator.go @@ -29,7 +29,7 @@ var ( ) var VRFV2PlusMaliciousMigratorMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_vrfCoordinator\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_vrfCoordinator\",\"type\":\"address\"}],\"name\":\"setCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_vrfCoordinator\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"setCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", Bin: "0x608060405234801561001057600080fd5b506040516102e03803806102e083398101604081905261002f91610054565b600080546001600160a01b0319166001600160a01b0392909216919091179055610084565b60006020828403121561006657600080fd5b81516001600160a01b038116811461007d57600080fd5b9392505050565b61024d806100936000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80638ea9811714610030575b600080fd5b61004361003e36600461012a565b610045565b005b600080546040805160c081018252838152602080820185905281830185905260608201859052608082018590528251908101835293845260a0810193909352517f9b1c385e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911691639b1c385e916100d49190600401610180565b602060405180830381600087803b1580156100ee57600080fd5b505af1158015610102573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101269190610167565b5050565b60006020828403121561013c57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461016057600080fd5b9392505050565b60006020828403121561017957600080fd5b5051919050565b6000602080835283518184015280840151604084015261ffff6040850151166060840152606084015163ffffffff80821660808601528060808701511660a0860152505060a084015160c08085015280518060e086015260005b818110156101f757828101840151868201610100015283016101da565b8181111561020a57600061010083880101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016939093016101000194935050505056fea164736f6c6343000806000a", } @@ -169,16 +169,16 @@ func (_VRFV2PlusMaliciousMigrator *VRFV2PlusMaliciousMigratorTransactorRaw) Tran return _VRFV2PlusMaliciousMigrator.Contract.contract.Transact(opts, method, params...) } -func (_VRFV2PlusMaliciousMigrator *VRFV2PlusMaliciousMigratorTransactor) SetCoordinator(opts *bind.TransactOpts, _vrfCoordinator common.Address) (*types.Transaction, error) { - return _VRFV2PlusMaliciousMigrator.contract.Transact(opts, "setCoordinator", _vrfCoordinator) +func (_VRFV2PlusMaliciousMigrator *VRFV2PlusMaliciousMigratorTransactor) SetCoordinator(opts *bind.TransactOpts, arg0 common.Address) (*types.Transaction, error) { + return _VRFV2PlusMaliciousMigrator.contract.Transact(opts, "setCoordinator", arg0) } -func (_VRFV2PlusMaliciousMigrator *VRFV2PlusMaliciousMigratorSession) SetCoordinator(_vrfCoordinator common.Address) (*types.Transaction, error) { - return _VRFV2PlusMaliciousMigrator.Contract.SetCoordinator(&_VRFV2PlusMaliciousMigrator.TransactOpts, _vrfCoordinator) +func (_VRFV2PlusMaliciousMigrator *VRFV2PlusMaliciousMigratorSession) SetCoordinator(arg0 common.Address) (*types.Transaction, error) { + return _VRFV2PlusMaliciousMigrator.Contract.SetCoordinator(&_VRFV2PlusMaliciousMigrator.TransactOpts, arg0) } -func (_VRFV2PlusMaliciousMigrator *VRFV2PlusMaliciousMigratorTransactorSession) SetCoordinator(_vrfCoordinator common.Address) (*types.Transaction, error) { - return _VRFV2PlusMaliciousMigrator.Contract.SetCoordinator(&_VRFV2PlusMaliciousMigrator.TransactOpts, _vrfCoordinator) +func (_VRFV2PlusMaliciousMigrator *VRFV2PlusMaliciousMigratorTransactorSession) SetCoordinator(arg0 common.Address) (*types.Transaction, error) { + return _VRFV2PlusMaliciousMigrator.Contract.SetCoordinator(&_VRFV2PlusMaliciousMigrator.TransactOpts, arg0) } func (_VRFV2PlusMaliciousMigrator *VRFV2PlusMaliciousMigrator) Address() common.Address { @@ -186,7 +186,7 @@ func (_VRFV2PlusMaliciousMigrator *VRFV2PlusMaliciousMigrator) Address() common. } type VRFV2PlusMaliciousMigratorInterface interface { - SetCoordinator(opts *bind.TransactOpts, _vrfCoordinator common.Address) (*types.Transaction, error) + SetCoordinator(opts *bind.TransactOpts, arg0 common.Address) (*types.Transaction, error) Address() common.Address } diff --git a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 5251d94e70c..ac0786a8bb5 100644 --- a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -100,7 +100,7 @@ vrfv2_wrapper_consumer_example: ../../contracts/solc/v0.8.6/VRFV2WrapperConsumer vrfv2_wrapper_interface: ../../contracts/solc/v0.8.6/VRFV2WrapperInterface.abi ../../contracts/solc/v0.8.6/VRFV2WrapperInterface.bin ff8560169de171a68b360b7438d13863682d07040d984fd0fb096b2379421003 vrfv2plus_client: ../../contracts/solc/v0.8.6/VRFV2PlusClient.abi ../../contracts/solc/v0.8.6/VRFV2PlusClient.bin 3ffbfa4971a7e5f46051a26b1722613f265d89ea1867547ecec58500953a9501 vrfv2plus_consumer_example: ../../contracts/solc/v0.8.6/VRFV2PlusConsumerExample.abi ../../contracts/solc/v0.8.6/VRFV2PlusConsumerExample.bin 2c480a6d7955d33a00690fdd943486d95802e48a03f3cc243df314448e4ddb2c -vrfv2plus_malicious_migrator: ../../contracts/solc/v0.8.6/VRFV2PlusMaliciousMigrator.abi ../../contracts/solc/v0.8.6/VRFV2PlusMaliciousMigrator.bin e5ae923d5fdfa916303cd7150b8474ccd912e14bafe950c6431f6ec94821f642 +vrfv2plus_malicious_migrator: ../../contracts/solc/v0.8.6/VRFV2PlusMaliciousMigrator.abi ../../contracts/solc/v0.8.6/VRFV2PlusMaliciousMigrator.bin 80dbc98be5e42246960c889d29488f978d3db0127e95e9b295352c481d8c9b07 vrfv2plus_reverting_example: ../../contracts/solc/v0.8.6/VRFV2PlusRevertingExample.abi ../../contracts/solc/v0.8.6/VRFV2PlusRevertingExample.bin 34743ac1dd5e2c9d210b2bd721ebd4dff3c29c548f05582538690dde07773589 vrfv2plus_wrapper: ../../contracts/solc/v0.8.6/VRFV2PlusWrapper.abi ../../contracts/solc/v0.8.6/VRFV2PlusWrapper.bin 3e1e3836e8c8bf7a6f83f571f17e258f30e6d02037e53eebf74c2af3fbcf0913 vrfv2plus_wrapper_consumer_example: ../../contracts/solc/v0.8.6/VRFV2PlusWrapperConsumerExample.abi ../../contracts/solc/v0.8.6/VRFV2PlusWrapperConsumerExample.bin 4b3da45ff177e09b1e731b5b0cf4e050033a600ef8b0d32e79eec97db5c72408 From bcb2c3ca1f1fd8726543d5adb30da9babc50e64e Mon Sep 17 00:00:00 2001 From: Sri Kidambi <1702865+kidambisrinivas@users.noreply.github.com> Date: Fri, 6 Oct 2023 23:10:39 +0300 Subject: [PATCH 05/10] Add migration support to VRFV2PlusWrapper (#10859) * Add migration support to VRFV2PlusWrapper * Add VRFV2PlusWrapper as consumer to new migrated coordinator * Add VRFV2PlusWrapper as consumer to new migrated coordinator * Add tests for migrate * Re-generate go wrappers after merge * Prettier * Move interface to separate file * Add comments and fund subscription before migration to check if funds are transferred correctly to sub in newCoordinator * Prettier * Minor fix --------- Co-authored-by: Sri Kidambi --- .../v0.8/dev/interfaces/IVRFV2PlusMigrate.sol | 15 + .../src/v0.8/dev/vrf/VRFV2PlusWrapper.sol | 9 + .../foundry/vrf/VRFV2Wrapper_Migration.t.sol | 357 ++++++++++++++++++ .../vrfv2plus_wrapper/vrfv2plus_wrapper.go | 18 +- ...rapper-dependency-versions-do-not-edit.txt | 2 +- 5 files changed, 398 insertions(+), 3 deletions(-) create mode 100644 contracts/src/v0.8/dev/interfaces/IVRFV2PlusMigrate.sol create mode 100644 contracts/test/v0.8/foundry/vrf/VRFV2Wrapper_Migration.t.sol diff --git a/contracts/src/v0.8/dev/interfaces/IVRFV2PlusMigrate.sol b/contracts/src/v0.8/dev/interfaces/IVRFV2PlusMigrate.sol new file mode 100644 index 00000000000..e1a755ff574 --- /dev/null +++ b/contracts/src/v0.8/dev/interfaces/IVRFV2PlusMigrate.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/// @notice This interface is implemented by all VRF V2+ coordinators that can +/// @notice migrate subscription data to new coordinators. +interface IVRFV2PlusMigrate { + /** + * @notice migrate the provided subscription ID to the provided VRF coordinator + * @notice msg.sender must be the subscription owner and newCoordinator must + * @notice implement IVRFCoordinatorV2PlusMigration. + * @param subId the subscription ID to migrate + * @param newCoordinator the vrf coordinator to migrate to + */ + function migrate(uint256 subId, address newCoordinator) external; +} diff --git a/contracts/src/v0.8/dev/vrf/VRFV2PlusWrapper.sol b/contracts/src/v0.8/dev/vrf/VRFV2PlusWrapper.sol index 8021f048989..29573aa2363 100644 --- a/contracts/src/v0.8/dev/vrf/VRFV2PlusWrapper.sol +++ b/contracts/src/v0.8/dev/vrf/VRFV2PlusWrapper.sol @@ -3,6 +3,7 @@ pragma solidity ^0.8.6; import {ConfirmedOwner} from "../../shared/access/ConfirmedOwner.sol"; import {TypeAndVersionInterface} from "../../interfaces/TypeAndVersionInterface.sol"; +import {IVRFV2PlusMigrate} from "../interfaces/IVRFV2PlusMigrate.sol"; import {VRFConsumerBaseV2Plus} from "./VRFConsumerBaseV2Plus.sol"; import {LinkTokenInterface} from "../../shared/interfaces/LinkTokenInterface.sol"; import {AggregatorV3Interface} from "../../interfaces/AggregatorV3Interface.sol"; @@ -578,4 +579,12 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume require(!s_disabled, "wrapper is disabled"); _; } + + /*************************************************************************** + * Section: Migration of VRFV2PlusWrapper to latest VRFV2PlusCoordinator + ***************************************************************************/ + + function migrate(address newCoordinator) external onlyOwner { + IVRFV2PlusMigrate(address(s_vrfCoordinator)).migrate(SUBSCRIPTION_ID, newCoordinator); + } } diff --git a/contracts/test/v0.8/foundry/vrf/VRFV2Wrapper_Migration.t.sol b/contracts/test/v0.8/foundry/vrf/VRFV2Wrapper_Migration.t.sol new file mode 100644 index 00000000000..e4c8a40172f --- /dev/null +++ b/contracts/test/v0.8/foundry/vrf/VRFV2Wrapper_Migration.t.sol @@ -0,0 +1,357 @@ +pragma solidity 0.8.6; + +import "../BaseTest.t.sol"; +import {VRF} from "../../../../src/v0.8/vrf/VRF.sol"; +import {MockLinkToken} from "../../../../src/v0.8/mocks/MockLinkToken.sol"; +import {MockV3Aggregator} from "../../../../src/v0.8/tests/MockV3Aggregator.sol"; +import {ExposedVRFCoordinatorV2_5} from "../../../../src/v0.8/dev/vrf/testhelpers/ExposedVRFCoordinatorV2_5.sol"; +import {VRFCoordinatorV2Plus_V2Example} from "../../../../src/v0.8/dev/vrf/testhelpers/VRFCoordinatorV2Plus_V2Example.sol"; +import {VRFV2PlusWrapperConsumerBase} from "../../../../src/v0.8/dev/vrf/VRFV2PlusWrapperConsumerBase.sol"; +import {VRFV2PlusWrapperConsumerExample} from "../../../../src/v0.8/dev/vrf/testhelpers/VRFV2PlusWrapperConsumerExample.sol"; +import {SubscriptionAPI} from "../../../../src/v0.8/dev/vrf/SubscriptionAPI.sol"; +import {VRFCoordinatorV2_5} from "../../../../src/v0.8/dev/vrf/VRFCoordinatorV2_5.sol"; +import {VRFV2PlusWrapper} from "../../../../src/v0.8/dev/vrf/VRFV2PlusWrapper.sol"; +import {VRFV2PlusClient} from "../../../../src/v0.8/dev/vrf/libraries/VRFV2PlusClient.sol"; + +contract VRFV2PlusWrapperTest is BaseTest { + address internal constant LINK_WHALE = 0xD883a6A1C22fC4AbFE938a5aDF9B2Cc31b1BF18B; + uint256 internal constant DEFAULT_NATIVE_FUNDING = 7 ether; // 7 ETH + uint256 internal constant DEFAULT_LINK_FUNDING = 10 ether; // 10 ETH + bytes32 vrfKeyHash = hex"9f2353bde94264dbc3d554a94cceba2d7d2b4fdce4304d3e09a1fea9fbeb1528"; + uint32 wrapperGasOverhead = 10_000; + uint32 coordinatorGasOverhead = 20_000; + + ExposedVRFCoordinatorV2_5 s_testCoordinator; + MockLinkToken s_linkToken; + MockV3Aggregator s_linkNativeFeed; + VRFV2PlusWrapper s_wrapper; + VRFV2PlusWrapperConsumerExample s_consumer; + + VRFCoordinatorV2Plus_V2Example s_newCoordinator; + + VRFCoordinatorV2_5.FeeConfig basicFeeConfig = + VRFCoordinatorV2_5.FeeConfig({fulfillmentFlatFeeLinkPPM: 0, fulfillmentFlatFeeNativePPM: 0}); + + event CoordinatorRegistered(address coordinatorAddress); + event MigrationCompleted(address newCoordinator, uint256 subId); + event WrapperRequestMade(uint256 indexed requestId, uint256 paid); + + function setUp() public override { + BaseTest.setUp(); + + // Fund our users. + vm.roll(1); + vm.deal(LINK_WHALE, 10_000 ether); + changePrank(LINK_WHALE); + + // Deploy link token and link/native feed. + s_linkToken = new MockLinkToken(); + s_linkNativeFeed = new MockV3Aggregator(18, 500000000000000000); // .5 ETH (good for testing) + + // Deploy coordinator and consumer. + s_testCoordinator = new ExposedVRFCoordinatorV2_5(address(0)); + s_wrapper = new VRFV2PlusWrapper(address(s_linkToken), address(s_linkNativeFeed), address(s_testCoordinator)); + s_consumer = new VRFV2PlusWrapperConsumerExample(address(s_linkToken), address(s_wrapper)); + + // Configure the coordinator. + s_testCoordinator.setLINKAndLINKNativeFeed(address(s_linkToken), address(s_linkNativeFeed)); + setConfigCoordinator(basicFeeConfig); + setConfigWrapper(); + + s_testCoordinator.s_config(); + + // Data structures for Migrateable Wrapper + s_newCoordinator = new VRFCoordinatorV2Plus_V2Example(address(0), address(s_testCoordinator)); + vm.expectEmit( + false, // no first indexed topic + false, // no second indexed topic + false, // no third indexed topic + true // check data (target coordinator address) + ); + address newCoordinatorAddr = address(s_newCoordinator); + emit CoordinatorRegistered(newCoordinatorAddr); + s_testCoordinator.registerMigratableCoordinator(newCoordinatorAddr); + assertTrue(s_testCoordinator.isTargetRegisteredExternal(newCoordinatorAddr)); + } + + function setConfigCoordinator(VRFCoordinatorV2_5.FeeConfig memory feeConfig) internal { + s_testCoordinator.setConfig( + 0, // minRequestConfirmations + 2_500_000, // maxGasLimit + 1, // stalenessSeconds + 50_000, // gasAfterPaymentCalculation + 50000000000000000, // fallbackWeiPerUnitLink + feeConfig + ); + } + + function setConfigWrapper() internal { + s_wrapper.setConfig( + wrapperGasOverhead, // wrapper gas overhead + coordinatorGasOverhead, // coordinator gas overhead + 0, // premium percentage + vrfKeyHash, // keyHash + 10, // max number of words, + 1, // stalenessSeconds + 50000000000000000, // fallbackWeiPerUnitLink + 0, // fulfillmentFlatFeeLinkPPM + 0 // fulfillmentFlatFeeNativePPM + ); + ( + , + , + , + uint32 _wrapperGasOverhead, + uint32 _coordinatorGasOverhead, + uint8 _wrapperPremiumPercentage, + bytes32 _keyHash, + uint8 _maxNumWords + ) = s_wrapper.getConfig(); + assertEq(_wrapperGasOverhead, wrapperGasOverhead); + assertEq(_coordinatorGasOverhead, coordinatorGasOverhead); + assertEq(0, _wrapperPremiumPercentage); + assertEq(vrfKeyHash, _keyHash); + assertEq(10, _maxNumWords); + } + + event RandomWordsRequested( + bytes32 indexed keyHash, + uint256 requestId, + uint256 preSeed, + uint256 indexed subId, + uint16 minimumRequestConfirmations, + uint32 callbackGasLimit, + uint32 numWords, + bytes extraArgs, + address indexed sender + ); + + function testMigrateWrapperLINKPayment() public { + s_linkToken.transfer(address(s_consumer), DEFAULT_LINK_FUNDING); + + uint256 subID = s_wrapper.SUBSCRIPTION_ID(); + address oldCoordinatorAddr = address(s_testCoordinator); + + // Fund subscription with native and LINK payment to check + // if funds are transferred to new subscription after call + // migration to new coordinator + s_linkToken.transferAndCall(oldCoordinatorAddr, DEFAULT_LINK_FUNDING, abi.encode(subID)); + s_testCoordinator.fundSubscriptionWithNative{value: DEFAULT_NATIVE_FUNDING}(subID); + + // Get type and version. + assertEq(s_wrapper.typeAndVersion(), "VRFV2Wrapper 1.0.0"); + + // subscription exists in V1 coordinator before migration + + ( + uint96 balance, + uint96 nativeBalance, + uint64 reqCount, + address owner, + address[] memory consumers + ) = s_testCoordinator.getSubscription(subID); + assertEq(reqCount, 0); + assertEq(balance, DEFAULT_LINK_FUNDING); + assertEq(nativeBalance, DEFAULT_NATIVE_FUNDING); + assertEq(owner, address(s_wrapper)); + assertEq(consumers.length, 1); + assertEq(consumers[0], address(s_wrapper)); + + vm.startPrank(LINK_WHALE); + + // Update wrapper to point to the new coordinator + vm.expectEmit( + false, // no first indexed field + false, // no second indexed field + false, // no third indexed field + true // check data fields + ); + address newCoordinatorAddr = address(s_newCoordinator); + emit MigrationCompleted(newCoordinatorAddr, subID); + + s_wrapper.migrate(newCoordinatorAddr); + + // subscription no longer exists in v1 coordinator after migration + vm.expectRevert(SubscriptionAPI.InvalidSubscription.selector); + s_testCoordinator.getSubscription(subID); + assertEq(s_testCoordinator.s_totalBalance(), 0); + assertEq(s_testCoordinator.s_totalNativeBalance(), 0); + assertEq(s_linkToken.balanceOf(oldCoordinatorAddr), 0); + assertEq(oldCoordinatorAddr.balance, 0); + + // subscription exists in v2 coordinator + (balance, nativeBalance, reqCount, owner, consumers) = s_newCoordinator.getSubscription(subID); + assertEq(owner, address(s_wrapper)); + assertEq(consumers.length, 1); + assertEq(consumers[0], address(s_wrapper)); + assertEq(reqCount, 0); + assertEq(balance, DEFAULT_LINK_FUNDING); + assertEq(nativeBalance, DEFAULT_NATIVE_FUNDING); + assertEq(s_newCoordinator.s_totalLinkBalance(), DEFAULT_LINK_FUNDING); + assertEq(s_newCoordinator.s_totalNativeBalance(), DEFAULT_NATIVE_FUNDING); + assertEq(s_linkToken.balanceOf(newCoordinatorAddr), DEFAULT_LINK_FUNDING); + assertEq(newCoordinatorAddr.balance, DEFAULT_NATIVE_FUNDING); + + // calling migrate again on V1 coordinator should fail + vm.expectRevert(); + s_wrapper.migrate(newCoordinatorAddr); + + // Request randomness from wrapper. + uint32 callbackGasLimit = 1_000_000; + vm.expectEmit(true, true, true, true); + uint256 wrapperCost = s_wrapper.calculateRequestPrice(callbackGasLimit); + emit WrapperRequestMade(1, wrapperCost); + uint256 requestId = s_consumer.makeRequest(callbackGasLimit, 0, 1); + assertEq(requestId, 1); + + (uint256 paid, bool fulfilled, bool native) = s_consumer.s_requests(requestId); + uint32 expectedPaid = (callbackGasLimit + wrapperGasOverhead + coordinatorGasOverhead) * 2; + uint256 wrapperCostEstimate = s_wrapper.estimateRequestPrice(callbackGasLimit, tx.gasprice); + uint256 wrapperCostCalculation = s_wrapper.calculateRequestPrice(callbackGasLimit); + assertEq(paid, expectedPaid); // 1_030_000 * 2 for link/native ratio + assertEq(uint256(paid), wrapperCostEstimate); + assertEq(wrapperCostEstimate, wrapperCostCalculation); + assertEq(fulfilled, false); + assertEq(native, false); + assertEq(s_linkToken.balanceOf(address(s_consumer)), DEFAULT_LINK_FUNDING - expectedPaid); + + (, uint256 gasLimit, ) = s_wrapper.s_callbacks(requestId); + assertEq(gasLimit, callbackGasLimit); + + vm.stopPrank(); + + vm.startPrank(newCoordinatorAddr); + + uint256[] memory words = new uint256[](1); + words[0] = 123; + s_wrapper.rawFulfillRandomWords(requestId, words); + (, bool nowFulfilled, uint256[] memory storedWords) = s_consumer.getRequestStatus(requestId); + assertEq(nowFulfilled, true); + assertEq(storedWords[0], 123); + + vm.stopPrank(); + + /// Withdraw funds from wrapper. + vm.startPrank(LINK_WHALE); + uint256 priorWhaleBalance = s_linkToken.balanceOf(LINK_WHALE); + s_wrapper.withdraw(LINK_WHALE, paid); + assertEq(s_linkToken.balanceOf(LINK_WHALE), priorWhaleBalance + paid); + assertEq(s_linkToken.balanceOf(address(s_wrapper)), 0); + + vm.stopPrank(); + } + + function testMigrateWrapperNativePayment() public { + vm.deal(address(s_consumer), DEFAULT_NATIVE_FUNDING); + + uint256 subID = s_wrapper.SUBSCRIPTION_ID(); + address oldCoordinatorAddr = address(s_testCoordinator); + + // Fund subscription with native and LINK payment to check + // if funds are transferred to new subscription after call + // migration to new coordinator + s_linkToken.transferAndCall(oldCoordinatorAddr, DEFAULT_LINK_FUNDING, abi.encode(subID)); + s_testCoordinator.fundSubscriptionWithNative{value: DEFAULT_NATIVE_FUNDING}(subID); + + // Get type and version. + assertEq(s_wrapper.typeAndVersion(), "VRFV2Wrapper 1.0.0"); + + // subscription exists in V1 coordinator before migration + ( + uint96 balance, + uint96 nativeBalance, + uint64 reqCount, + address owner, + address[] memory consumers + ) = s_testCoordinator.getSubscription(subID); + assertEq(reqCount, 0); + assertEq(balance, DEFAULT_LINK_FUNDING); + assertEq(nativeBalance, DEFAULT_NATIVE_FUNDING); + assertEq(owner, address(s_wrapper)); + assertEq(consumers.length, 1); + assertEq(consumers[0], address(s_wrapper)); + + vm.startPrank(LINK_WHALE); + + // Update wrapper to point to the new coordinator + vm.expectEmit( + false, // no first indexed field + false, // no second indexed field + false, // no third indexed field + true // check data fields + ); + address newCoordinatorAddr = address(s_newCoordinator); + emit MigrationCompleted(newCoordinatorAddr, subID); + + s_wrapper.migrate(newCoordinatorAddr); + + // subscription no longer exists in v1 coordinator after migration + vm.expectRevert(SubscriptionAPI.InvalidSubscription.selector); + s_testCoordinator.getSubscription(subID); + assertEq(s_testCoordinator.s_totalBalance(), 0); + assertEq(s_testCoordinator.s_totalNativeBalance(), 0); + assertEq(s_linkToken.balanceOf(oldCoordinatorAddr), 0); + assertEq(oldCoordinatorAddr.balance, 0); + + // subscription exists in v2 coordinator + (balance, nativeBalance, reqCount, owner, consumers) = s_newCoordinator.getSubscription(subID); + assertEq(owner, address(s_wrapper)); + assertEq(consumers.length, 1); + assertEq(consumers[0], address(s_wrapper)); + assertEq(reqCount, 0); + assertEq(balance, DEFAULT_LINK_FUNDING); + assertEq(nativeBalance, DEFAULT_NATIVE_FUNDING); + assertEq(s_newCoordinator.s_totalLinkBalance(), DEFAULT_LINK_FUNDING); + assertEq(s_newCoordinator.s_totalNativeBalance(), DEFAULT_NATIVE_FUNDING); + assertEq(s_linkToken.balanceOf(newCoordinatorAddr), DEFAULT_LINK_FUNDING); + assertEq(newCoordinatorAddr.balance, DEFAULT_NATIVE_FUNDING); + + // calling migrate again on V1 coordinator should fail + vm.expectRevert(); + s_wrapper.migrate(newCoordinatorAddr); + + // Request randomness from wrapper. + uint32 callbackGasLimit = 1_000_000; + vm.expectEmit(true, true, true, true); + uint256 wrapperCost = s_wrapper.calculateRequestPriceNative(callbackGasLimit); + emit WrapperRequestMade(1, wrapperCost); + uint256 requestId = s_consumer.makeRequestNative(callbackGasLimit, 0, 1); + assertEq(requestId, 1); + + (uint256 paid, bool fulfilled, bool native) = s_consumer.s_requests(requestId); + uint32 expectedPaid = callbackGasLimit + wrapperGasOverhead + coordinatorGasOverhead; + uint256 wrapperNativeCostEstimate = s_wrapper.estimateRequestPriceNative(callbackGasLimit, tx.gasprice); + uint256 wrapperCostCalculation = s_wrapper.calculateRequestPriceNative(callbackGasLimit); + assertEq(paid, expectedPaid); + assertEq(uint256(paid), wrapperNativeCostEstimate); + assertEq(wrapperNativeCostEstimate, wrapperCostCalculation); + assertEq(fulfilled, false); + assertEq(native, true); + assertEq(address(s_consumer).balance, DEFAULT_NATIVE_FUNDING - expectedPaid); + + (, uint256 gasLimit, ) = s_wrapper.s_callbacks(requestId); + assertEq(gasLimit, callbackGasLimit); + + vm.stopPrank(); + + vm.startPrank(newCoordinatorAddr); + + uint256[] memory words = new uint256[](1); + words[0] = 123; + s_wrapper.rawFulfillRandomWords(requestId, words); + (, bool nowFulfilled, uint256[] memory storedWords) = s_consumer.getRequestStatus(requestId); + assertEq(nowFulfilled, true); + assertEq(storedWords[0], 123); + + vm.stopPrank(); + + // Withdraw funds from wrapper. + vm.startPrank(LINK_WHALE); + uint256 priorWhaleBalance = LINK_WHALE.balance; + s_wrapper.withdrawNative(LINK_WHALE, paid); + assertEq(LINK_WHALE.balance, priorWhaleBalance + paid); + assertEq(address(s_wrapper).balance, 0); + + vm.stopPrank(); + } +} diff --git a/core/gethwrappers/generated/vrfv2plus_wrapper/vrfv2plus_wrapper.go b/core/gethwrappers/generated/vrfv2plus_wrapper/vrfv2plus_wrapper.go index 7fe1a766a10..b94cb71c7b8 100644 --- a/core/gethwrappers/generated/vrfv2plus_wrapper/vrfv2plus_wrapper.go +++ b/core/gethwrappers/generated/vrfv2plus_wrapper/vrfv2plus_wrapper.go @@ -31,8 +31,8 @@ var ( ) var VRFV2PlusWrapperMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_link\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_linkNativeFeed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_coordinator\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"FailedToTransferLink\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"expectedMinimumLength\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"actualLength\",\"type\":\"uint16\"}],\"name\":\"IncorrectExtraArgsLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LINKPaymentInRequestRandomWordsInNative\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LinkAlreadySet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NativePaymentInOnTokenTransfer\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"have\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"want\",\"type\":\"address\"}],\"name\":\"OnlyCoordinatorCanFulfill\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"have\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"}],\"name\":\"OnlyOwnerOrCoordinator\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"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\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"WrapperFulfillmentFailed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"SUBSCRIPTION_ID\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_callbackGasLimit\",\"type\":\"uint32\"}],\"name\":\"calculateRequestPrice\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_callbackGasLimit\",\"type\":\"uint32\"}],\"name\":\"calculateRequestPriceNative\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"internalType\":\"bool\",\"name\":\"isLinkMode\",\"type\":\"bool\"}],\"name\":\"checkPaymentMode\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"disable\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"enable\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"_requestGasPriceWei\",\"type\":\"uint256\"}],\"name\":\"estimateRequestPrice\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"_requestGasPriceWei\",\"type\":\"uint256\"}],\"name\":\"estimateRequestPriceNative\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"int256\"},{\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"wrapperGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"coordinatorGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"wrapperPremiumPercentage\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"maxNumWords\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastRequestId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"randomWords\",\"type\":\"uint256[]\"}],\"name\":\"rawFulfillRandomWords\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"_requestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"_numWords\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"name\":\"requestRandomWordsInNative\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_callbacks\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"callbackAddress\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"requestGasPrice\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_configured\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_disabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_fulfillmentTxSizeBytes\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_link\",\"outputs\":[{\"internalType\":\"contractLinkTokenInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_linkNativeFeed\",\"outputs\":[{\"internalType\":\"contractAggregatorV3Interface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_vrfCoordinator\",\"outputs\":[{\"internalType\":\"contractIVRFCoordinatorV2Plus\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_wrapperGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_coordinatorGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"_wrapperPremiumPercentage\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"_keyHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"_maxNumWords\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"int256\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"int256\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeNativePPM\",\"type\":\"uint32\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_vrfCoordinator\",\"type\":\"address\"}],\"name\":\"setCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"size\",\"type\":\"uint32\"}],\"name\":\"setFulfillmentTxSize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"link\",\"type\":\"address\"}],\"name\":\"setLINK\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"linkNativeFeed\",\"type\":\"address\"}],\"name\":\"setLinkNativeFeed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"withdrawNative\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60a06040526007805463ffffffff60201b1916650244000000001790553480156200002957600080fd5b5060405162003577380380620035778339810160408190526200004c9162000323565b803380600081620000a45760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000d757620000d7816200025a565b5050600280546001600160a01b0319166001600160a01b03938416179055508316156200012857600680546001600160601b03166c010000000000000000000000006001600160a01b038616021790555b6001600160a01b038216156200016257600780546001600160601b03166c010000000000000000000000006001600160a01b038516021790555b6002546040805163288688f960e21b815290516000926001600160a01b03169163a21a23e491600480830192602092919082900301818787803b158015620001a957600080fd5b505af1158015620001be573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001e491906200036d565b6080819052600254604051632fb1302360e21b8152600481018390523060248201529192506001600160a01b03169063bec4c08c90604401600060405180830381600087803b1580156200023757600080fd5b505af11580156200024c573d6000803e3d6000fd5b505050505050505062000387565b6001600160a01b038116331415620002b55760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200009b565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b03811681146200031e57600080fd5b919050565b6000806000606084860312156200033957600080fd5b620003448462000306565b9250620003546020850162000306565b9150620003646040850162000306565b90509250925092565b6000602082840312156200038057600080fd5b5051919050565b6080516131c6620003b1600039600081816101ef0152818161122f015261180001526131c66000f3fe6080604052600436106101d85760003560e01c80638ea9811711610102578063bf17e55911610095578063f254bdc711610064578063f254bdc7146106f2578063f2fde38b1461072f578063f3fef3a31461074f578063fc2a88c31461076f57600080fd5b8063bf17e559146105d1578063c3f909d4146105f1578063cdd8d8851461067b578063da4f5e6d146106b557600080fd5b8063a3907d71116100d1578063a3907d711461055d578063a4c0ed3614610572578063a608a1e114610592578063bed41a93146105b157600080fd5b80638ea98117146104dd5780639cfc058e146104fd5780639eccacf614610510578063a02e06161461053d57600080fd5b80634306d3541161017a5780636505965411610149578063650596541461043c57806379ba50971461045c5780637fb5d19d146104715780638da5cb5b1461049157600080fd5b80634306d3541461030757806348baa1c5146103275780634b160935146103f257806357a8070a1461041257600080fd5b806318b6f4c8116101b657806318b6f4c8146102925780631fe543e3146102b25780632f2770db146102d25780633255c456146102e757600080fd5b8063030932bb146101dd57806307b18bde14610224578063181f5a7714610246575b600080fd5b3480156101e957600080fd5b506102117f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b34801561023057600080fd5b5061024461023f366004612932565b610785565b005b34801561025257600080fd5b50604080518082018252601281527f56524656325772617070657220312e302e3000000000000000000000000000006020820152905161021b9190612dcb565b34801561029e57600080fd5b506102446102ad3660046129d3565b610861565b3480156102be57600080fd5b506102446102cd366004612a57565b6109d8565b3480156102de57600080fd5b50610244610a55565b3480156102f357600080fd5b50610211610302366004612c5a565b610a8b565b34801561031357600080fd5b50610211610322366004612b5a565b610b85565b34801561033357600080fd5b506103b1610342366004612a25565b60096020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff81169074010000000000000000000000000000000000000000810463ffffffff16907801000000000000000000000000000000000000000000000000900467ffffffffffffffff1683565b6040805173ffffffffffffffffffffffffffffffffffffffff909416845263ffffffff909216602084015267ffffffffffffffff169082015260600161021b565b3480156103fe57600080fd5b5061021161040d366004612b5a565b610c8c565b34801561041e57600080fd5b5060085461042c9060ff1681565b604051901515815260200161021b565b34801561044857600080fd5b50610244610457366004612917565b610d7d565b34801561046857600080fd5b50610244610dc8565b34801561047d57600080fd5b5061021161048c366004612c5a565b610ec5565b34801561049d57600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161021b565b3480156104e957600080fd5b506102446104f8366004612917565b610fcb565b61021161050b366004612b75565b6110d6565b34801561051c57600080fd5b506002546104b89073ffffffffffffffffffffffffffffffffffffffff1681565b34801561054957600080fd5b50610244610558366004612917565b61146b565b34801561056957600080fd5b50610244611516565b34801561057e57600080fd5b5061024461058d36600461295c565b611548565b34801561059e57600080fd5b5060085461042c90610100900460ff1681565b3480156105bd57600080fd5b506102446105cc366004612c76565b611a28565b3480156105dd57600080fd5b506102446105ec366004612b5a565b611b7e565b3480156105fd57600080fd5b506005546006546007546008546003546040805195865263ffffffff8086166020880152640100000000909504851690860152838316606086015268010000000000000000909204909216608084015260ff620100008304811660a085015260c084019190915263010000009091041660e08201526101000161021b565b34801561068757600080fd5b506007546106a090640100000000900463ffffffff1681565b60405163ffffffff909116815260200161021b565b3480156106c157600080fd5b506006546104b8906c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1681565b3480156106fe57600080fd5b506007546104b8906c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1681565b34801561073b57600080fd5b5061024461074a366004612917565b611bc5565b34801561075b57600080fd5b5061024461076a366004612932565b611bd9565b34801561077b57600080fd5b5061021160045481565b61078d611cd4565b60008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d80600081146107e7576040519150601f19603f3d011682016040523d82523d6000602084013e6107ec565b606091505b505090508061085c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f6661696c656420746f207769746864726177206e61746976650000000000000060448201526064015b60405180910390fd5b505050565b81516108a2578061089e576040517f6b81746e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b8151602411156108f35781516040517f51200dce0000000000000000000000000000000000000000000000000000000081526108539160249160040161ffff92831681529116602082015260400190565b6000826023815181106109085761090861314d565b6020910101517fff00000000000000000000000000000000000000000000000000000000000000167f010000000000000000000000000000000000000000000000000000000000000014905080801561095e5750815b15610995576040517f6048aa6800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b801580156109a1575081155b1561085c576040517f6b81746e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60025473ffffffffffffffffffffffffffffffffffffffff163314610a4b576002546040517f1cf993f400000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091166024820152604401610853565b61089e8282611d57565b610a5d611cd4565b600880547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100179055565b60085460009060ff16610afa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f77726170706572206973206e6f7420636f6e66696775726564000000000000006044820152606401610853565b600854610100900460ff1615610b6c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f777261707065722069732064697361626c6564000000000000000000000000006044820152606401610853565b610b7c8363ffffffff1683611f3f565b90505b92915050565b60085460009060ff16610bf4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f77726170706572206973206e6f7420636f6e66696775726564000000000000006044820152606401610853565b600854610100900460ff1615610c66576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f777261707065722069732064697361626c6564000000000000000000000000006044820152606401610853565b6000610c70612015565b9050610c838363ffffffff163a8361217c565b9150505b919050565b60085460009060ff16610cfb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f77726170706572206973206e6f7420636f6e66696775726564000000000000006044820152606401610853565b600854610100900460ff1615610d6d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f777261707065722069732064697361626c6564000000000000000000000000006044820152606401610853565b610b7f8263ffffffff163a611f3f565b610d85611cd4565b6007805473ffffffffffffffffffffffffffffffffffffffff9092166c01000000000000000000000000026bffffffffffffffffffffffff909216919091179055565b60015473ffffffffffffffffffffffffffffffffffffffff163314610e49576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610853565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60085460009060ff16610f34576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f77726170706572206973206e6f7420636f6e66696775726564000000000000006044820152606401610853565b600854610100900460ff1615610fa6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f777261707065722069732064697361626c6564000000000000000000000000006044820152606401610853565b6000610fb0612015565b9050610fc38463ffffffff16848361217c565b949350505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331480159061100b575060025473ffffffffffffffffffffffffffffffffffffffff163314155b1561108f573361103060005473ffffffffffffffffffffffffffffffffffffffff1690565b6002546040517f061db9c100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201529183166024830152919091166044820152606401610853565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600061111783838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052509250610861915050565b60006111228761226e565b905060006111368863ffffffff163a611f3f565b9050803410156111a2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f66656520746f6f206c6f770000000000000000000000000000000000000000006044820152606401610853565b6008546301000000900460ff1663ffffffff8716111561121e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f6e756d576f72647320746f6f20686967680000000000000000000000000000006044820152606401610853565b6040805160c08101825260035481527f0000000000000000000000000000000000000000000000000000000000000000602082015261ffff89169181019190915260075460009190606082019063ffffffff1661127b868d612ef0565b6112859190612ef0565b63ffffffff1681526020018863ffffffff16815260200187878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509152506002546040517f9b1c385e00000000000000000000000000000000000000000000000000000000815291925073ffffffffffffffffffffffffffffffffffffffff1690639b1c385e9061132b908490600401612dde565b602060405180830381600087803b15801561134557600080fd5b505af1158015611359573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061137d9190612a3e565b6040805160608101825233815263ffffffff808d16602080840191825267ffffffffffffffff3a81168587019081526000888152600990935295909120935184549251955190911678010000000000000000000000000000000000000000000000000277ffffffffffffffffffffffffffffffffffffffffffffffff9590931674010000000000000000000000000000000000000000027fffffffffffffffff00000000000000000000000000000000000000000000000090921673ffffffffffffffffffffffffffffffffffffffff91909116171792909216919091179055935050505095945050505050565b611473611cd4565b6006546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff16156114d3576040517f2d118a6e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006805473ffffffffffffffffffffffffffffffffffffffff9092166c01000000000000000000000000026bffffffffffffffffffffffff909216919091179055565b61151e611cd4565b600880547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055565b60085460ff166115b4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f77726170706572206973206e6f7420636f6e66696775726564000000000000006044820152606401610853565b600854610100900460ff1615611626576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f777261707065722069732064697361626c6564000000000000000000000000006044820152606401610853565b6006546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1633146116b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f6f6e6c792063616c6c61626c652066726f6d204c494e4b0000000000000000006044820152606401610853565b60008080806116c885870187612beb565b93509350935093506116db816001610861565b60006116e68561226e565b905060006116f2612015565b905060006117078763ffffffff163a8461217c565b9050808a1015611773576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f66656520746f6f206c6f770000000000000000000000000000000000000000006044820152606401610853565b6008546301000000900460ff1663ffffffff861611156117ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f6e756d576f72647320746f6f20686967680000000000000000000000000000006044820152606401610853565b6040805160c08101825260035481527f0000000000000000000000000000000000000000000000000000000000000000602082015261ffff88169181019190915260075460009190606082019063ffffffff1661184c878c612ef0565b6118569190612ef0565b63ffffffff908116825288166020820152604090810187905260025490517f9b1c385e00000000000000000000000000000000000000000000000000000000815291925060009173ffffffffffffffffffffffffffffffffffffffff90911690639b1c385e906118ca908590600401612dde565b602060405180830381600087803b1580156118e457600080fd5b505af11580156118f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061191c9190612a3e565b905060405180606001604052808e73ffffffffffffffffffffffffffffffffffffffff1681526020018a63ffffffff1681526020013a67ffffffffffffffff168152506009600083815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a81548163ffffffff021916908363ffffffff16021790555060408201518160000160186101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055509050508060048190555050505050505050505050505050565b611a30611cd4565b6007805463ffffffff9a8b167fffffffffffffffffffffffffffffffffffffffff00000000ffffffff000000009091161768010000000000000000998b168a02179055600880546003979097557fffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ffff9096166201000060ff988916027fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffff161763010000009590971694909402959095177fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117909355600680546005949094557fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff9187167fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009094169390931764010000000094871694909402939093179290921691909316909102179055565b611b86611cd4565b6007805463ffffffff909216640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff909216919091179055565b611bcd611cd4565b611bd681612286565b50565b611be1611cd4565b6006546040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152602482018490526c010000000000000000000000009092049091169063a9059cbb90604401602060405180830381600087803b158015611c6657600080fd5b505af1158015611c7a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c9e91906129b6565b61089e576040517f7c07fc4c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005473ffffffffffffffffffffffffffffffffffffffff163314611d55576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610853565b565b60008281526009602081815260408084208151606081018352815473ffffffffffffffffffffffffffffffffffffffff808216835274010000000000000000000000000000000000000000820463ffffffff1683870152780100000000000000000000000000000000000000000000000090910467ffffffffffffffff1693820193909352878652939092529290558051909116611e51576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f72657175657374206e6f7420666f756e640000000000000000000000000000006044820152606401610853565b600080631fe543e360e01b8585604051602401611e6f929190612e3b565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000611ee9846020015163ffffffff1685600001518461237c565b905080611f3757835160405173ffffffffffffffffffffffffffffffffffffffff9091169087907fc551b83c151f2d1c7eeb938ac59008e0409f1c1dc1e2f112449d4d79b458902290600090a35b505050505050565b6007546000908190611f5e90640100000000900463ffffffff166123c8565b60075463ffffffff680100000000000000008204811691611f80911687612ed8565b611f8a9190612ed8565b611f94908561309b565b611f9e9190612ed8565b6008549091508190600090606490611fbf9062010000900460ff1682612f18565b611fcc9060ff168461309b565b611fd69190612f3d565b6006549091506000906120009068010000000000000000900463ffffffff1664e8d4a5100061309b565b61200a9083612ed8565b979650505050505050565b600654600754604080517ffeaf968c000000000000000000000000000000000000000000000000000000008152905160009363ffffffff16151592849283926c0100000000000000000000000090920473ffffffffffffffffffffffffffffffffffffffff169163feaf968c9160048082019260a092909190829003018186803b1580156120a257600080fd5b505afa1580156120b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120da9190612d10565b50945090925084915050801561210057506120f582426130d8565b60065463ffffffff16105b1561210a57506005545b6000811215612175576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f496e76616c6964204c494e4b20776569207072696365000000000000000000006044820152606401610853565b9392505050565b600754600090819061219b90640100000000900463ffffffff166123c8565b60075463ffffffff6801000000000000000082048116916121bd911688612ed8565b6121c79190612ed8565b6121d1908661309b565b6121db9190612ed8565b90506000836121f283670de0b6b3a764000061309b565b6121fc9190612f3d565b60085490915060009060649061221b9062010000900460ff1682612f18565b6122289060ff168461309b565b6122329190612f3d565b60065490915060009061225890640100000000900463ffffffff1664e8d4a5100061309b565b6122629083612ed8565b98975050505050505050565b600061227b603f83612f51565b610b7f906001612ef0565b73ffffffffffffffffffffffffffffffffffffffff8116331415612306576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610853565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60005a61138881101561238e57600080fd5b6113888103905084604082048203116123a657600080fd5b50823b6123b257600080fd5b60008083516020850160008789f1949350505050565b6000466123d481612498565b15612478576000606c73ffffffffffffffffffffffffffffffffffffffff166341b247a86040518163ffffffff1660e01b815260040160c06040518083038186803b15801561242257600080fd5b505afa158015612436573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061245a9190612b10565b5050505091505083608c61246e9190612ed8565b610fc3908261309b565b612481816124bb565b1561248f57610c83836124f5565b50600092915050565b600061a4b18214806124ac575062066eed82145b80610b7f57505062066eee1490565b6000600a8214806124cd57506101a482145b806124da575062aa37dc82145b806124e6575061210582145b80610b7f57505062014a331490565b60008073420000000000000000000000000000000000000f73ffffffffffffffffffffffffffffffffffffffff1663519b4bd36040518163ffffffff1660e01b815260040160206040518083038186803b15801561255257600080fd5b505afa158015612566573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061258a9190612a3e565b905060008061259981866130d8565b905060006125a882601061309b565b6125b384600461309b565b6125bd9190612ed8565b9050600073420000000000000000000000000000000000000f73ffffffffffffffffffffffffffffffffffffffff16630c18c1626040518163ffffffff1660e01b815260040160206040518083038186803b15801561261b57600080fd5b505afa15801561262f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126539190612a3e565b9050600073420000000000000000000000000000000000000f73ffffffffffffffffffffffffffffffffffffffff1663f45e65d86040518163ffffffff1660e01b815260040160206040518083038186803b1580156126b157600080fd5b505afa1580156126c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126e99190612a3e565b9050600073420000000000000000000000000000000000000f73ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561274757600080fd5b505afa15801561275b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061277f9190612a3e565b9050600061278e82600a612fd5565b90506000818461279e8789612ed8565b6127a8908c61309b565b6127b2919061309b565b6127bc9190612f3d565b9b9a5050505050505050505050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610c8757600080fd5b60008083601f84011261280157600080fd5b50813567ffffffffffffffff81111561281957600080fd5b60208301915083602082850101111561283157600080fd5b9250929050565b600082601f83011261284957600080fd5b813567ffffffffffffffff8111156128635761286361317c565b61289460207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601612e89565b8181528460208386010111156128a957600080fd5b816020850160208301376000918101602001919091529392505050565b803561ffff81168114610c8757600080fd5b803563ffffffff81168114610c8757600080fd5b803560ff81168114610c8757600080fd5b805169ffffffffffffffffffff81168114610c8757600080fd5b60006020828403121561292957600080fd5b610b7c826127cb565b6000806040838503121561294557600080fd5b61294e836127cb565b946020939093013593505050565b6000806000806060858703121561297257600080fd5b61297b856127cb565b935060208501359250604085013567ffffffffffffffff81111561299e57600080fd5b6129aa878288016127ef565b95989497509550505050565b6000602082840312156129c857600080fd5b8151612175816131ab565b600080604083850312156129e657600080fd5b823567ffffffffffffffff8111156129fd57600080fd5b612a0985828601612838565b9250506020830135612a1a816131ab565b809150509250929050565b600060208284031215612a3757600080fd5b5035919050565b600060208284031215612a5057600080fd5b5051919050565b60008060408385031215612a6a57600080fd5b8235915060208084013567ffffffffffffffff80821115612a8a57600080fd5b818601915086601f830112612a9e57600080fd5b813581811115612ab057612ab061317c565b8060051b9150612ac1848301612e89565b8181528481019084860184860187018b1015612adc57600080fd5b600095505b83861015612aff578035835260019590950194918601918601612ae1565b508096505050505050509250929050565b60008060008060008060c08789031215612b2957600080fd5b865195506020870151945060408701519350606087015192506080870151915060a087015190509295509295509295565b600060208284031215612b6c57600080fd5b610b7c826128d8565b600080600080600060808688031215612b8d57600080fd5b612b96866128d8565b9450612ba4602087016128c6565b9350612bb2604087016128d8565b9250606086013567ffffffffffffffff811115612bce57600080fd5b612bda888289016127ef565b969995985093965092949392505050565b60008060008060808587031215612c0157600080fd5b612c0a856128d8565b9350612c18602086016128c6565b9250612c26604086016128d8565b9150606085013567ffffffffffffffff811115612c4257600080fd5b612c4e87828801612838565b91505092959194509250565b60008060408385031215612c6d57600080fd5b61294e836128d8565b60008060008060008060008060006101208a8c031215612c9557600080fd5b612c9e8a6128d8565b9850612cac60208b016128d8565b9750612cba60408b016128ec565b965060608a01359550612ccf60808b016128ec565b9450612cdd60a08b016128d8565b935060c08a01359250612cf260e08b016128d8565b9150612d016101008b016128d8565b90509295985092959850929598565b600080600080600060a08688031215612d2857600080fd5b612d31866128fd565b9450602086015193506040860151925060608601519150612d54608087016128fd565b90509295509295909350565b6000815180845260005b81811015612d8657602081850181015186830182015201612d6a565b81811115612d98576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610b7c6020830184612d60565b60208152815160208201526020820151604082015261ffff60408301511660608201526000606083015163ffffffff80821660808501528060808601511660a0850152505060a083015160c080840152610fc360e0840182612d60565b6000604082018483526020604081850152818551808452606086019150828701935060005b81811015612e7c57845183529383019391830191600101612e60565b5090979650505050505050565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612ed057612ed061317c565b604052919050565b60008219821115612eeb57612eeb6130ef565b500190565b600063ffffffff808316818516808303821115612f0f57612f0f6130ef565b01949350505050565b600060ff821660ff84168060ff03821115612f3557612f356130ef565b019392505050565b600082612f4c57612f4c61311e565b500490565b600063ffffffff80841680612f6857612f6861311e565b92169190910492915050565b600181815b80851115612fcd57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115612fb357612fb36130ef565b80851615612fc057918102915b93841c9390800290612f79565b509250929050565b6000610b7c8383600082612feb57506001610b7f565b81612ff857506000610b7f565b816001811461300e576002811461301857613034565b6001915050610b7f565b60ff841115613029576130296130ef565b50506001821b610b7f565b5060208310610133831016604e8410600b8410161715613057575081810a610b7f565b6130618383612f74565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115613093576130936130ef565b029392505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156130d3576130d36130ef565b500290565b6000828210156130ea576130ea6130ef565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b8015158114611bd657600080fdfea164736f6c6343000806000a", + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_link\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_linkNativeFeed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_coordinator\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"FailedToTransferLink\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"expectedMinimumLength\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"actualLength\",\"type\":\"uint16\"}],\"name\":\"IncorrectExtraArgsLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LINKPaymentInRequestRandomWordsInNative\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LinkAlreadySet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NativePaymentInOnTokenTransfer\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"have\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"want\",\"type\":\"address\"}],\"name\":\"OnlyCoordinatorCanFulfill\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"have\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"}],\"name\":\"OnlyOwnerOrCoordinator\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"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\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"WrapperFulfillmentFailed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"SUBSCRIPTION_ID\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_callbackGasLimit\",\"type\":\"uint32\"}],\"name\":\"calculateRequestPrice\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_callbackGasLimit\",\"type\":\"uint32\"}],\"name\":\"calculateRequestPriceNative\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"internalType\":\"bool\",\"name\":\"isLinkMode\",\"type\":\"bool\"}],\"name\":\"checkPaymentMode\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"disable\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"enable\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"_requestGasPriceWei\",\"type\":\"uint256\"}],\"name\":\"estimateRequestPrice\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"_requestGasPriceWei\",\"type\":\"uint256\"}],\"name\":\"estimateRequestPriceNative\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"int256\"},{\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"wrapperGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"coordinatorGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"wrapperPremiumPercentage\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"maxNumWords\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastRequestId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newCoordinator\",\"type\":\"address\"}],\"name\":\"migrate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"randomWords\",\"type\":\"uint256[]\"}],\"name\":\"rawFulfillRandomWords\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"_requestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"_numWords\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"name\":\"requestRandomWordsInNative\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_callbacks\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"callbackAddress\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"requestGasPrice\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_configured\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_disabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_fulfillmentTxSizeBytes\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_link\",\"outputs\":[{\"internalType\":\"contractLinkTokenInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_linkNativeFeed\",\"outputs\":[{\"internalType\":\"contractAggregatorV3Interface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_vrfCoordinator\",\"outputs\":[{\"internalType\":\"contractIVRFCoordinatorV2Plus\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_wrapperGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_coordinatorGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"_wrapperPremiumPercentage\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"_keyHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"_maxNumWords\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"int256\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"int256\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeNativePPM\",\"type\":\"uint32\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_vrfCoordinator\",\"type\":\"address\"}],\"name\":\"setCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"size\",\"type\":\"uint32\"}],\"name\":\"setFulfillmentTxSize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"link\",\"type\":\"address\"}],\"name\":\"setLINK\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"linkNativeFeed\",\"type\":\"address\"}],\"name\":\"setLinkNativeFeed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"withdrawNative\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60a06040526007805463ffffffff60201b1916650244000000001790553480156200002957600080fd5b506040516200365f3803806200365f8339810160408190526200004c9162000323565b803380600081620000a45760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000d757620000d7816200025a565b5050600280546001600160a01b0319166001600160a01b03938416179055508316156200012857600680546001600160601b03166c010000000000000000000000006001600160a01b038616021790555b6001600160a01b038216156200016257600780546001600160601b03166c010000000000000000000000006001600160a01b038516021790555b6002546040805163288688f960e21b815290516000926001600160a01b03169163a21a23e491600480830192602092919082900301818787803b158015620001a957600080fd5b505af1158015620001be573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001e491906200036d565b6080819052600254604051632fb1302360e21b8152600481018390523060248201529192506001600160a01b03169063bec4c08c90604401600060405180830381600087803b1580156200023757600080fd5b505af11580156200024c573d6000803e3d6000fd5b505050505050505062000387565b6001600160a01b038116331415620002b55760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200009b565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b03811681146200031e57600080fd5b919050565b6000806000606084860312156200033957600080fd5b620003448462000306565b9250620003546020850162000306565b9150620003646040850162000306565b90509250925092565b6000602082840312156200038057600080fd5b5051919050565b6080516132a7620003b8600039600081816101fa0152818161125a0152818161182b0152611c2301526132a76000f3fe6080604052600436106101e35760003560e01c80639cfc058e11610102578063c3f909d411610095578063f254bdc711610064578063f254bdc71461071d578063f2fde38b1461075a578063f3fef3a31461077a578063fc2a88c31461079a57600080fd5b8063c3f909d4146105fc578063cdd8d88514610686578063ce5494bb146106c0578063da4f5e6d146106e057600080fd5b8063a4c0ed36116100d1578063a4c0ed361461057d578063a608a1e11461059d578063bed41a93146105bc578063bf17e559146105dc57600080fd5b80639cfc058e146105085780639eccacf61461051b578063a02e061614610548578063a3907d711461056857600080fd5b806348baa1c51161017a57806379ba50971161014957806379ba5097146104675780637fb5d19d1461047c5780638da5cb5b1461049c5780638ea98117146104e857600080fd5b806348baa1c5146103325780634b160935146103fd57806357a8070a1461041d578063650596541461044757600080fd5b80631fe543e3116101b65780631fe543e3146102bd5780632f2770db146102dd5780633255c456146102f25780634306d3541461031257600080fd5b8063030932bb146101e857806307b18bde1461022f578063181f5a771461025157806318b6f4c81461029d575b600080fd5b3480156101f457600080fd5b5061021c7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b34801561023b57600080fd5b5061024f61024a366004612a13565b6107b0565b005b34801561025d57600080fd5b50604080518082018252601281527f56524656325772617070657220312e302e300000000000000000000000000000602082015290516102269190612eac565b3480156102a957600080fd5b5061024f6102b8366004612ab4565b61088c565b3480156102c957600080fd5b5061024f6102d8366004612b38565b610a03565b3480156102e957600080fd5b5061024f610a80565b3480156102fe57600080fd5b5061021c61030d366004612d3b565b610ab6565b34801561031e57600080fd5b5061021c61032d366004612c3b565b610bb0565b34801561033e57600080fd5b506103bc61034d366004612b06565b60096020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff81169074010000000000000000000000000000000000000000810463ffffffff16907801000000000000000000000000000000000000000000000000900467ffffffffffffffff1683565b6040805173ffffffffffffffffffffffffffffffffffffffff909416845263ffffffff909216602084015267ffffffffffffffff1690820152606001610226565b34801561040957600080fd5b5061021c610418366004612c3b565b610cb7565b34801561042957600080fd5b506008546104379060ff1681565b6040519015158152602001610226565b34801561045357600080fd5b5061024f6104623660046129f8565b610da8565b34801561047357600080fd5b5061024f610df3565b34801561048857600080fd5b5061021c610497366004612d3b565b610ef0565b3480156104a857600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610226565b3480156104f457600080fd5b5061024f6105033660046129f8565b610ff6565b61021c610516366004612c56565b611101565b34801561052757600080fd5b506002546104c39073ffffffffffffffffffffffffffffffffffffffff1681565b34801561055457600080fd5b5061024f6105633660046129f8565b611496565b34801561057457600080fd5b5061024f611541565b34801561058957600080fd5b5061024f610598366004612a3d565b611573565b3480156105a957600080fd5b5060085461043790610100900460ff1681565b3480156105c857600080fd5b5061024f6105d7366004612d57565b611a53565b3480156105e857600080fd5b5061024f6105f7366004612c3b565b611ba9565b34801561060857600080fd5b506005546006546007546008546003546040805195865263ffffffff8086166020880152640100000000909504851690860152838316606086015268010000000000000000909204909216608084015260ff620100008304811660a085015260c084019190915263010000009091041660e082015261010001610226565b34801561069257600080fd5b506007546106ab90640100000000900463ffffffff1681565b60405163ffffffff9091168152602001610226565b3480156106cc57600080fd5b5061024f6106db3660046129f8565b611bf0565b3480156106ec57600080fd5b506006546104c3906c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1681565b34801561072957600080fd5b506007546104c3906c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1681565b34801561076657600080fd5b5061024f6107753660046129f8565b611ca6565b34801561078657600080fd5b5061024f610795366004612a13565b611cba565b3480156107a657600080fd5b5061021c60045481565b6107b8611db5565b60008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114610812576040519150601f19603f3d011682016040523d82523d6000602084013e610817565b606091505b5050905080610887576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f6661696c656420746f207769746864726177206e61746976650000000000000060448201526064015b60405180910390fd5b505050565b81516108cd57806108c9576040517f6b81746e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b81516024111561091e5781516040517f51200dce00000000000000000000000000000000000000000000000000000000815261087e9160249160040161ffff92831681529116602082015260400190565b6000826023815181106109335761093361322e565b6020910101517fff00000000000000000000000000000000000000000000000000000000000000167f01000000000000000000000000000000000000000000000000000000000000001490508080156109895750815b156109c0576040517f6048aa6800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b801580156109cc575081155b15610887576040517f6b81746e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60025473ffffffffffffffffffffffffffffffffffffffff163314610a76576002546040517f1cf993f400000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff909116602482015260440161087e565b6108c98282611e38565b610a88611db5565b600880547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100179055565b60085460009060ff16610b25576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f77726170706572206973206e6f7420636f6e6669677572656400000000000000604482015260640161087e565b600854610100900460ff1615610b97576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f777261707065722069732064697361626c656400000000000000000000000000604482015260640161087e565b610ba78363ffffffff1683612020565b90505b92915050565b60085460009060ff16610c1f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f77726170706572206973206e6f7420636f6e6669677572656400000000000000604482015260640161087e565b600854610100900460ff1615610c91576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f777261707065722069732064697361626c656400000000000000000000000000604482015260640161087e565b6000610c9b6120f6565b9050610cae8363ffffffff163a8361225d565b9150505b919050565b60085460009060ff16610d26576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f77726170706572206973206e6f7420636f6e6669677572656400000000000000604482015260640161087e565b600854610100900460ff1615610d98576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f777261707065722069732064697361626c656400000000000000000000000000604482015260640161087e565b610baa8263ffffffff163a612020565b610db0611db5565b6007805473ffffffffffffffffffffffffffffffffffffffff9092166c01000000000000000000000000026bffffffffffffffffffffffff909216919091179055565b60015473ffffffffffffffffffffffffffffffffffffffff163314610e74576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161087e565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60085460009060ff16610f5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f77726170706572206973206e6f7420636f6e6669677572656400000000000000604482015260640161087e565b600854610100900460ff1615610fd1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f777261707065722069732064697361626c656400000000000000000000000000604482015260640161087e565b6000610fdb6120f6565b9050610fee8463ffffffff16848361225d565b949350505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314801590611036575060025473ffffffffffffffffffffffffffffffffffffffff163314155b156110ba573361105b60005473ffffffffffffffffffffffffffffffffffffffff1690565b6002546040517f061db9c100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9384166004820152918316602483015291909116604482015260640161087e565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600061114283838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920182905250925061088c915050565b600061114d8761234f565b905060006111618863ffffffff163a612020565b9050803410156111cd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f66656520746f6f206c6f77000000000000000000000000000000000000000000604482015260640161087e565b6008546301000000900460ff1663ffffffff87161115611249576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f6e756d576f72647320746f6f2068696768000000000000000000000000000000604482015260640161087e565b6040805160c08101825260035481527f0000000000000000000000000000000000000000000000000000000000000000602082015261ffff89169181019190915260075460009190606082019063ffffffff166112a6868d612fd1565b6112b09190612fd1565b63ffffffff1681526020018863ffffffff16815260200187878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509152506002546040517f9b1c385e00000000000000000000000000000000000000000000000000000000815291925073ffffffffffffffffffffffffffffffffffffffff1690639b1c385e90611356908490600401612ebf565b602060405180830381600087803b15801561137057600080fd5b505af1158015611384573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113a89190612b1f565b6040805160608101825233815263ffffffff808d16602080840191825267ffffffffffffffff3a81168587019081526000888152600990935295909120935184549251955190911678010000000000000000000000000000000000000000000000000277ffffffffffffffffffffffffffffffffffffffffffffffff9590931674010000000000000000000000000000000000000000027fffffffffffffffff00000000000000000000000000000000000000000000000090921673ffffffffffffffffffffffffffffffffffffffff91909116171792909216919091179055935050505095945050505050565b61149e611db5565b6006546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff16156114fe576040517f2d118a6e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006805473ffffffffffffffffffffffffffffffffffffffff9092166c01000000000000000000000000026bffffffffffffffffffffffff909216919091179055565b611549611db5565b600880547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055565b60085460ff166115df576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f77726170706572206973206e6f7420636f6e6669677572656400000000000000604482015260640161087e565b600854610100900460ff1615611651576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f777261707065722069732064697361626c656400000000000000000000000000604482015260640161087e565b6006546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1633146116e2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f6f6e6c792063616c6c61626c652066726f6d204c494e4b000000000000000000604482015260640161087e565b60008080806116f385870187612ccc565b935093509350935061170681600161088c565b60006117118561234f565b9050600061171d6120f6565b905060006117328763ffffffff163a8461225d565b9050808a101561179e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f66656520746f6f206c6f77000000000000000000000000000000000000000000604482015260640161087e565b6008546301000000900460ff1663ffffffff8616111561181a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f6e756d576f72647320746f6f2068696768000000000000000000000000000000604482015260640161087e565b6040805160c08101825260035481527f0000000000000000000000000000000000000000000000000000000000000000602082015261ffff88169181019190915260075460009190606082019063ffffffff16611877878c612fd1565b6118819190612fd1565b63ffffffff908116825288166020820152604090810187905260025490517f9b1c385e00000000000000000000000000000000000000000000000000000000815291925060009173ffffffffffffffffffffffffffffffffffffffff90911690639b1c385e906118f5908590600401612ebf565b602060405180830381600087803b15801561190f57600080fd5b505af1158015611923573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119479190612b1f565b905060405180606001604052808e73ffffffffffffffffffffffffffffffffffffffff1681526020018a63ffffffff1681526020013a67ffffffffffffffff168152506009600083815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a81548163ffffffff021916908363ffffffff16021790555060408201518160000160186101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055509050508060048190555050505050505050505050505050565b611a5b611db5565b6007805463ffffffff9a8b167fffffffffffffffffffffffffffffffffffffffff00000000ffffffff000000009091161768010000000000000000998b168a02179055600880546003979097557fffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ffff9096166201000060ff988916027fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffff161763010000009590971694909402959095177fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117909355600680546005949094557fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff9187167fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009094169390931764010000000094871694909402939093179290921691909316909102179055565b611bb1611db5565b6007805463ffffffff909216640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff909216919091179055565b611bf8611db5565b6002546040517f405b84fa0000000000000000000000000000000000000000000000000000000081527f0000000000000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff83811660248301529091169063405b84fa90604401600060405180830381600087803b158015611c8b57600080fd5b505af1158015611c9f573d6000803e3d6000fd5b5050505050565b611cae611db5565b611cb781612367565b50565b611cc2611db5565b6006546040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152602482018490526c010000000000000000000000009092049091169063a9059cbb90604401602060405180830381600087803b158015611d4757600080fd5b505af1158015611d5b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d7f9190612a97565b6108c9576040517f7c07fc4c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005473ffffffffffffffffffffffffffffffffffffffff163314611e36576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161087e565b565b60008281526009602081815260408084208151606081018352815473ffffffffffffffffffffffffffffffffffffffff808216835274010000000000000000000000000000000000000000820463ffffffff1683870152780100000000000000000000000000000000000000000000000090910467ffffffffffffffff1693820193909352878652939092529290558051909116611f32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f72657175657374206e6f7420666f756e64000000000000000000000000000000604482015260640161087e565b600080631fe543e360e01b8585604051602401611f50929190612f1c565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000611fca846020015163ffffffff1685600001518461245d565b90508061201857835160405173ffffffffffffffffffffffffffffffffffffffff9091169087907fc551b83c151f2d1c7eeb938ac59008e0409f1c1dc1e2f112449d4d79b458902290600090a35b505050505050565b600754600090819061203f90640100000000900463ffffffff166124a9565b60075463ffffffff680100000000000000008204811691612061911687612fb9565b61206b9190612fb9565b612075908561317c565b61207f9190612fb9565b60085490915081906000906064906120a09062010000900460ff1682612ff9565b6120ad9060ff168461317c565b6120b7919061301e565b6006549091506000906120e19068010000000000000000900463ffffffff1664e8d4a5100061317c565b6120eb9083612fb9565b979650505050505050565b600654600754604080517ffeaf968c000000000000000000000000000000000000000000000000000000008152905160009363ffffffff16151592849283926c0100000000000000000000000090920473ffffffffffffffffffffffffffffffffffffffff169163feaf968c9160048082019260a092909190829003018186803b15801561218357600080fd5b505afa158015612197573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121bb9190612df1565b5094509092508491505080156121e157506121d682426131b9565b60065463ffffffff16105b156121eb57506005545b6000811215612256576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f496e76616c6964204c494e4b2077656920707269636500000000000000000000604482015260640161087e565b9392505050565b600754600090819061227c90640100000000900463ffffffff166124a9565b60075463ffffffff68010000000000000000820481169161229e911688612fb9565b6122a89190612fb9565b6122b2908661317c565b6122bc9190612fb9565b90506000836122d383670de0b6b3a764000061317c565b6122dd919061301e565b6008549091506000906064906122fc9062010000900460ff1682612ff9565b6123099060ff168461317c565b612313919061301e565b60065490915060009061233990640100000000900463ffffffff1664e8d4a5100061317c565b6123439083612fb9565b98975050505050505050565b600061235c603f83613032565b610baa906001612fd1565b73ffffffffffffffffffffffffffffffffffffffff81163314156123e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161087e565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60005a61138881101561246f57600080fd5b61138881039050846040820482031161248757600080fd5b50823b61249357600080fd5b60008083516020850160008789f1949350505050565b6000466124b581612579565b15612559576000606c73ffffffffffffffffffffffffffffffffffffffff166341b247a86040518163ffffffff1660e01b815260040160c06040518083038186803b15801561250357600080fd5b505afa158015612517573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061253b9190612bf1565b5050505091505083608c61254f9190612fb9565b610fee908261317c565b6125628161259c565b1561257057610cae836125d6565b50600092915050565b600061a4b182148061258d575062066eed82145b80610baa57505062066eee1490565b6000600a8214806125ae57506101a482145b806125bb575062aa37dc82145b806125c7575061210582145b80610baa57505062014a331490565b60008073420000000000000000000000000000000000000f73ffffffffffffffffffffffffffffffffffffffff1663519b4bd36040518163ffffffff1660e01b815260040160206040518083038186803b15801561263357600080fd5b505afa158015612647573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061266b9190612b1f565b905060008061267a81866131b9565b9050600061268982601061317c565b61269484600461317c565b61269e9190612fb9565b9050600073420000000000000000000000000000000000000f73ffffffffffffffffffffffffffffffffffffffff16630c18c1626040518163ffffffff1660e01b815260040160206040518083038186803b1580156126fc57600080fd5b505afa158015612710573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127349190612b1f565b9050600073420000000000000000000000000000000000000f73ffffffffffffffffffffffffffffffffffffffff1663f45e65d86040518163ffffffff1660e01b815260040160206040518083038186803b15801561279257600080fd5b505afa1580156127a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127ca9190612b1f565b9050600073420000000000000000000000000000000000000f73ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561282857600080fd5b505afa15801561283c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128609190612b1f565b9050600061286f82600a6130b6565b90506000818461287f8789612fb9565b612889908c61317c565b612893919061317c565b61289d919061301e565b9b9a5050505050505050505050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610cb257600080fd5b60008083601f8401126128e257600080fd5b50813567ffffffffffffffff8111156128fa57600080fd5b60208301915083602082850101111561291257600080fd5b9250929050565b600082601f83011261292a57600080fd5b813567ffffffffffffffff8111156129445761294461325d565b61297560207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601612f6a565b81815284602083860101111561298a57600080fd5b816020850160208301376000918101602001919091529392505050565b803561ffff81168114610cb257600080fd5b803563ffffffff81168114610cb257600080fd5b803560ff81168114610cb257600080fd5b805169ffffffffffffffffffff81168114610cb257600080fd5b600060208284031215612a0a57600080fd5b610ba7826128ac565b60008060408385031215612a2657600080fd5b612a2f836128ac565b946020939093013593505050565b60008060008060608587031215612a5357600080fd5b612a5c856128ac565b935060208501359250604085013567ffffffffffffffff811115612a7f57600080fd5b612a8b878288016128d0565b95989497509550505050565b600060208284031215612aa957600080fd5b81516122568161328c565b60008060408385031215612ac757600080fd5b823567ffffffffffffffff811115612ade57600080fd5b612aea85828601612919565b9250506020830135612afb8161328c565b809150509250929050565b600060208284031215612b1857600080fd5b5035919050565b600060208284031215612b3157600080fd5b5051919050565b60008060408385031215612b4b57600080fd5b8235915060208084013567ffffffffffffffff80821115612b6b57600080fd5b818601915086601f830112612b7f57600080fd5b813581811115612b9157612b9161325d565b8060051b9150612ba2848301612f6a565b8181528481019084860184860187018b1015612bbd57600080fd5b600095505b83861015612be0578035835260019590950194918601918601612bc2565b508096505050505050509250929050565b60008060008060008060c08789031215612c0a57600080fd5b865195506020870151945060408701519350606087015192506080870151915060a087015190509295509295509295565b600060208284031215612c4d57600080fd5b610ba7826129b9565b600080600080600060808688031215612c6e57600080fd5b612c77866129b9565b9450612c85602087016129a7565b9350612c93604087016129b9565b9250606086013567ffffffffffffffff811115612caf57600080fd5b612cbb888289016128d0565b969995985093965092949392505050565b60008060008060808587031215612ce257600080fd5b612ceb856129b9565b9350612cf9602086016129a7565b9250612d07604086016129b9565b9150606085013567ffffffffffffffff811115612d2357600080fd5b612d2f87828801612919565b91505092959194509250565b60008060408385031215612d4e57600080fd5b612a2f836129b9565b60008060008060008060008060006101208a8c031215612d7657600080fd5b612d7f8a6129b9565b9850612d8d60208b016129b9565b9750612d9b60408b016129cd565b965060608a01359550612db060808b016129cd565b9450612dbe60a08b016129b9565b935060c08a01359250612dd360e08b016129b9565b9150612de26101008b016129b9565b90509295985092959850929598565b600080600080600060a08688031215612e0957600080fd5b612e12866129de565b9450602086015193506040860151925060608601519150612e35608087016129de565b90509295509295909350565b6000815180845260005b81811015612e6757602081850181015186830182015201612e4b565b81811115612e79576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610ba76020830184612e41565b60208152815160208201526020820151604082015261ffff60408301511660608201526000606083015163ffffffff80821660808501528060808601511660a0850152505060a083015160c080840152610fee60e0840182612e41565b6000604082018483526020604081850152818551808452606086019150828701935060005b81811015612f5d57845183529383019391830191600101612f41565b5090979650505050505050565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612fb157612fb161325d565b604052919050565b60008219821115612fcc57612fcc6131d0565b500190565b600063ffffffff808316818516808303821115612ff057612ff06131d0565b01949350505050565b600060ff821660ff84168060ff03821115613016576130166131d0565b019392505050565b60008261302d5761302d6131ff565b500490565b600063ffffffff80841680613049576130496131ff565b92169190910492915050565b600181815b808511156130ae57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115613094576130946131d0565b808516156130a157918102915b93841c939080029061305a565b509250929050565b6000610ba783836000826130cc57506001610baa565b816130d957506000610baa565b81600181146130ef57600281146130f957613115565b6001915050610baa565b60ff84111561310a5761310a6131d0565b50506001821b610baa565b5060208310610133831016604e8410600b8410161715613138575081810a610baa565b6131428383613055565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115613174576131746131d0565b029392505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156131b4576131b46131d0565b500290565b6000828210156131cb576131cb6131d0565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b8015158114611cb757600080fdfea164736f6c6343000806000a", } var VRFV2PlusWrapperABI = VRFV2PlusWrapperMetaData.ABI @@ -602,6 +602,18 @@ func (_VRFV2PlusWrapper *VRFV2PlusWrapperTransactorSession) Enable() (*types.Tra return _VRFV2PlusWrapper.Contract.Enable(&_VRFV2PlusWrapper.TransactOpts) } +func (_VRFV2PlusWrapper *VRFV2PlusWrapperTransactor) Migrate(opts *bind.TransactOpts, newCoordinator common.Address) (*types.Transaction, error) { + return _VRFV2PlusWrapper.contract.Transact(opts, "migrate", newCoordinator) +} + +func (_VRFV2PlusWrapper *VRFV2PlusWrapperSession) Migrate(newCoordinator common.Address) (*types.Transaction, error) { + return _VRFV2PlusWrapper.Contract.Migrate(&_VRFV2PlusWrapper.TransactOpts, newCoordinator) +} + +func (_VRFV2PlusWrapper *VRFV2PlusWrapperTransactorSession) Migrate(newCoordinator common.Address) (*types.Transaction, error) { + return _VRFV2PlusWrapper.Contract.Migrate(&_VRFV2PlusWrapper.TransactOpts, newCoordinator) +} + func (_VRFV2PlusWrapper *VRFV2PlusWrapperTransactor) OnTokenTransfer(opts *bind.TransactOpts, _sender common.Address, _amount *big.Int, _data []byte) (*types.Transaction, error) { return _VRFV2PlusWrapper.contract.Transact(opts, "onTokenTransfer", _sender, _amount, _data) } @@ -1233,6 +1245,8 @@ type VRFV2PlusWrapperInterface interface { Enable(opts *bind.TransactOpts) (*types.Transaction, error) + Migrate(opts *bind.TransactOpts, newCoordinator common.Address) (*types.Transaction, error) + OnTokenTransfer(opts *bind.TransactOpts, _sender common.Address, _amount *big.Int, _data []byte) (*types.Transaction, error) RawFulfillRandomWords(opts *bind.TransactOpts, requestId *big.Int, randomWords []*big.Int) (*types.Transaction, error) diff --git a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt index ac0786a8bb5..bd3bb50c496 100644 --- a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -102,6 +102,6 @@ vrfv2plus_client: ../../contracts/solc/v0.8.6/VRFV2PlusClient.abi ../../contract vrfv2plus_consumer_example: ../../contracts/solc/v0.8.6/VRFV2PlusConsumerExample.abi ../../contracts/solc/v0.8.6/VRFV2PlusConsumerExample.bin 2c480a6d7955d33a00690fdd943486d95802e48a03f3cc243df314448e4ddb2c vrfv2plus_malicious_migrator: ../../contracts/solc/v0.8.6/VRFV2PlusMaliciousMigrator.abi ../../contracts/solc/v0.8.6/VRFV2PlusMaliciousMigrator.bin 80dbc98be5e42246960c889d29488f978d3db0127e95e9b295352c481d8c9b07 vrfv2plus_reverting_example: ../../contracts/solc/v0.8.6/VRFV2PlusRevertingExample.abi ../../contracts/solc/v0.8.6/VRFV2PlusRevertingExample.bin 34743ac1dd5e2c9d210b2bd721ebd4dff3c29c548f05582538690dde07773589 -vrfv2plus_wrapper: ../../contracts/solc/v0.8.6/VRFV2PlusWrapper.abi ../../contracts/solc/v0.8.6/VRFV2PlusWrapper.bin 3e1e3836e8c8bf7a6f83f571f17e258f30e6d02037e53eebf74c2af3fbcf0913 +vrfv2plus_wrapper: ../../contracts/solc/v0.8.6/VRFV2PlusWrapper.abi ../../contracts/solc/v0.8.6/VRFV2PlusWrapper.bin bd5f9c8972cb12af4e76bfdc85caf67ef3d824276468b10d6e6e82df2925982f vrfv2plus_wrapper_consumer_example: ../../contracts/solc/v0.8.6/VRFV2PlusWrapperConsumerExample.abi ../../contracts/solc/v0.8.6/VRFV2PlusWrapperConsumerExample.bin 4b3da45ff177e09b1e731b5b0cf4e050033a600ef8b0d32e79eec97db5c72408 vrfv2plus_wrapper_load_test_consumer: ../../contracts/solc/v0.8.6/VRFV2PlusWrapperLoadTestConsumer.abi ../../contracts/solc/v0.8.6/VRFV2PlusWrapperLoadTestConsumer.bin 4886b08ff9cf013033b7c08e0317f23130ba8e2be445625fdbe1424eb7c38989 From c89f9c30166d2b320eeefe9bb050ea0243635a7e Mon Sep 17 00:00:00 2001 From: Tate Date: Fri, 6 Oct 2023 20:17:18 -0600 Subject: [PATCH 06/10] Fix the upgrade test ci (#10880) --- .github/workflows/integration-tests.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index aee2fb2edee..884da09f4cb 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -449,8 +449,8 @@ jobs: CHAINLINK_COMMIT_SHA: ${{ github.sha }} CHAINLINK_ENV_USER: ${{ github.actor }} CHAINLINK_IMAGE: public.ecr.aws/chainlink/chainlink - TEST_UPGRADE_VERSION: ${{ github.sha }} - TEST_UPGRADE_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink + UPGRADE_VERSION: ${{ github.sha }} + UPGRADE_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink TEST_LOG_LEVEL: debug TEST_SUITE: migration steps: From 7dbb38bb5283f54dfa4a788c91d9b3963f6ae271 Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Mon, 9 Oct 2023 04:55:59 -0500 Subject: [PATCH 07/10] core: randomize p2p ports; consolidate GetFreePort implementations (#10884) --- core/internal/features/features_test.go | 24 +++++++++---------- .../features/ocr2/features_ocr2_test.go | 13 ++++------ core/internal/testutils/testutils.go | 17 ++++++++++++- .../v0/internal/testutils.go | 22 ++++------------- .../v1/internal/testutils.go | 22 ++++------------- .../internal/ocr2vrf_integration_test.go | 22 ++++------------- 6 files changed, 48 insertions(+), 72 deletions(-) diff --git a/core/internal/features/features_test.go b/core/internal/features/features_test.go index 39eee3f7b43..489f744cdef 100644 --- a/core/internal/features/features_test.go +++ b/core/internal/features/features_test.go @@ -670,12 +670,12 @@ func setupOCRContracts(t *testing.T) (*bind.TransactOpts, *backends.SimulatedBac return owner, b, ocrContractAddress, ocrContract, flagsContract, flagsContractAddress } -func setupNode(t *testing.T, owner *bind.TransactOpts, portV1, portV2 int, dbName string, +func setupNode(t *testing.T, owner *bind.TransactOpts, portV1, portV2 uint16, dbName string, b *backends.SimulatedBackend, ns ocrnetworking.NetworkingStack, overrides func(c *chainlink.Config, s *chainlink.Secrets), ) (*cltest.TestApplication, string, common.Address, ocrkey.KeyV2) { p2pKey, err := p2pkey.NewV2() require.NoError(t, err) - config, _ := heavyweight.FullTestDBV2(t, fmt.Sprintf("%s%d", dbName, portV1), func(c *chainlink.Config, s *chainlink.Secrets) { + config, _ := heavyweight.FullTestDBV2(t, dbName, func(c *chainlink.Config, s *chainlink.Secrets) { c.Insecure.OCRDevelopmentMode = ptr(true) // Disables ocr spec validation so we can have fast polling for the test. c.OCR.Enabled = ptr(true) @@ -743,7 +743,7 @@ func setupForwarderEnabledNode( t *testing.T, owner *bind.TransactOpts, portV1, - portV2 int, + portV2 uint16, dbName string, b *backends.SimulatedBackend, ns ocrnetworking.NetworkingStack, @@ -757,7 +757,7 @@ func setupForwarderEnabledNode( ) { p2pKey, err := p2pkey.NewV2() require.NoError(t, err) - config, _ := heavyweight.FullTestDBV2(t, fmt.Sprintf("%s%d", dbName, portV1), func(c *chainlink.Config, s *chainlink.Secrets) { + config, _ := heavyweight.FullTestDBV2(t, dbName, func(c *chainlink.Config, s *chainlink.Secrets) { c.Insecure.OCRDevelopmentMode = ptr(true) // Disables ocr spec validation so we can have fast polling for the test. c.OCR.Enabled = ptr(true) @@ -856,8 +856,8 @@ func TestIntegration_OCR(t *testing.T) { for _, tt := range tests { test := tt t.Run(test.name, func(t *testing.T) { - bootstrapNodePortV1 := test.portStart - bootstrapNodePortV2 := test.portStart + numOracles + 1 + bootstrapNodePortV1 := testutils.GetFreePort(t) + bootstrapNodePortV2 := testutils.GetFreePort(t) g := gomega.NewWithT(t) owner, b, ocrContractAddress, ocrContract, flagsContract, flagsContractAddress := setupOCRContracts(t) @@ -871,8 +871,8 @@ func TestIntegration_OCR(t *testing.T) { apps []*cltest.TestApplication ) for i := 0; i < numOracles; i++ { - portV1 := bootstrapNodePortV1 + i + 1 - portV2 := bootstrapNodePortV2 + i + 1 + portV1 := testutils.GetFreePort(t) + portV2 := testutils.GetFreePort(t) app, peerID, transmitter, key := setupNode(t, owner, portV1, portV2, fmt.Sprintf("o%d_%d", i, test.id), b, test.ns, func(c *chainlink.Config, s *chainlink.Secrets) { c.EVM[0].FlagsContractAddress = ptr(ethkey.EIP55AddressFromAddress(flagsContractAddress)) c.EVM[0].GasEstimator.EIP1559DynamicFees = ptr(test.eip1559) @@ -1080,8 +1080,8 @@ func TestIntegration_OCR_ForwarderFlow(t *testing.T) { t.Parallel() numOracles := 4 t.Run("ocr_forwarder_flow", func(t *testing.T) { - bootstrapNodePortV1 := 20000 - bootstrapNodePortV2 := 20000 + numOracles + 1 + bootstrapNodePortV1 := testutils.GetFreePort(t) + bootstrapNodePortV2 := testutils.GetFreePort(t) g := gomega.NewWithT(t) owner, b, ocrContractAddress, ocrContract, flagsContract, flagsContractAddress := setupOCRContracts(t) @@ -1097,8 +1097,8 @@ func TestIntegration_OCR_ForwarderFlow(t *testing.T) { apps []*cltest.TestApplication ) for i := 0; i < numOracles; i++ { - portV1 := bootstrapNodePortV1 + i + 1 - portV2 := bootstrapNodePortV2 + i + 1 + portV1 := testutils.GetFreePort(t) + portV2 := testutils.GetFreePort(t) app, peerID, transmitter, forwarder, key := setupForwarderEnabledNode(t, owner, portV1, portV2, fmt.Sprintf("o%d_%d", i, 1), b, ocrnetworking.NetworkingStackV2, func(c *chainlink.Config, s *chainlink.Secrets) { c.Feature.LogPoller = ptr(true) c.EVM[0].FlagsContractAddress = ptr(ethkey.EIP55AddressFromAddress(flagsContractAddress)) diff --git a/core/internal/features/ocr2/features_ocr2_test.go b/core/internal/features/ocr2/features_ocr2_test.go index 0a6192c99c3..f31f19a4f2d 100644 --- a/core/internal/features/ocr2/features_ocr2_test.go +++ b/core/internal/features/ocr2/features_ocr2_test.go @@ -23,11 +23,12 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/eth/ethconfig" "github.com/onsi/gomega" - "github.com/smartcontractkit/libocr/commontypes" - "github.com/smartcontractkit/libocr/gethwrappers2/ocr2aggregator" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/smartcontractkit/libocr/commontypes" + "github.com/smartcontractkit/libocr/gethwrappers2/ocr2aggregator" + testoffchainaggregator2 "github.com/smartcontractkit/libocr/gethwrappers2/testocr2aggregator" confighelper2 "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" ocrtypes2 "github.com/smartcontractkit/libocr/offchainreporting2plus/types" @@ -191,9 +192,7 @@ func TestIntegration_OCR2(t *testing.T) { owner, b, ocrContractAddress, ocrContract := setupOCR2Contracts(t) lggr := logger.TestLogger(t) - // Note it's plausible these ports could be occupied on a CI machine. - // May need a port randomize + retry approach if we observe collisions. - bootstrapNodePort := uint16(29999) + bootstrapNodePort := testutils.GetFreePort(t) bootstrapNode := setupNodeOCR2(t, owner, bootstrapNodePort, "bootstrap", false /* useForwarders */, b, nil) var ( @@ -462,9 +461,7 @@ func TestIntegration_OCR2_ForwarderFlow(t *testing.T) { owner, b, ocrContractAddress, ocrContract := setupOCR2Contracts(t) lggr := logger.TestLogger(t) - // Note it's plausible these ports could be occupied on a CI machine. - // May need a port randomize + retry approach if we observe collisions. - bootstrapNodePort := uint16(29898) + bootstrapNodePort := testutils.GetFreePort(t) bootstrapNode := setupNodeOCR2(t, owner, bootstrapNodePort, "bootstrap", true /* useForwarders */, b, nil) var ( diff --git a/core/internal/testutils/testutils.go b/core/internal/testutils/testutils.go index d50efcc799a..0d4e710b497 100644 --- a/core/internal/testutils/testutils.go +++ b/core/internal/testutils/testutils.go @@ -10,6 +10,7 @@ import ( "math" "math/big" mrand "math/rand" + "net" "net/http" "net/http/httptest" "net/url" @@ -24,10 +25,11 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/google/uuid" "github.com/gorilla/websocket" - "github.com/smartcontractkit/sqlx" "github.com/tidwall/gjson" "go.uber.org/zap/zaptest/observer" + "github.com/smartcontractkit/sqlx" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" // NOTE: To avoid circular dependencies, this package MUST NOT import @@ -450,3 +452,16 @@ func MustDecodeBase64(s string) (b []byte) { } return } + +// GetFreePort returns a free port. +// NOTE: This approach is technically incorrect because the returned port +// can still be taken by the time the caller attempts to bind to it. +// Unfortunately, we can't specify zero port in P2P.V2.ListenAddresses at the moment. +func GetFreePort(t *testing.T) uint16 { + addr, err := net.ResolveTCPAddr("tcp", "localhost:0") + require.NoError(t, err) + listener, err := net.ListenTCP("tcp", addr) + require.NoError(t, err) + require.NoError(t, listener.Close()) + return uint16(listener.Addr().(*net.TCPAddr).Port) +} diff --git a/core/services/ocr2/plugins/functions/integration_tests/v0/internal/testutils.go b/core/services/ocr2/plugins/functions/integration_tests/v0/internal/testutils.go index 9013620e1e6..a36b3cd3ea7 100644 --- a/core/services/ocr2/plugins/functions/integration_tests/v0/internal/testutils.go +++ b/core/services/ocr2/plugins/functions/integration_tests/v0/internal/testutils.go @@ -7,7 +7,6 @@ import ( "io" "math/big" "math/rand" - "net" "net/http" "net/http/httptest" "net/url" @@ -22,11 +21,12 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/eth/ethconfig" "github.com/onsi/gomega" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/smartcontractkit/libocr/commontypes" confighelper2 "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" ocrtypes2 "github.com/smartcontractkit/libocr/offchainreporting2plus/types" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink/v2/core/assets" "github.com/smartcontractkit/chainlink/v2/core/bridges" @@ -469,7 +469,7 @@ func CreateFunctionsNodes( require.Fail(t, "ocr2Keystores and thresholdKeyShares must have the same length") } - bootstrapPort := getFreePort(t) + bootstrapPort := testutils.GetFreePort(t) bootstrapNode = StartNewNode(t, owner, bootstrapPort, "bootstrap", b, uint32(maxGas), nil, nil, "") AddBootstrapJob(t, bootstrapNode.App, oracleContractAddress) @@ -487,7 +487,7 @@ func CreateFunctionsNodes( } else { ocr2Keystore = ocr2Keystores[i] } - nodePort := getFreePort(t) + nodePort := testutils.GetFreePort(t) oracleNode := StartNewNode(t, owner, nodePort, fmt.Sprintf("oracle%d", i), b, uint32(maxGas), []commontypes.BootstrapperLocator{ {PeerID: bootstrapNode.PeerID, Addrs: []string{fmt.Sprintf("127.0.0.1:%d", bootstrapPort)}}, }, ocr2Keystore, thresholdKeyShare) @@ -503,18 +503,6 @@ func CreateFunctionsNodes( return bootstrapNode, oracleNodes, oracleIdentites } -// NOTE: This approach is technically incorrect because the returned port -// can still be taken by the time the caller attempts to bind to it. -// Unfortunately, we can't specify zero port in P2P.V2.ListenAddresses at the moment. -func getFreePort(t *testing.T) uint16 { - addr, err := net.ResolveTCPAddr("tcp", "localhost:0") - require.NoError(t, err) - listener, err := net.ListenTCP("tcp", addr) - require.NoError(t, err) - require.NoError(t, listener.Close()) - return uint16(listener.Addr().(*net.TCPAddr).Port) -} - func ClientTestRequests( t *testing.T, owner *bind.TransactOpts, 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 c376213ed13..0970ea7c482 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 @@ -7,7 +7,6 @@ import ( "io" "math/big" "math/rand" - "net" "net/http" "net/http/httptest" "net/url" @@ -23,11 +22,12 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/eth/ethconfig" "github.com/onsi/gomega" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/smartcontractkit/libocr/commontypes" confighelper2 "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" ocrtypes2 "github.com/smartcontractkit/libocr/offchainreporting2plus/types" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink/v2/core/assets" "github.com/smartcontractkit/chainlink/v2/core/bridges" @@ -549,7 +549,7 @@ func CreateFunctionsNodes( require.Fail(t, "ocr2Keystores and thresholdKeyShares must have the same length") } - bootstrapPort := getFreePort(t) + bootstrapPort := testutils.GetFreePort(t) bootstrapNode = StartNewNode(t, owner, bootstrapPort, "bootstrap", b, uint32(maxGas), nil, nil, "") AddBootstrapJob(t, bootstrapNode.App, routerAddress) @@ -567,7 +567,7 @@ func CreateFunctionsNodes( } else { ocr2Keystore = ocr2Keystores[i] } - nodePort := getFreePort(t) + nodePort := testutils.GetFreePort(t) oracleNode := StartNewNode(t, owner, nodePort, fmt.Sprintf("oracle%d", i), b, uint32(maxGas), []commontypes.BootstrapperLocator{ {PeerID: bootstrapNode.PeerID, Addrs: []string{fmt.Sprintf("127.0.0.1:%d", bootstrapPort)}}, }, ocr2Keystore, thresholdKeyShare) @@ -583,18 +583,6 @@ func CreateFunctionsNodes( return bootstrapNode, oracleNodes, oracleIdentites } -// NOTE: This approach is technically incorrect because the returned port -// can still be taken by the time the caller attempts to bind to it. -// Unfortunately, we can't specify zero port in P2P.V2.ListenAddresses at the moment. -func getFreePort(t *testing.T) uint16 { - addr, err := net.ResolveTCPAddr("tcp", "localhost:0") - require.NoError(t, err) - listener, err := net.ListenTCP("tcp", addr) - require.NoError(t, err) - require.NoError(t, listener.Close()) - return uint16(listener.Addr().(*net.TCPAddr).Port) -} - func ClientTestRequests( t *testing.T, owner *bind.TransactOpts, diff --git a/core/services/ocr2/plugins/ocr2vrf/internal/ocr2vrf_integration_test.go b/core/services/ocr2/plugins/ocr2vrf/internal/ocr2vrf_integration_test.go index c6a4552683a..852017dffa9 100644 --- a/core/services/ocr2/plugins/ocr2vrf/internal/ocr2vrf_integration_test.go +++ b/core/services/ocr2/plugins/ocr2vrf/internal/ocr2vrf_integration_test.go @@ -7,7 +7,6 @@ import ( "errors" "fmt" "math/big" - "net" "testing" "time" @@ -20,6 +19,9 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/eth/ethconfig" "github.com/onsi/gomega" + "github.com/stretchr/testify/require" + "go.dedis.ch/kyber/v3" + "github.com/smartcontractkit/libocr/commontypes" confighelper2 "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" ocrtypes2 "github.com/smartcontractkit/libocr/offchainreporting2plus/types" @@ -27,9 +29,6 @@ import ( ocr2dkg "github.com/smartcontractkit/ocr2vrf/dkg" "github.com/smartcontractkit/ocr2vrf/ocr2vrf" ocr2vrftypes "github.com/smartcontractkit/ocr2vrf/types" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "go.dedis.ch/kyber/v3" "github.com/smartcontractkit/chainlink/v2/core/assets" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/forwarders" @@ -337,7 +336,7 @@ func runOCR2VRFTest(t *testing.T, useForwarders bool) { t.Log("Creating bootstrap node") - bootstrapNodePort := getFreePort(t) + bootstrapNodePort := testutils.GetFreePort(t) bootstrapNode := setupNodeOCR2(t, uni.owner, bootstrapNodePort, "bootstrap", uni.backend, false, nil) numNodes := 5 @@ -362,7 +361,7 @@ func runOCR2VRFTest(t *testing.T, useForwarders bool) { fmt.Sprintf("127.0.0.1:%d", bootstrapNodePort), }}, } - node := setupNodeOCR2(t, uni.owner, getFreePort(t), fmt.Sprintf("ocr2vrforacle%d", i), uni.backend, useForwarders, bootstrappers) + node := setupNodeOCR2(t, uni.owner, testutils.GetFreePort(t), fmt.Sprintf("ocr2vrforacle%d", i), uni.backend, useForwarders, bootstrappers) sendingKeys = append(sendingKeys, node.sendingKeys) dkgSignKey, err := node.app.GetKeyStore().DKGSign().Create() @@ -875,15 +874,4 @@ func randomKeyID(t *testing.T) (r [32]byte) { return } -func getFreePort(t *testing.T) uint16 { - addr, err := net.ResolveTCPAddr("tcp", "localhost:0") - require.NoError(t, err) - - l, err := net.ListenTCP("tcp", addr) - require.NoError(t, err) - defer func() { assert.NoError(t, l.Close()) }() - - return uint16(l.Addr().(*net.TCPAddr).Port) -} - func ptr[T any](v T) *T { return &v } From 5a0197bb6cb3e576339be0a0f8f768ce24259e58 Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Mon, 9 Oct 2023 05:47:33 -0500 Subject: [PATCH 08/10] golangci-lint (#10882) * x is unused (unused) * error-return: error should be the last type when returning multiple items (revive) * var-declaration: should omit type X from declaration of Y; it will be inferred from the right-hand side (revive) * defer: prefer not to defer inside loops (revive) * error-strings: error strings should not be capitalized or end with punctuation or a newline (revive) * File is not 'goimports'-ed with -local github.com/smartcontractkit/chainlink (goimports) * SA1012: do not pass a nil Context, even if a function permits it; pass context. * ineffectual assignment to err (ineffassign) --- core/chains/evm/chain.go | 1 - core/chains/evm/gas/fixed_price_estimator.go | 1 + core/chains/evm/txmgr/strategies_test.go | 2 +- core/chains/evm/txmgr/transmitchecker_test.go | 2 +- core/cmd/cosmos_node_commands_test.go | 5 ++-- core/gethwrappers/versions.go | 4 +-- core/services/chainlink/config_general.go | 6 +---- core/services/functions/listener_test.go | 26 +++++++++---------- core/services/keystore/eth.go | 18 ------------- .../ocr2/plugins/ocr2keeper/evm21/registry.go | 5 ++-- core/services/pipeline/task.bridge_test.go | 2 +- core/services/vrf/v2/integration_v2_test.go | 6 ++--- .../vrf/v2/listener_v2_helpers_test.go | 2 +- .../vrf/vrftesthelpers/consumer_v2.go | 1 + core/web/bridge_types_controller_test.go | 2 +- core/web/nodes_controller.go | 4 +-- core/web/resolver/chain.go | 1 + tools/flakeytests/runner_test.go | 6 ----- 18 files changed, 33 insertions(+), 61 deletions(-) diff --git a/core/chains/evm/chain.go b/core/chains/evm/chain.go index ddd9a38c755..58c793cc646 100644 --- a/core/chains/evm/chain.go +++ b/core/chains/evm/chain.go @@ -64,7 +64,6 @@ var ( // LegacyChains implements [LegacyChainContainer] type LegacyChains struct { *chains.ChainsKV[Chain] - dflt Chain cfgs toml.EVMConfigs } diff --git a/core/chains/evm/gas/fixed_price_estimator.go b/core/chains/evm/gas/fixed_price_estimator.go index 733dd179fec..a45df741a27 100644 --- a/core/chains/evm/gas/fixed_price_estimator.go +++ b/core/chains/evm/gas/fixed_price_estimator.go @@ -4,6 +4,7 @@ import ( "context" "github.com/pkg/errors" + commonfee "github.com/smartcontractkit/chainlink/v2/common/fee" feetypes "github.com/smartcontractkit/chainlink/v2/common/fee/types" "github.com/smartcontractkit/chainlink/v2/core/assets" diff --git a/core/chains/evm/txmgr/strategies_test.go b/core/chains/evm/txmgr/strategies_test.go index 3d9fed8fce1..9c5a1be37f1 100644 --- a/core/chains/evm/txmgr/strategies_test.go +++ b/core/chains/evm/txmgr/strategies_test.go @@ -21,7 +21,7 @@ func Test_SendEveryStrategy(t *testing.T) { assert.Equal(t, uuid.NullUUID{}, s.Subject()) - n, err := s.PruneQueue(nil, nil) + n, err := s.PruneQueue(testutils.Context(t), nil) assert.NoError(t, err) assert.Equal(t, int64(0), n) } diff --git a/core/chains/evm/txmgr/transmitchecker_test.go b/core/chains/evm/txmgr/transmitchecker_test.go index f8a80990d31..d536eaf40b6 100644 --- a/core/chains/evm/txmgr/transmitchecker_test.go +++ b/core/chains/evm/txmgr/transmitchecker_test.go @@ -164,7 +164,7 @@ func TestTransmitCheckers(t *testing.T) { mock.AnythingOfType("*hexutil.Bytes"), "eth_call", mock.MatchedBy(func(callarg map[string]interface{}) bool { return fmt.Sprintf("%s", callarg["value"]) == "0x282" // 642 - }), "latest").Return(errors.New("error!")).Once() + }), "latest").Return(errors.New("error")).Once() // Non-revert errors are logged but should not prevent transmission, and do not need // to be passed to the caller diff --git a/core/cmd/cosmos_node_commands_test.go b/core/cmd/cosmos_node_commands_test.go index 93364b74e0b..c19749ecd12 100644 --- a/core/cmd/cosmos_node_commands_test.go +++ b/core/cmd/cosmos_node_commands_test.go @@ -6,11 +6,12 @@ import ( "testing" "github.com/pelletier/go-toml/v2" - coscfg "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos/config" - "github.com/smartcontractkit/chainlink-relay/pkg/utils" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + coscfg "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos/config" + "github.com/smartcontractkit/chainlink-relay/pkg/utils" + "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" "github.com/smartcontractkit/chainlink/v2/core/chains/cosmos" diff --git a/core/gethwrappers/versions.go b/core/gethwrappers/versions.go index 5b65e2f411a..acdefd06a59 100644 --- a/core/gethwrappers/versions.go +++ b/core/gethwrappers/versions.go @@ -54,7 +54,7 @@ func versionsDBLineReader() (*bufio.Scanner, error) { } -// readVersionsDB populates an IntegratedVersion with all the info in the +// ReadVersionsDB populates an IntegratedVersion with all the info in the // versions DB func ReadVersionsDB() (*IntegratedVersion, error) { rv := IntegratedVersion{} @@ -87,7 +87,7 @@ func ReadVersionsDB() (*IntegratedVersion, error) { } _, alreadyExists := rv.ContractVersions[topic] if alreadyExists { - return nil, errors.Errorf(`topic "%s" already mentioned!`, topic) + return nil, errors.Errorf(`topic "%s" already mentioned`, topic) } rv.ContractVersions[topic] = ContractVersion{ AbiPath: line[1], BinaryPath: line[2], Hash: line[3], diff --git a/core/services/chainlink/config_general.go b/core/services/chainlink/config_general.go index 688215c6978..33be81add5d 100644 --- a/core/services/chainlink/config_general.go +++ b/core/services/chainlink/config_general.go @@ -3,7 +3,6 @@ package chainlink import ( _ "embed" "fmt" - "net/url" "os" "path/filepath" "strings" @@ -506,7 +505,4 @@ func (g *generalConfig) Threshold() coreconfig.Threshold { return &thresholdConfig{s: g.secrets.Threshold} } -var ( - zeroURL = url.URL{} - zeroSha256Hash = models.Sha256Hash{} -) +var zeroSha256Hash = models.Sha256Hash{} diff --git a/core/services/functions/listener_test.go b/core/services/functions/listener_test.go index a06fcf3e3b2..2bcf2542638 100644 --- a/core/services/functions/listener_test.go +++ b/core/services/functions/listener_test.go @@ -63,19 +63,19 @@ type FunctionsListenerUniverse struct { func ptr[T any](t T) *T { return &t } var ( - RequestID functions_service.RequestID = newRequestID() - RequestIDStr = fmt.Sprintf("0x%x", [32]byte(RequestID)) - SubscriptionOwner common.Address = common.BigToAddress(big.NewInt(42069)) - SubscriptionID = uint64(5) - ResultBytes = []byte{0xab, 0xcd} - ErrorBytes = []byte{0xff, 0x11} - Domains = []string{"github.com", "google.com"} - EncryptedSecretsUrls []byte = []byte{0x11, 0x22} - EncryptedSecrets []byte = []byte(`{"TDH2Ctxt":"eyJHcm","SymCtxt":"+yHR","Nonce":"kgjHyT3Jar0M155E"}`) - DecryptedSecrets []byte = []byte(`{"0x0":"lhcK"}`) - SignedCBORRequestHex = "a666736f75726365782172657475726e2046756e6374696f6e732e656e636f646555696e743235362831296773656372657473421234686c616e6775616765006c636f64654c6f636174696f6e006f736563726574734c6f636174696f6e0170726571756573745369676e617475726558416fb6d10871aa3865b6620dc5f4594d2a9ad9166ba6b1dbc3f508362fd27aa0461babada48979092a11ecadec9c663a2ea99da4e368408b36a3fb414acfefdd2a1c" - SubOwnerAddr common.Address = common.HexToAddress("0x2334dE553AB93c69b0ccbe278B6f5E8350Db6204") - NonSubOwnerAddr common.Address = common.HexToAddress("0x60C9CF55b9de9A956d921A97575108149b758131") + RequestID = newRequestID() + RequestIDStr = fmt.Sprintf("0x%x", [32]byte(RequestID)) + SubscriptionOwner = common.BigToAddress(big.NewInt(42069)) + SubscriptionID = uint64(5) + ResultBytes = []byte{0xab, 0xcd} + ErrorBytes = []byte{0xff, 0x11} + Domains = []string{"github.com", "google.com"} + EncryptedSecretsUrls = []byte{0x11, 0x22} + EncryptedSecrets = []byte(`{"TDH2Ctxt":"eyJHcm","SymCtxt":"+yHR","Nonce":"kgjHyT3Jar0M155E"}`) + DecryptedSecrets = []byte(`{"0x0":"lhcK"}`) + SignedCBORRequestHex = "a666736f75726365782172657475726e2046756e6374696f6e732e656e636f646555696e743235362831296773656372657473421234686c616e6775616765006c636f64654c6f636174696f6e006f736563726574734c6f636174696f6e0170726571756573745369676e617475726558416fb6d10871aa3865b6620dc5f4594d2a9ad9166ba6b1dbc3f508362fd27aa0461babada48979092a11ecadec9c663a2ea99da4e368408b36a3fb414acfefdd2a1c" + SubOwnerAddr = common.HexToAddress("0x2334dE553AB93c69b0ccbe278B6f5E8350Db6204") + NonSubOwnerAddr = common.HexToAddress("0x60C9CF55b9de9A956d921A97575108149b758131") ) func NewFunctionsListenerUniverse(t *testing.T, timeoutSec int, pruneFrequencySec int, setTiers bool, version uint32) *FunctionsListenerUniverse { diff --git a/core/services/keystore/eth.go b/core/services/keystore/eth.go index 9909f398bf4..362baed6afc 100644 --- a/core/services/keystore/eth.go +++ b/core/services/keystore/eth.go @@ -664,24 +664,6 @@ func (ks *eth) add(key ethkey.KeyV2, chainIDs ...*big.Int) (err error) { return err } -func (ks *eth) addWithNonce(key ethkey.KeyV2, chainID *big.Int, nonce int64, isDisabled bool) (err error) { - ks.lock.Lock() - defer ks.lock.Unlock() - err = ks.safeAddKey(key, func(tx pg.Queryer) (merr error) { - state := new(ethkey.State) - sql := `INSERT INTO evm.key_states (address, next_nonce, disabled, evm_chain_id, created_at, updated_at) -VALUES ($1, $2, $3, $4, NOW(), NOW()) RETURNING *;` - if err = ks.orm.q.Get(state, sql, key.Address, nonce, isDisabled, chainID); err != nil { - return errors.Wrap(err, "failed to insert evm_key_state") - } - - ks.keyStates.add(state) - return nil - }) - ks.notify() - return err -} - // notify notifies subscribers that eth keys have changed func (ks *eth) notify() { ks.subscribersMu.RLock() diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/registry.go b/core/services/ocr2/plugins/ocr2keeper/evm21/registry.go index d7cd5f26250..1cad587e635 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/registry.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/registry.go @@ -15,9 +15,10 @@ import ( coreTypes "github.com/ethereum/go-ethereum/core/types" "github.com/patrickmn/go-cache" "github.com/pkg/errors" - ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types" "go.uber.org/multierr" + ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" @@ -144,8 +145,6 @@ type EvmRegistry struct { lastPollBlock int64 ctx context.Context headFunc func(ocr2keepers.BlockKey) - runState int - runError error mercury *MercuryConfig hc HttpClient bs *BlockSubscriber diff --git a/core/services/pipeline/task.bridge_test.go b/core/services/pipeline/task.bridge_test.go index e37b2095236..6f542d485e0 100644 --- a/core/services/pipeline/task.bridge_test.go +++ b/core/services/pipeline/task.bridge_test.go @@ -138,7 +138,7 @@ func fakeIntermittentlyFailingPriceResponder(t *testing.T, requestData map[strin if reqBody.Meta["shouldFail"].(bool) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusBadGateway) - require.NoError(t, json.NewEncoder(w).Encode(errors.New("EA failure!"))) + require.NoError(t, json.NewEncoder(w).Encode(errors.New("EA failure"))) return } w.Header().Set("Content-Type", "application/json") diff --git a/core/services/vrf/v2/integration_v2_test.go b/core/services/vrf/v2/integration_v2_test.go index 531c7ebb663..b26bdf750ba 100644 --- a/core/services/vrf/v2/integration_v2_test.go +++ b/core/services/vrf/v2/integration_v2_test.go @@ -222,9 +222,8 @@ func newVRFCoordinatorV2Universe(t *testing.T, key ethkey.KeyV2, numConsumers in backend.Commit() // Deploy old VRF v2 coordinator from bytecode - err, oldRootContractAddress, oldRootContract := deployOldCoordinator( + oldRootContractAddress, oldRootContract := deployOldCoordinator( t, linkAddress, bhsAddress, linkEthFeed, backend, neil) - require.NoError(t, err) // Deploy the VRFOwner contract, which will own the VRF coordinator // in some tests. @@ -423,7 +422,6 @@ func deployOldCoordinator( backend *backends.SimulatedBackend, neil *bind.TransactOpts, ) ( - error, common.Address, *vrf_coordinator_v2.VRFCoordinatorV2, ) { @@ -447,7 +445,7 @@ func deployOldCoordinator( require.NotEqual(t, common.HexToAddress("0x0"), oldRootContractAddress, "old vrf coordinator address equal to zero address, deployment failed") oldRootContract, err := vrf_coordinator_v2.NewVRFCoordinatorV2(oldRootContractAddress, backend) require.NoError(t, err, "could not create wrapper object for old vrf coordinator v2") - return err, oldRootContractAddress, oldRootContract + return oldRootContractAddress, oldRootContract } // Send eth from prefunded account. diff --git a/core/services/vrf/v2/listener_v2_helpers_test.go b/core/services/vrf/v2/listener_v2_helpers_test.go index 204d1e1fcab..8ba900bdc3a 100644 --- a/core/services/vrf/v2/listener_v2_helpers_test.go +++ b/core/services/vrf/v2/listener_v2_helpers_test.go @@ -7,7 +7,7 @@ import ( "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink/v2/core/assets" - "github.com/smartcontractkit/chainlink/v2/core/services/vrf/v2" + v2 "github.com/smartcontractkit/chainlink/v2/core/services/vrf/v2" ) func TestListener_EstimateFeeJuels(t *testing.T) { diff --git a/core/services/vrf/vrftesthelpers/consumer_v2.go b/core/services/vrf/vrftesthelpers/consumer_v2.go index ec3d727f7ab..abaf97b828b 100644 --- a/core/services/vrf/vrftesthelpers/consumer_v2.go +++ b/core/services/vrf/vrftesthelpers/consumer_v2.go @@ -7,6 +7,7 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" gethtypes "github.com/ethereum/go-ethereum/core/types" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_consumer_v2" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_consumer_v2_plus_upgradeable_example" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_consumer_v2_upgradeable_example" diff --git a/core/web/bridge_types_controller_test.go b/core/web/bridge_types_controller_test.go index 7184b05f5e0..e0048cc64d4 100644 --- a/core/web/bridge_types_controller_test.go +++ b/core/web/bridge_types_controller_test.go @@ -140,7 +140,7 @@ func BenchmarkBridgeTypesController_Index(b *testing.B) { b.ResetTimer() for n := 0; n < b.N; n++ { resp, cleanup := client.Get("/v2/bridge_types") - defer cleanup() + b.Cleanup(cleanup) assert.Equal(b, http.StatusOK, resp.StatusCode, "Response should be successful") } } diff --git a/core/web/nodes_controller.go b/core/web/nodes_controller.go index 1eddc67c364..3547b150bc7 100644 --- a/core/web/nodes_controller.go +++ b/core/web/nodes_controller.go @@ -76,9 +76,9 @@ func (n *nodesController[R]) Index(c *gin.Context, size, page, offset int) { // fetch nodes for chain ID // backward compatibility var rid relay.ID - err := rid.UnmarshalString(id) + err = rid.UnmarshalString(id) if err != nil { - rid.ChainID = relay.ChainID(id) + rid.ChainID = id rid.Network = n.nodeSet.network } nodes, count, err = n.nodeSet.NodeStatuses(c, offset, size, rid) diff --git a/core/web/resolver/chain.go b/core/web/resolver/chain.go index 02573f423a4..53f1016d72b 100644 --- a/core/web/resolver/chain.go +++ b/core/web/resolver/chain.go @@ -2,6 +2,7 @@ package resolver import ( "github.com/graph-gophers/graphql-go" + "github.com/smartcontractkit/chainlink-relay/pkg/types" ) diff --git a/tools/flakeytests/runner_test.go b/tools/flakeytests/runner_test.go index 8fa81db5ba0..c4509ff2cc9 100644 --- a/tools/flakeytests/runner_test.go +++ b/tools/flakeytests/runner_test.go @@ -232,12 +232,6 @@ func TestRunner_RootLevelTest(t *testing.T) { assert.True(t, ok) } -type exitError struct{} - -func (e *exitError) ExitCode() int { return 1 } - -func (e *exitError) Error() string { return "exit code: 1" } - func TestRunner_RerunFailsWithNonzeroExitCode(t *testing.T) { output := `{"Time":"2023-09-07T15:39:46.378315+01:00","Action":"fail","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Test":"TestLink","Elapsed":0}` From e3929ddd6e6dc99ce24bea319eb6fd143f84e650 Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Mon, 9 Oct 2023 11:38:56 -0500 Subject: [PATCH 09/10] .github/workflows: fix race file match (#10885) --- .github/workflows/ci-core.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-core.yml b/.github/workflows/ci-core.yml index ca95d0c55dc..09d805a116e 100644 --- a/.github/workflows/ci-core.yml +++ b/.github/workflows/ci-core.yml @@ -107,7 +107,7 @@ jobs: output-file: ./output-short.txt - name: Print Races if: ${{ failure() && matrix.cmd == 'go_core_race_tests' }} - run: find *.race | xargs cat + run: find race.* | xargs cat - name: Store logs artifacts if: always() uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 # v3.1.0 From a40a6a8deb66f779773d34ef5e4cf321937333ba Mon Sep 17 00:00:00 2001 From: Makram Date: Mon, 9 Oct 2023 21:42:51 +0300 Subject: [PATCH 10/10] chore: update codeowners (#10888) Update CODEOWNERS to specify more fine-grained ownership over specific contracts in the contracts/ directory, as well as some other misc code ownership in various vrf-related directories and files. --- CODEOWNERS | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/CODEOWNERS b/CODEOWNERS index c49affb8aab..0c7e4dc7e7b 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1,5 +1,5 @@ # CODEOWNERS Best Practices -# 1. Per Github docs: "Order is important; the last matching pattern takes the most precedence." +# 1. Per Github docs: "Order is important; the last matching pattern takes the most precedence." # Please define less specific codeowner paths before more specific codeowner paths in order for the more specific rule to have priority # Misc @@ -37,6 +37,10 @@ # VRF-related services /core/services/vrf @smartcontractkit/vrf-team /core/services/blockhashstore @smartcontractkit/vrf-team +/core/services/blockheaderfeeder @smartcontractkit/vrf-team +/core/services/pipeline/task.vrf.go @smartcontractkit/vrf-team +/core/services/pipeline/task.vrfv2.go @smartcontractkit/vrf-team +/core/services/pipeline/task.vrfv2plus.go @smartcontractkit/vrf-team /core/services/ocr2/plugins/dkg @smartcontractkit/vrf-team /core/services/ocr2/plugins/ocr2vrf @smartcontractkit/vrf-team @@ -74,6 +78,10 @@ core/scripts/gateway @bolekk @pinebit /contracts/src/v0.8/functions @smartcontractkit/functions /contracts/test/v0.8/functions @smartcontractkit/functions /contracts/src/v0.8/llo-feeds @austinborn @Fletch153 +/contracts/src/v0.8/vrf @smartcontractkit/vrf-team +/contracts/src/v0.8/dev/vrf @smartcontractkit/vrf-team +/contracts/src/v0.8/dev/BlockhashStore.sol @smartcontractkit/vrf-team +/contracts/src/v0.8/dev/VRFConsumerBaseV2Upgradeable.sol @smartcontractkit/vrf-team # Tests /integration-tests/ @smartcontractkit/test-tooling-team