NEW

CCIP is now live for all developers. See what's new.

Set a gas price threshold on your upkeep

You can set a gas price threshold on your upkeep to prevent your upkeep from being serviced when gas prices exceed the maximum gas price you specify. (This is a different gas setting than the upkeep gas limit, which limits the amount of gas used.) You can set a maximum gas price on conditional upkeeps and log trigger upkeeps.

After you set your maximum gas price, it takes a few minutes to go into effect as it syncs with the nodes. Updating your maximum gas price does not impact any upkeep where the execution is in-flight.

Limitations

Do not use the gas price control when speed of execution is important. The gas price control can significantly delay your execution for conditional upkeeps and prevent execution entirely for log trigger upkeeps.

Gas prices spike after your transaction is in flight

Due to the decentralized nature of the Automation network and its transaction manager, it is possible that your upkeep will be performed at a gas price higher than the maximum gas price you set. This edge case can happen when:

  1. The Automation network determines that the upkeep should be performed while the onchain gas price is below your threshold. After that check occurs, the performUpkeep transaction is in flight (in the mempool).
  2. After the transaction is already in flight, gas prices start spiking and move above your threshold. To ensure that the node's sending key nonce does not become blocked, the node automatically increases the gas to confirm the transaction and prevent the nonce from blocking subsequent transactions.

To avoid this edge case, increase the buffer in your gas price threshold.

Log trigger upkeeps are not retried

If a log trigger upkeep is triggered by a log event, and is declared ineligible to perform the upkeep because gas prices are above your gas price threshold, the upkeep is not retried.

Choose your maximum gas price

Each node compares the specified threshold to its estimate of onchain gas price. A quorum is needed before upkeeps are performed. Nodes may bid aggressively on gas prices to ensure transactions go through. If the node's gas price bid is above your maximum gas price, the node will not perform your upkeep. For example, if you set a gas price threshold of 3 gwei, your upkeep's execution may stop as soon as the node's gas price bid hits 3 gwei, even if the actual gas price is only 2 gwei. To adjust for this, you may need to set a higher gas price threshold.

Create a new upkeep with a gas price threshold

To create a new upkeep with a gas threshold in place, you can create a conditional upkeep or log trigger upkeep programmatically. You need to format and encode your offchain config before you set the offchainConfig parameter.

Set the maximum gas price on an existing upkeep

Set the maximum gas price using the offchainConfig field in your upkeep. Only the upkeep admin can set gas controls for an upkeep. This setting is not yet available in the Automation UI, so it must be done programmatically.

To set the maximum gas price on an upkeep, follow these steps:

  1. Format and encode your offchain config. The offchain config is where you set your maximum gas price.
  2. Run setUpkeepOffchainConfig on the registry using your upkeep ID and the encoded value of your offchain config.

Format and encode your offchain config

Currently, the only parameter that you can set in your upkeep's offchain config is maxGasPrice. You need to format your offchain config as a JSON object and CBOR encode it before you update it on the registry.

  1. Format your offchain config as JSON. For example: {"maxGasPrice": 100000000000}. Use quotation marks only around the key, "maxGasPrice". Do not use quotation marks around the value of the maximum gas price you are setting.

  2. Encode the JSON object using CBOR encoding:

    // SPDX-License-Identifier: MIT
    pragma solidity 0.8.19;
    
    import { CBOR } from "../../vendor/solidity-cborutils/v2.0.0/CBOR.sol"
    
    contract CBOREncoder {
    using CBOR for CBOR.CBORBuffer;
    
    // @notice encodes a max gas price to CBOR encoded bytes
    // @param maxGasPrice The max gas price
    // @return CBOR encoded bytes and the struct depth
    function encode(uint256 maxGasPrice, uint256 capacity) external pure returns (bytes memory, uint256) {
    CBOR.CBORBuffer memory buffer = CBOR.create(capacity);
    buffer.writeString("maxGasPrice");
    buffer.writeUInt256(maxGasPrice);
    return (buffer.buf.buf, buffer.depth);
    }
    }
    

Send the request

Call setUpkeepOffchainConfig on the registry. You can do this directly with MetaMask or an RPC call to the node.

Code example

To run this example, install its dependencies:

npm install ethers cbor
const { ethers } = require("ethers")
const { cbor } = require("cbor")

// Replace with your own provider
const provider = new ethers.providers.JsonRpcProvider("https://mainnet.infura.io/v3/YOUR_INFURA_PROJECT_ID")
const privateKey = "YOUR_PRIVATE_KEY" // Replace with your wallet private key
const wallet = new ethers.Wallet(privateKey, provider)

// The contract address and ABI
const contractAddress = "0x6593c7De001fC8542bB1703532EE1E5aA0D458fD"
const abi = [
  {
    inputs: [
      {
        internalType: "uint256",
        name: "id",
        type: "uint256",
      },
      {
        internalType: "bytes",
        name: "config",
        type: "bytes",
      },
    ],
    name: "setUpkeepOffchainConfig",
    outputs: [],
    stateMutability: "nonpayable",
    type: "function",
  },
]

// Initialize the contract
const contract = new ethers.Contract(contractAddress, abi, wallet)

// The JSON object to be encoded
const myObject = { maxGasPrice: 100000000000 }

// Encode the JSON object to CBOR
const encodedConfig = cbor.encode(myObject)

// The id you want to use (replace with your actual id)
const id = 1

// The function to call the contract
async function setUpkeepOffchainConfig() {
  try {
    const tx = await contract.setUpkeepOffchainConfig(id, encodedConfig)
    console.log("Transaction hash:", tx.hash)

    // Wait for the transaction to be mined
    const receipt = await tx.wait()
    console.log("Transaction was mined in block:", receipt.blockNumber)
  } catch (error) {
    console.error("Error sending transaction:", error)
  }
}
// Call the function
setUpkeepOffchainConfig()

Remove the maximum gas price

To remove the maximum gas price, you can set the value of your offchainConfig back to 0x:

  • Format your request as JSON ({"maxGasPrice": 0x})
  • Encode this request with CBOR encoding.
  • Run setUpkeepOffchainConfig on the registry using your upkeep ID and the CBOR encoded value for 0x.

What's next

Stay updated on the latest Chainlink news