Skip to content

Commit

Permalink
Merge branch 'develop' into tt_922_automation_seth
Browse files Browse the repository at this point in the history
  • Loading branch information
Tofel committed May 9, 2024
2 parents edc4a24 + 579ab3d commit 0bd7419
Show file tree
Hide file tree
Showing 84 changed files with 2,322 additions and 1,023 deletions.
5 changes: 5 additions & 0 deletions .changeset/big-trees-help.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"chainlink": patch
---

core/services: fix ocrWrapper saveError contexts #internal
5 changes: 5 additions & 0 deletions .changeset/heavy-mails-rule.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"chainlink": patch
---

Add logs for when the assumptions of how the log buffer will be used are violated #internal
5 changes: 5 additions & 0 deletions .changeset/poor-gorillas-give.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"chainlink": patch
---

#changed CCIP price cache to use DB timestamp
5 changes: 5 additions & 0 deletions .changeset/sharp-walls-poke.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"chainlink": patch
---

add upkeepCharged event #bugfix
5 changes: 5 additions & 0 deletions .changeset/swift-mugs-push.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"chainlink": minor
---

Decouple gas tests from core #internal
5 changes: 5 additions & 0 deletions contracts/.changeset/fresh-rivers-think.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@chainlink/contracts": patch
---

add upkeepCharged event #bugfix
2 changes: 1 addition & 1 deletion contracts/scripts/native_solc_compile_all_shared
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,4 @@ compileContract shared/token/ERC677/BurnMintERC677.sol
compileContract shared/token/ERC677/LinkToken.sol
compileContract shared/mocks/WERC20Mock.sol
compileContract vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/ERC20.sol
compileContract shared/test/helpers/ChainReaderTestContract.sol
compileContract shared/test/helpers/ChainReaderTester.sol

Large diffs are not rendered by default.

