Skip to content

Commit

Permalink
Merge branch 'ccip-develop' into pick-txm-mantle-error-fix
Browse files Browse the repository at this point in the history
  • Loading branch information
matYang authored Oct 21, 2024
2 parents 198b352 + 4377d9a commit eede056
Show file tree
Hide file tree
Showing 18 changed files with 238 additions and 185 deletions.
243 changes: 122 additions & 121 deletions contracts/gas-snapshots/ccip.gas-snapshot

Large diffs are not rendered by default.

55 changes: 38 additions & 17 deletions contracts/src/v0.8/ccip/FeeQuoter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ contract FeeQuoter is AuthorizedCallers, IFeeQuoter, ITypeAndVersion, IReceiver,

error TokenNotSupported(address token);
error FeeTokenNotSupported(address token);
error ChainNotSupported(uint64 chain);
error StaleGasPrice(uint64 destChainSelector, uint256 threshold, uint256 timePassed);
error StaleKeystoneUpdate(address token, uint256 feedTimestamp, uint256 storedTimeStamp);
error DataFeedValueOutOfUint224Range();
Expand Down Expand Up @@ -76,7 +75,8 @@ contract FeeQuoter is AuthorizedCallers, IFeeQuoter, ITypeAndVersion, IReceiver,
struct StaticConfig {
uint96 maxFeeJuelsPerMsg; // ─╮ Maximum fee that can be charged for a message
address linkToken; // ────────╯ LINK token address
uint32 stalenessThreshold; // The amount of time a gas price can be stale before it is considered invalid.
// The amount of time a token price can be stale before it is considered invalid (gas price staleness is configured per dest chain)
uint32 tokenPriceStalenessThreshold;
}

/// @dev The struct representing the received CCIP feed report from keystone IReceiver.onReport()
Expand All @@ -103,6 +103,7 @@ contract FeeQuoter is AuthorizedCallers, IFeeQuoter, ITypeAndVersion, IReceiver,
uint32 defaultTxGasLimit; //─────────────────╮ Default gas limit for a tx
uint64 gasMultiplierWeiPerEth; // │ Multiplier for gas costs, 1e18 based so 11e17 = 10% extra cost.
uint32 networkFeeUSDCents; // │ Flat network fee to charge for messages, multiples of 0.01 USD
uint32 gasPriceStalenessThreshold; // │ The amount of time a gas price can be stale before it is considered invalid (0 means disabled)
bool enforceOutOfOrder; // │ Whether to enforce the allowOutOfOrderExecution extraArg value to be true.
bytes4 chainFamilySelector; // ──────────────╯ Selector that identifies the destination chain's family. Used to determine the correct validations to perform for the dest chain.
}
Expand Down Expand Up @@ -202,8 +203,8 @@ contract FeeQuoter is AuthorizedCallers, IFeeQuoter, ITypeAndVersion, IReceiver,

/// @dev Subset of tokens which prices tracked by this registry which are fee tokens.
EnumerableSet.AddressSet private s_feeTokens;
/// @dev The amount of time a gas price can be stale before it is considered invalid.
uint32 private immutable i_stalenessThreshold;
/// @dev The amount of time a token price can be stale before it is considered invalid.
uint32 private immutable i_tokenPriceStalenessThreshold;

constructor(
StaticConfig memory staticConfig,
Expand All @@ -216,14 +217,14 @@ contract FeeQuoter is AuthorizedCallers, IFeeQuoter, ITypeAndVersion, IReceiver,
) AuthorizedCallers(priceUpdaters) {
if (
staticConfig.linkToken == address(0) || staticConfig.maxFeeJuelsPerMsg == 0
|| staticConfig.stalenessThreshold == 0
|| staticConfig.tokenPriceStalenessThreshold == 0
) {
revert InvalidStaticConfig();
}

i_linkToken = staticConfig.linkToken;
i_maxFeeJuelsPerMsg = staticConfig.maxFeeJuelsPerMsg;
i_stalenessThreshold = staticConfig.stalenessThreshold;
i_tokenPriceStalenessThreshold = staticConfig.tokenPriceStalenessThreshold;

_applyFeeTokensUpdates(feeTokens, new address[](0));
_updateTokenPriceFeeds(tokenPriceFeeds);
Expand All @@ -241,7 +242,7 @@ contract FeeQuoter is AuthorizedCallers, IFeeQuoter, ITypeAndVersion, IReceiver,
Internal.TimestampedPackedUint224 memory tokenPrice = s_usdPerToken[token];

// If the token price is not stale, return it
if (block.timestamp - tokenPrice.timestamp < i_stalenessThreshold) {
if (block.timestamp - tokenPrice.timestamp < i_tokenPriceStalenessThreshold) {
return tokenPrice;
}

Expand Down Expand Up @@ -305,14 +306,12 @@ contract FeeQuoter is AuthorizedCallers, IFeeQuoter, ITypeAndVersion, IReceiver,
function getTokenAndGasPrices(
address token,
uint64 destChainSelector
) public view returns (uint224 tokenPrice, uint224 gasPriceValue) {
Internal.TimestampedPackedUint224 memory gasPrice = s_usdPerUnitGasByDestChainSelector[destChainSelector];
// We do allow a gas price of 0, but no stale or unset gas prices
if (gasPrice.timestamp == 0) revert ChainNotSupported(destChainSelector);
uint256 timePassed = block.timestamp - gasPrice.timestamp;
if (timePassed > i_stalenessThreshold) revert StaleGasPrice(destChainSelector, i_stalenessThreshold, timePassed);

return (_getValidatedTokenPrice(token), gasPrice.value);
) external view returns (uint224 tokenPrice, uint224 gasPriceValue) {
if (!s_destChainConfigs[destChainSelector].isEnabled) revert DestinationChainNotEnabled(destChainSelector);
return (
_getValidatedTokenPrice(token),
_getValidatedGasPrice(destChainSelector, s_destChainConfigs[destChainSelector].gasPriceStalenessThreshold)
);
}

/// @notice Convert a given token amount to target token amount.
Expand Down Expand Up @@ -374,6 +373,27 @@ contract FeeQuoter is AuthorizedCallers, IFeeQuoter, ITypeAndVersion, IReceiver,
return Internal.TimestampedPackedUint224({value: rebasedValue, timestamp: uint32(block.timestamp)});
}

/// @dev Gets the fee token price and the gas price, both denominated in dollars.
/// @param destChainSelector The destination chain to get the gas price for.
/// @param gasPriceStalenessThreshold The amount of time a gas price can be stale before it is considered invalid.
/// @return gasPriceValue The price of gas in 1e18 dollars per base unit.
function _getValidatedGasPrice(
uint64 destChainSelector,
uint32 gasPriceStalenessThreshold
) private view returns (uint224 gasPriceValue) {
Internal.TimestampedPackedUint224 memory gasPrice = s_usdPerUnitGasByDestChainSelector[destChainSelector];
// If the staleness threshold is 0, we consider the gas price to be always valid
if (gasPriceStalenessThreshold != 0) {
// We do allow a gas price of 0, but no stale or unset gas prices
uint256 timePassed = block.timestamp - gasPrice.timestamp;
if (timePassed > gasPriceStalenessThreshold) {
revert StaleGasPrice(destChainSelector, gasPriceStalenessThreshold, timePassed);
}
}

return gasPrice.value;
}

// ================================================================
// │ Fee tokens │
// ================================================================
Expand Down Expand Up @@ -507,7 +527,8 @@ contract FeeQuoter is AuthorizedCallers, IFeeQuoter, ITypeAndVersion, IReceiver,
_validateMessage(destChainConfig, message.data.length, numberOfTokens, message.receiver);

// The below call asserts that feeToken is a supported token
(uint224 feeTokenPrice, uint224 packedGasPrice) = getTokenAndGasPrices(message.feeToken, destChainSelector);
uint224 feeTokenPrice = _getValidatedTokenPrice(message.feeToken);
uint224 packedGasPrice = _getValidatedGasPrice(destChainSelector, destChainConfig.gasPriceStalenessThreshold);

// Calculate premiumFee in USD with 18 decimals precision first.
// If message-only and no token transfers, a flat network fee is charged.
Expand Down Expand Up @@ -990,7 +1011,7 @@ contract FeeQuoter is AuthorizedCallers, IFeeQuoter, ITypeAndVersion, IReceiver,
return StaticConfig({
maxFeeJuelsPerMsg: i_maxFeeJuelsPerMsg,
linkToken: i_linkToken,
stalenessThreshold: i_stalenessThreshold
tokenPriceStalenessThreshold: i_tokenPriceStalenessThreshold
});
}
}
43 changes: 34 additions & 9 deletions contracts/src/v0.8/ccip/test/feeQuoter/FeeQuoter.t.sol
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.24;