22 changes: 2 additions & 20 deletions contracts/src/v0.8/automation/dev/v2_3/AutomationRegistry2_3.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,14 @@ import {AutomationRegistryBase2_3} from "./AutomationRegistryBase2_3.sol";
import {AutomationRegistryLogicA2_3} from "./AutomationRegistryLogicA2_3.sol";
import {AutomationRegistryLogicC2_3} from "./AutomationRegistryLogicC2_3.sol";
import {Chainable} from "../../Chainable.sol";
import {IERC677Receiver} from "../../../shared/interfaces/IERC677Receiver.sol";
import {OCR2Abstract} from "../../../shared/ocr2/OCR2Abstract.sol";
import {IERC20Metadata as IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/extensions/IERC20Metadata.sol";

/**
* @notice Registry for adding work for Chainlink nodes to perform on client
* contracts. Clients must support the AutomationCompatibleInterface interface.
*/
contract AutomationRegistry2_3 is AutomationRegistryBase2_3, OCR2Abstract, Chainable, IERC677Receiver {
contract AutomationRegistry2_3 is AutomationRegistryBase2_3, OCR2Abstract, Chainable {
using Address for address;
using EnumerableSet for EnumerableSet.UintSet;
using EnumerableSet for EnumerableSet.AddressSet;
Expand Down Expand Up @@ -213,7 +212,7 @@ contract AutomationRegistry2_3 is AutomationRegistryBase2_3, OCR2Abstract, Chain
emit UpkeepPerformed(
report.upkeepIds[i],
upkeepTransmitInfo[i].performSuccess,
receipt.gasReimbursementInJuels + receipt.premiumInJuels, // TODO - this is currently the LINK amount, but may change to billing token
receipt.gasChargeInBillingToken + receipt.premiumInBillingToken,
upkeepTransmitInfo[i].gasUsed,
gasOverhead,
report.triggers[i]
Expand All @@ -227,23 +226,6 @@ contract AutomationRegistry2_3 is AutomationRegistryBase2_3, OCR2Abstract, Chain
s_reserveAmounts[IERC20(address(i_link))] += transmitVars.totalReimbursement + transmitVars.totalPremium;
}

/**
* @notice uses LINK's transferAndCall to LINK and add funding to an upkeep
* @dev safe to cast uint256 to uint96 as total LINK supply is under UINT96MAX
* @param sender the account which transferred the funds
* @param amount number of LINK transfer
*/
function onTokenTransfer(address sender, uint256 amount, bytes calldata data) external override {
if (msg.sender != address(i_link)) revert OnlyCallableByLINKToken();
if (data.length != 32) revert InvalidDataLength();
uint256 id = abi.decode(data, (uint256));
if (s_upkeep[id].maxValidBlocknumber != UINT32_MAX) revert UpkeepCancelled();
if (address(s_upkeep[id].billingToken) != address(i_link)) revert InvalidToken();
s_upkeep[id].balance = s_upkeep[id].balance + uint96(amount);
s_reserveAmounts[IERC20(address(i_link))] = s_reserveAmounts[IERC20(address(i_link))] + amount;
emit FundsAdded(id, sender, uint96(amount));
}

// ================================================================
// | OCR2ABSTRACT |
// ================================================================
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ abstract contract AutomationRegistryBase2_3 is ConfirmedOwner {
// Next block of constants are only used in maxPayment estimation during checkUpkeep simulation
// These values are calibrated using hardhat tests which simulate various cases and verify that
// the variables result in accurate estimation
uint256 internal constant REGISTRY_CONDITIONAL_OVERHEAD = 93_000; // Fixed gas overhead for conditional upkeeps
uint256 internal constant REGISTRY_LOG_OVERHEAD = 118_000; // Fixed gas overhead for log upkeeps
uint256 internal constant REGISTRY_CONDITIONAL_OVERHEAD = 97_700; // Fixed gas overhead for conditional upkeeps
uint256 internal constant REGISTRY_LOG_OVERHEAD = 122_000; // Fixed gas overhead for log upkeeps
uint256 internal constant REGISTRY_PER_SIGNER_GAS_OVERHEAD = 5_600; // Value scales with f
uint256 internal constant REGISTRY_PER_PERFORM_BYTE_GAS_OVERHEAD = 24; // Per perform data byte overhead

Expand All @@ -59,7 +59,7 @@ abstract contract AutomationRegistryBase2_3 is ConfirmedOwner {
// to account for gas used in payment processing. These values are calibrated using hardhat tests which simulates various cases and verifies that
// the variables result in accurate estimation
uint256 internal constant ACCOUNTING_FIXED_GAS_OVERHEAD = 51_200; // Fixed overhead per tx
uint256 internal constant ACCOUNTING_PER_UPKEEP_GAS_OVERHEAD = 9_200; // Overhead per upkeep performed in batch
uint256 internal constant ACCOUNTING_PER_UPKEEP_GAS_OVERHEAD = 13_200; // Overhead per upkeep performed in batch

LinkTokenInterface internal immutable i_link;
AggregatorV3Interface internal immutable i_linkUSDFeed;
Expand Down Expand Up @@ -441,8 +441,16 @@ abstract contract AutomationRegistryBase2_3 is ConfirmedOwner {
struct PaymentReceipt {
uint96 gasChargeInBillingToken;
uint96 premiumInBillingToken;
// one word ends
uint96 gasReimbursementInJuels;
uint96 premiumInJuels;
// second word ends
IERC20 billingToken;
uint96 linkUSD;
// third word ends
uint96 nativeUSD;
uint96 billingUSD;
// fourth word ends
}

event AdminPrivilegeConfigSet(address indexed admin, bytes privilegeConfig);
Expand Down Expand Up @@ -480,6 +488,7 @@ abstract contract AutomationRegistryBase2_3 is ConfirmedOwner {
uint256 gasOverhead,
bytes trigger
);
event UpkeepCharged(uint256 indexed id, PaymentReceipt receipt);
event UpkeepPrivilegeConfigSet(uint256 indexed id, bytes privilegeConfig);
event UpkeepReceived(uint256 indexed id, uint256 startingBalance, address importedFrom);
event UpkeepRegistered(uint256 indexed id, uint32 performGas, address admin);
Expand Down Expand Up @@ -655,11 +664,11 @@ abstract contract AutomationRegistryBase2_3 is ConfirmedOwner {
}

/**
* @dev calculates LINK paid for gas spent plus a configure premium percentage
* @param hotVars the hot path variables
* @param paymentParams the pricing data and gas usage data
* @return receipt the receipt of payment with pricing breakdown
* @dev use of PaymentParams struct is necessary to avoid stack too deep errors
* @dev calculates LINK paid for gas spent plus a configure premium percentage
* @dev 1 USD = 1e18 attoUSD
* @dev 1 USD = 1e26 hexaicosaUSD (had to borrow this prefix from geometry because there is no metric prefix for 1e-26)
* @dev 1 millicent = 1e-5 USD = 1e13 attoUSD
Expand Down Expand Up @@ -702,6 +711,11 @@ abstract contract AutomationRegistryBase2_3 is ConfirmedOwner {
);
receipt.premiumInJuels = SafeCast.toUint96(premiumHexaicosaUSD / paymentParams.linkUSD);

receipt.billingToken = paymentParams.billingToken;
receipt.linkUSD = SafeCast.toUint96(paymentParams.linkUSD);
receipt.nativeUSD = SafeCast.toUint96(paymentParams.nativeUSD);
receipt.billingUSD = SafeCast.toUint96(paymentParams.billingTokenParams.priceUSD);

return receipt;
}

Expand Down Expand Up @@ -1026,6 +1040,7 @@ abstract contract AutomationRegistryBase2_3 is ConfirmedOwner {
s_upkeep[upkeepId].amountSpent += payment;
s_reserveAmounts[paymentParams.billingToken] -= payment;

emit UpkeepCharged(upkeepId, receipt);
return receipt;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@ import {UpkeepTranscoderInterfaceV2} from "../../interfaces/UpkeepTranscoderInte
import {MigratableKeeperRegistryInterfaceV2} from "../../interfaces/MigratableKeeperRegistryInterfaceV2.sol";
import {IERC20Metadata as IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import {SafeERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol";
import {IERC677Receiver} from "../../../shared/interfaces/IERC677Receiver.sol";

/**
* @notice Logic contract, works in tandem with AutomationRegistry as a proxy
*/
contract AutomationRegistryLogicA2_3 is AutomationRegistryBase2_3, Chainable {
contract AutomationRegistryLogicA2_3 is AutomationRegistryBase2_3, Chainable, IERC677Receiver {
using Address for address;
using EnumerableSet for EnumerableSet.UintSet;
using EnumerableSet for EnumerableSet.AddressSet;
Expand All @@ -43,6 +44,23 @@ contract AutomationRegistryLogicA2_3 is AutomationRegistryBase2_3, Chainable {
Chainable(address(logicB))
{}

/**
* @notice uses LINK's transferAndCall to LINK and add funding to an upkeep
* @dev safe to cast uint256 to uint96 as total LINK supply is under UINT96MAX
* @param sender the account which transferred the funds
* @param amount number of LINK transfer
*/
function onTokenTransfer(address sender, uint256 amount, bytes calldata data) external override {
if (msg.sender != address(i_link)) revert OnlyCallableByLINKToken();
if (data.length != 32) revert InvalidDataLength();
uint256 id = abi.decode(data, (uint256));
if (s_upkeep[id].maxValidBlocknumber != UINT32_MAX) revert UpkeepCancelled();
if (address(s_upkeep[id].billingToken) != address(i_link)) revert InvalidToken();
s_upkeep[id].balance = s_upkeep[id].balance + uint96(amount);
s_reserveAmounts[IERC20(address(i_link))] = s_reserveAmounts[IERC20(address(i_link))] + amount;
emit FundsAdded(id, sender, uint96(amount));
}

// ================================================================
// | UPKEEP MANAGEMENT |
// ================================================================
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ struct InnerTestStruct {
string S;
}

contract LatestValueHolder {
contract ChainReaderTester {
event Triggered(
int32 indexed field,
string differentField,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ const emptyBytes = '0x'
const emptyBytes32 =
'0x0000000000000000000000000000000000000000000000000000000000000000'

const transmitGasOverhead = 1_000_000
const transmitGasOverhead = 1_025_000
const checkGasOverhead = 600_000

const stalenessSeconds = BigNumber.from(43820)
Expand Down
2 changes: 1 addition & 1 deletion core/chains/evm/forwarders/forwarder_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ func (f *FwdMgr) runLoop() {
f.latestBlock,
[]common.Hash{authChangedTopic},
addrs,
evmlogpoller.Confirmations(f.cfg.FinalityDepth()),
evmtypes.Confirmations(f.cfg.FinalityDepth()),
)
if err != nil {
f.logger.Errorw("Failed to retrieve latest log round", "err", err)
Expand Down
23 changes: 12 additions & 11 deletions core/chains/evm/gas/arbitrum_estimator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ import (

"github.com/smartcontractkit/chainlink-common/pkg/logger"
"github.com/smartcontractkit/chainlink-common/pkg/services/servicetest"
"github.com/smartcontractkit/chainlink-common/pkg/utils/tests"

"github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/mocks"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/rollups"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
)

type arbConfig struct {
Expand Down Expand Up @@ -57,7 +58,7 @@ func TestArbitrumEstimator(t *testing.T) {
l1Oracle := rollups.NewArbitrumL1GasOracle(logger.Test(t), feeEstimatorClient)

o := gas.NewArbitrumEstimator(logger.Test(t), &arbConfig{}, feeEstimatorClient, l1Oracle)
_, _, err := o.GetLegacyGas(testutils.Context(t), calldata, gasLimit, maxGasPrice)
_, _, err := o.GetLegacyGas(tests.Context(t), calldata, gasLimit, maxGasPrice)
assert.EqualError(t, err, "estimator is not started")
})

Expand All @@ -83,7 +84,7 @@ func TestArbitrumEstimator(t *testing.T) {

o := gas.NewArbitrumEstimator(logger.Test(t), &arbConfig{v: maxGasLimit, bumpPercent: bumpPercent, bumpMin: bumpMin}, feeEstimatorClient, l1Oracle)
servicetest.RunHealthy(t, o)
gasPrice, chainSpecificGasLimit, err := o.GetLegacyGas(testutils.Context(t), calldata, gasLimit, maxGasPrice)
gasPrice, chainSpecificGasLimit, err := o.GetLegacyGas(tests.Context(t), calldata, gasLimit, maxGasPrice)
require.NoError(t, err)
// Expected price for a standard l2_suggested_estimator would be 42, but we add a fixed gasPriceBufferPercentage.
assert.Equal(t, assets.NewWeiI(42).AddPercentage(gasPriceBufferPercentage), gasPrice)
Expand All @@ -109,7 +110,7 @@ func TestArbitrumEstimator(t *testing.T) {
}).Return(zeros.Bytes(), nil)

servicetest.RunHealthy(t, o)
gasPrice, chainSpecificGasLimit, err := o.GetLegacyGas(testutils.Context(t), calldata, gasLimit, assets.NewWeiI(40))
gasPrice, chainSpecificGasLimit, err := o.GetLegacyGas(tests.Context(t), calldata, gasLimit, assets.NewWeiI(40))
require.Error(t, err)
assert.EqualError(t, err, "estimated gas price: 42 wei is greater than the maximum gas price configured: 40 wei")
assert.Nil(t, gasPrice)
Expand All @@ -135,7 +136,7 @@ func TestArbitrumEstimator(t *testing.T) {
}).Return(zeros.Bytes(), nil)

servicetest.RunHealthy(t, o)
gasPrice, chainSpecificGasLimit, err := o.GetLegacyGas(testutils.Context(t), calldata, gasLimit, assets.NewWeiI(110))
gasPrice, chainSpecificGasLimit, err := o.GetLegacyGas(tests.Context(t), calldata, gasLimit, assets.NewWeiI(110))
assert.EqualError(t, err, "estimated gas price: 120 wei is greater than the maximum gas price configured: 110 wei")
assert.Nil(t, gasPrice)
assert.Equal(t, uint64(0), chainSpecificGasLimit)
Expand All @@ -146,7 +147,7 @@ func TestArbitrumEstimator(t *testing.T) {
l1Oracle := rollups.NewArbitrumL1GasOracle(logger.Test(t), feeEstimatorClient)

o := gas.NewArbitrumEstimator(logger.Test(t), &arbConfig{}, feeEstimatorClient, l1Oracle)
_, _, err := o.BumpLegacyGas(testutils.Context(t), assets.NewWeiI(42), gasLimit, assets.NewWeiI(10), nil)
_, _, err := o.BumpLegacyGas(tests.Context(t), assets.NewWeiI(42), gasLimit, assets.NewWeiI(10), nil)
assert.EqualError(t, err, "estimator is not started")
})

Expand All @@ -167,7 +168,7 @@ func TestArbitrumEstimator(t *testing.T) {

servicetest.RunHealthy(t, o)

_, _, err := o.GetLegacyGas(testutils.Context(t), calldata, gasLimit, maxGasPrice)
_, _, err := o.GetLegacyGas(tests.Context(t), calldata, gasLimit, maxGasPrice)
assert.EqualError(t, err, "failed to estimate gas; gas price not set")
})

Expand All @@ -176,7 +177,7 @@ func TestArbitrumEstimator(t *testing.T) {
l1Oracle := rollups.NewArbitrumL1GasOracle(logger.Test(t), feeEstimatorClient)

o := gas.NewArbitrumEstimator(logger.Test(t), &arbConfig{}, feeEstimatorClient, l1Oracle)
_, err := o.GetDynamicFee(testutils.Context(t), maxGasPrice)
_, err := o.GetDynamicFee(tests.Context(t), maxGasPrice)
assert.EqualError(t, err, "dynamic fees are not implemented for this estimator")
})

Expand All @@ -189,7 +190,7 @@ func TestArbitrumEstimator(t *testing.T) {
FeeCap: assets.NewWeiI(42),
TipCap: assets.NewWeiI(5),
}
_, err := o.BumpDynamicFee(testutils.Context(t), fee, maxGasPrice, nil)
_, err := o.BumpDynamicFee(tests.Context(t), fee, maxGasPrice, nil)
assert.EqualError(t, err, "dynamic fees are not implemented for this estimator")
})

Expand Down Expand Up @@ -221,7 +222,7 @@ func TestArbitrumEstimator(t *testing.T) {

o := gas.NewArbitrumEstimator(logger.Test(t), &arbConfig{v: maxGasLimit, bumpPercent: bumpPercent, bumpMin: bumpMin}, feeEstimatorClient, l1Oracle)
servicetest.RunHealthy(t, o)
gasPrice, chainSpecificGasLimit, err := o.GetLegacyGas(testutils.Context(t), calldata, gasLimit, maxGasPrice)
gasPrice, chainSpecificGasLimit, err := o.GetLegacyGas(tests.Context(t), calldata, gasLimit, maxGasPrice)
require.NoError(t, err)
require.NotNil(t, gasPrice)
// Again, a normal l2_suggested_estimator would return 42, but arbitrum_estimator adds a buffer.
Expand Down Expand Up @@ -256,7 +257,7 @@ func TestArbitrumEstimator(t *testing.T) {

o := gas.NewArbitrumEstimator(logger.Test(t), &arbConfig{v: maxGasLimit, bumpPercent: bumpPercent, bumpMin: bumpMin}, feeEstimatorClient, l1Oracle)
servicetest.RunHealthy(t, o)
gasPrice, chainSpecificGasLimit, err := o.GetLegacyGas(testutils.Context(t), calldata, gasLimit, maxGasPrice)
gasPrice, chainSpecificGasLimit, err := o.GetLegacyGas(tests.Context(t), calldata, gasLimit, maxGasPrice)
require.Error(t, err, "expected error but got (%s, %d)", gasPrice, chainSpecificGasLimit)
})
}
4 changes: 2 additions & 2 deletions core/chains/evm/gas/block_history_estimator.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ type estimatorGasEstimatorConfig interface {
type BlockHistoryEstimator struct {
services.StateMachine
ethClient feeEstimatorClient
chainID big.Int
chainID *big.Int
config chainConfig
eConfig estimatorGasEstimatorConfig
bhConfig BlockHistoryConfig
Expand Down Expand Up @@ -127,7 +127,7 @@ type BlockHistoryEstimator struct {
// NewBlockHistoryEstimator returns a new BlockHistoryEstimator that listens
// for new heads and updates the base gas price dynamically based on the
// configured percentile of gas prices in that block
func NewBlockHistoryEstimator(lggr logger.Logger, ethClient feeEstimatorClient, cfg chainConfig, eCfg estimatorGasEstimatorConfig, bhCfg BlockHistoryConfig, chainID big.Int, l1Oracle rollups.L1Oracle) EvmEstimator {
func NewBlockHistoryEstimator(lggr logger.Logger, ethClient feeEstimatorClient, cfg chainConfig, eCfg estimatorGasEstimatorConfig, bhCfg BlockHistoryConfig, chainID *big.Int, l1Oracle rollups.L1Oracle) EvmEstimator {
ctx, cancel := context.WithCancel(context.Background())

b := &BlockHistoryEstimator{
Expand Down
Loading

0 comments on commit 0bd7419

Please sign in to comment.