import {IFeeQuoter} from "../../interfaces/IFeeQuoter.sol";

import {KeystoneFeedsPermissionHandler} from "../../../keystone/KeystoneFeedsPermissionHandler.sol";
import {AuthorizedCallers} from "../../../shared/access/AuthorizedCallers.sol";
import {MockV3Aggregator} from "../../../tests/MockV3Aggregator.sol";
Expand Down Expand Up @@ -35,7 +33,7 @@ contract FeeQuoter_constructor is FeeQuoterSetup {
FeeQuoter.StaticConfig memory staticConfig = FeeQuoter.StaticConfig({
linkToken: s_sourceTokens[0],
maxFeeJuelsPerMsg: MAX_MSG_FEES_JUELS,
stalenessThreshold: uint32(TWELVE_HOURS)
tokenPriceStalenessThreshold: uint32(TWELVE_HOURS)
});
s_feeQuoter = new FeeQuoterHelper(
staticConfig,
Expand Down Expand Up @@ -93,7 +91,7 @@ contract FeeQuoter_constructor is FeeQuoterSetup {
FeeQuoter.StaticConfig memory staticConfig = FeeQuoter.StaticConfig({
linkToken: s_sourceTokens[0],
maxFeeJuelsPerMsg: MAX_MSG_FEES_JUELS,
stalenessThreshold: 0
tokenPriceStalenessThreshold: 0
});

vm.expectRevert(FeeQuoter.InvalidStaticConfig.selector);
Expand All @@ -113,7 +111,7 @@ contract FeeQuoter_constructor is FeeQuoterSetup {
FeeQuoter.StaticConfig memory staticConfig = FeeQuoter.StaticConfig({
linkToken: address(0),
maxFeeJuelsPerMsg: MAX_MSG_FEES_JUELS,
stalenessThreshold: uint32(TWELVE_HOURS)
tokenPriceStalenessThreshold: uint32(TWELVE_HOURS)
});

vm.expectRevert(FeeQuoter.InvalidStaticConfig.selector);
Expand All @@ -133,7 +131,7 @@ contract FeeQuoter_constructor is FeeQuoterSetup {
FeeQuoter.StaticConfig memory staticConfig = FeeQuoter.StaticConfig({
linkToken: s_sourceTokens[0],
maxFeeJuelsPerMsg: 0,
stalenessThreshold: uint32(TWELVE_HOURS)
tokenPriceStalenessThreshold: uint32(TWELVE_HOURS)
});

vm.expectRevert(FeeQuoter.InvalidStaticConfig.selector);
Expand Down Expand Up @@ -173,7 +171,7 @@ contract FeeQuoter_getTokenPrice is FeeQuoterSetup {
uint256 originalTimestampValue = block.timestamp;

// Above staleness threshold
vm.warp(originalTimestampValue + s_feeQuoter.getStaticConfig().stalenessThreshold + 1);
vm.warp(originalTimestampValue + s_feeQuoter.getStaticConfig().tokenPriceStalenessThreshold + 1);

address sourceToken = _initialiseSingleTokenPriceFeed();
Internal.TimestampedPackedUint224 memory tokenPriceAnswer = s_feeQuoter.getTokenPrice(sourceToken);
Expand Down Expand Up @@ -596,8 +594,35 @@ contract FeeQuoter_getTokenAndGasPrices is FeeQuoterSetup {
assertEq(gasPrice, priceUpdates.gasPriceUpdates[0].usdPerUnitGas);
}

function test_StalenessCheckDisabled_Success() public {
uint64 neverStaleChainSelector = 345678;
FeeQuoter.DestChainConfigArgs[] memory destChainConfigArgs = _generateFeeQuoterDestChainConfigArgs();
destChainConfigArgs[0].destChainSelector = neverStaleChainSelector;
destChainConfigArgs[0].destChainConfig.gasPriceStalenessThreshold = 0; // disables the staleness check

s_feeQuoter.applyDestChainConfigUpdates(destChainConfigArgs);

Internal.GasPriceUpdate[] memory gasPriceUpdates = new Internal.GasPriceUpdate[](1);
gasPriceUpdates[0] = Internal.GasPriceUpdate({destChainSelector: neverStaleChainSelector, usdPerUnitGas: 999});

Internal.PriceUpdates memory priceUpdates =
Internal.PriceUpdates({tokenPriceUpdates: new Internal.TokenPriceUpdate[](0), gasPriceUpdates: gasPriceUpdates});
s_feeQuoter.updatePrices(priceUpdates);

// this should have no affect! But we do it anyway to make sure the staleness check is disabled
vm.warp(block.timestamp + 52_000_000 weeks); // 1M-ish years

(, uint224 gasPrice) = s_feeQuoter.getTokenAndGasPrices(s_sourceFeeToken, neverStaleChainSelector);

assertEq(gasPrice, 999);
}

function test_ZeroGasPrice_Success() public {
uint64 zeroGasDestChainSelector = 345678;
FeeQuoter.DestChainConfigArgs[] memory destChainConfigArgs = _generateFeeQuoterDestChainConfigArgs();
destChainConfigArgs[0].destChainSelector = zeroGasDestChainSelector;

s_feeQuoter.applyDestChainConfigUpdates(destChainConfigArgs);
Internal.GasPriceUpdate[] memory gasPriceUpdates = new Internal.GasPriceUpdate[](1);
gasPriceUpdates[0] = Internal.GasPriceUpdate({destChainSelector: zeroGasDestChainSelector, usdPerUnitGas: 0});

Expand All @@ -607,11 +632,11 @@ contract FeeQuoter_getTokenAndGasPrices is FeeQuoterSetup {

(, uint224 gasPrice) = s_feeQuoter.getTokenAndGasPrices(s_sourceFeeToken, zeroGasDestChainSelector);

assertEq(gasPrice, priceUpdates.gasPriceUpdates[0].usdPerUnitGas);
assertEq(gasPrice, 0);
}

function test_UnsupportedChain_Revert() public {
vm.expectRevert(abi.encodeWithSelector(FeeQuoter.ChainNotSupported.selector, DEST_CHAIN_SELECTOR + 1));
vm.expectRevert(abi.encodeWithSelector(FeeQuoter.DestinationChainNotEnabled.selector, DEST_CHAIN_SELECTOR + 1));
s_feeQuoter.getTokenAndGasPrices(s_sourceTokens[0], DEST_CHAIN_SELECTOR + 1);
}

Expand Down
3 changes: 2 additions & 1 deletion contracts/src/v0.8/ccip/test/feeQuoter/FeeQuoterSetup.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ contract FeeQuoterSetup is TokenSetup {
FeeQuoter.StaticConfig({
linkToken: s_sourceTokens[0],
maxFeeJuelsPerMsg: MAX_MSG_FEES_JUELS,
stalenessThreshold: uint32(TWELVE_HOURS)
tokenPriceStalenessThreshold: uint32(TWELVE_HOURS)
}),
priceUpdaters,
feeTokens,
Expand Down Expand Up @@ -254,6 +254,7 @@ contract FeeQuoterSetup is TokenSetup {
defaultTxGasLimit: GAS_LIMIT,
gasMultiplierWeiPerEth: 5e17,
networkFeeUSDCents: 1_00,
gasPriceStalenessThreshold: uint32(TWELVE_HOURS),
enforceOutOfOrder: false,
chainFamilySelector: Internal.CHAIN_FAMILY_SELECTOR_EVM
})
Expand Down
6 changes: 3 additions & 3 deletions core/gethwrappers/ccip/deployment_test/deployment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,9 @@ func TestDeployAllV1_6(t *testing.T) {
owner,
chain,
fee_quoter.FeeQuoterStaticConfig{
MaxFeeJuelsPerMsg: big.NewInt(1e18),
LinkToken: common.HexToAddress("0x1"),
StalenessThreshold: 10,
MaxFeeJuelsPerMsg: big.NewInt(1e18),
LinkToken: common.HexToAddress("0x1"),
TokenPriceStalenessThreshold: 10,
},
[]common.Address{common.HexToAddress("0x1")},
[]common.Address{common.HexToAddress("0x2")},
Expand Down
15 changes: 8 additions & 7 deletions core/gethwrappers/ccip/generated/fee_quoter/fee_quoter.go

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ commit_store_helper: ../../../contracts/solc/v0.8.24/CommitStoreHelper/CommitSto
ether_sender_receiver: ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.abi ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.bin 09510a3f773f108a3c231e8d202835c845ded862d071ec54c4f89c12d868b8de
evm_2_evm_offramp: ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.bin b0d77babbe635cd6ba04c2af049badc9e9d28a4b6ed6bb75f830ad902a618beb
evm_2_evm_onramp: ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.bin 5c02c2b167946b3467636ff2bb58594cb4652fc63d8bdfee2488ed562e2a3e50
fee_quoter: ../../../contracts/solc/v0.8.24/FeeQuoter/FeeQuoter.abi ../../../contracts/solc/v0.8.24/FeeQuoter/FeeQuoter.bin 6806f01f305df73a923361f128b8962e9a8d3e7338a9a5b5fbe0636e6c9fc35f
fee_quoter: ../../../contracts/solc/v0.8.24/FeeQuoter/FeeQuoter.abi ../../../contracts/solc/v0.8.24/FeeQuoter/FeeQuoter.bin 503823a939ff99fe3bdaaef7a89cd4bbe475e260d3921335dbf9c80d4f584b76
lock_release_token_pool: ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.bin e6a8ec9e8faccb1da7d90e0f702ed72975964f97dc3222b54cfcca0a0ba3fea2
lock_release_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.bin e632b08be0fbd1d013e8b3a9d75293d0d532b83071c531ff2be1deec1fa48ec1
maybe_revert_message_receiver: ../../../contracts/solc/v0.8.24/MaybeRevertMessageReceiver/MaybeRevertMessageReceiver.abi ../../../contracts/solc/v0.8.24/MaybeRevertMessageReceiver/MaybeRevertMessageReceiver.bin d73956c26232ebcc4a5444429fa99cbefed960e323be9b5a24925885c2e477d5
Expand Down
2 changes: 1 addition & 1 deletion core/scripts/ccip/manual-execution/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ go 1.20
require (
github.com/ethereum/go-ethereum v1.11.3
github.com/pkg/errors v0.9.1
github.com/smartcontractkit/chain-selectors v1.0.23
github.com/smartcontractkit/chain-selectors v1.0.27
go.uber.org/multierr v1.1.0
golang.org/x/crypto v0.1.0
)
Expand Down
4 changes: 2 additions & 2 deletions core/scripts/ccip/manual-execution/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1:Bn1aCHHRnjv4Bl16T8rcaFjYSrGrIZvpiGO6P3Q4GpU=
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/smartcontractkit/chain-selectors v1.0.23 h1:D2Eaex4Cw/O7Lg3tX6WklOqnjjIQAEBnutCtksPzVDY=
github.com/smartcontractkit/chain-selectors v1.0.23/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE=
github.com/smartcontractkit/chain-selectors v1.0.27 h1:VE/ftX9Aae4gnw67yR1raKi+30iWKL/sWq8uyiLHM8k=
github.com/smartcontractkit/chain-selectors v1.0.27/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE=
github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY=
Expand Down
2 changes: 1 addition & 1 deletion core/scripts/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ require (
github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.17.0
github.com/shopspring/decimal v1.4.0
github.com/smartcontractkit/chain-selectors v1.0.25
github.com/smartcontractkit/chain-selectors v1.0.27
github.com/smartcontractkit/chainlink-automation v1.0.4
github.com/smartcontractkit/chainlink-common v0.2.2-0.20240723123524-e407ecd120b1
github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000
Expand Down
4 changes: 2 additions & 2 deletions core/scripts/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1070,8 +1070,8 @@ github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMB
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/smartcontractkit/chain-selectors v1.0.25 h1:TrcpbCsDRJ1322ukdi64KBou4aabPnQ1OYfQMFMrjcg=
github.com/smartcontractkit/chain-selectors v1.0.25/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE=
github.com/smartcontractkit/chain-selectors v1.0.27 h1:VE/ftX9Aae4gnw67yR1raKi+30iWKL/sWq8uyiLHM8k=
github.com/smartcontractkit/chain-selectors v1.0.27/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE=
github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8=
github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM=
github.com/smartcontractkit/chainlink-common v0.2.2-0.20240723123524-e407ecd120b1 h1:pdEpjgbZ5w/Sd5lzg/XiuC5gVyrmSovOo+3nUD46SP8=
Expand Down
Loading

0 comments on commit eede056

Please sign in to comment.