NEW

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

Back

Data Feed Circuit Breaker Using Chainlink Automation

Build your own Data Feed Circuit Breaker Using Chainlink Automation.

Overview

Circuit breakers are useful for pausing dApps and processes when adverse events are detected onchain. These circuit breakers can prevent loss of assets during volatile market events, unstable network conditions, or if systems that your dApp relies on become compromised.

The example circuit breaker contract is a highly configurable proof of concept that can be used with Data Feeds. It is capable of emitting events or calling custom functions based on predefined conditions, and it comes with an interactive UI that allows users to easily configure and manage the contract.

Objective

The Circuit Breaker repository contains an example implementation of a circuit breaker that can be used with any OCR price feed. You can monitor a given contract, specify the price when the circuit breaker will be triggered based on predefined conditions, and specify the underlying logic of what happens when the circuit breaker is triggered.

Before you begin

You can run this example on Linux, MacOS, or the Windows Subsystem for Linux.

Before you start this tutorial, install the required tools:

  • Install git
    • Run git --version to check the installation. You should see an output similar to git version x.x.x.
  • Install Nodejs 16.0.0 or higher
    • Run node --version to check the installation. You should see an output similar to v16.x.x.
  • Install and configure a cryptocurrency wallet like MetaMask.
  • Add the Avalanche Fuji testnet and LINK to your wallet:

    Avalanche Fuji testnet

  • Add testnet funds to your wallet. You will need both ERC-677 LINK and the gas currency for the chain where your contract is deployed. For this example, use Avalanche Fuji and testnet LINK. You can get both at faucets.chain.link.

Steps to implement

1 Setup the example

To set up this example, clone the source and install the required packages.

  1. Clone the smartcontractkit/quickstarts-circuitbreaker repository and change directories:

    git clone https://github.com/smartcontractkit/quickstarts-circuitbreaker.git && \
    cd quickstarts-circuitbreaker
    
  2. Install the chainlink/contracts npm package:

    npm install @chainlink/[email protected] --save
    

    For this tutorial, disregard the resulting npm warnings.

2 Deploy contracts
  1. Open the ExampleImplementation.sol contract in Remix:

  2. On the Solidity compiler tab, click Compile ExampleImplementation.sol.

  3. On the Deploy and run transactions tab, select Injected Provider - MetaMask for the Environment field. Make sure the ExampleImplementation.sol contract is selected in the Contract field.

  4. Scroll down to the Deploy section:

    Click the dropdown carat to expand the Deploy section:

  5. Enter the following input to the constructor:

    ItemValue
    _MAXBALANCE2000000000000
    _FEEDADDRESS0x31CF013A08c6Ac228C94551d535d5BAfE19c602a
    _EMERGENCYPOSSIBLEtrue
    • The maxBalance in sats. For example, 2000000000000 for a max balance of $20,000.
    • The proxy contract address of the price feed. For example, the address for the BTC/USD price feed on Fuji is 0x31CF013A08c6Ac228C94551d535d5BAfE19c602a. Find other price feed addresses here.
    • The isEmergencyPossible flag: set this to true if you want the circuit breaking condition to be checked. You can turn off this check by setting this value to false.
  6. Click Deploy and confirm the transaction in your wallet.

Next, deploy the CircuitBreaker.sol contract:

  1. Open the CircuitBreaker.sol contract in Remix:

  2. On the Solidity compiler tab, click Compile CircuitBreaker.sol.

  3. On the Deploy and run transactions tab, select Injected Provider - MetaMask for the Environment field. Make sure the CircuitBreaker.sol contract is selected in the Contract field.

  4. There are no constructor inputs for this contract. Click Deploy and confirm the transaction in your wallet.

3 Register and fund an upkeep

Registering an upkeep on Chainlink Automation creates a smart contract that will run your circuit breaker contract.

  1. Click Register new Upkeep.

  2. Select the Custom logic trigger.

  3. For Target contract address, input the address of your deployed CircuitBreaker.sol contract. You can find this in your wallet's transaction history or copy it from Remix:

There may be a warning that says "Unable to verify if this is an Automation compatible contract." The CircuitBreaker.sol contract does implement the AutomationCompatibleInterface so you can disregard this warning. Click Next.

  1. For Upkeep details, add the following:

    • A name for your upkeep
    • A starting balance of 2 testnet LINK
    • The admin address and gas limit are prefilled for you.
    • Although the Check data field is marked optional, it is required for this tutorial. You'll fill this in during the next step.
  2. For your upkeep's Check data field, you need to ABI encode the address of your deployed ExampleImplementation.sol contract.

    1. Navigate to the HashEx Online ABI Encoder.

    2. Click Add argument and select Address as the argument type from the dropdown menu. 1. Enter the address of your deployed ExampleImplementation.sol contract.

    3. From the Encoded data field, copy the encoded address.

    4. Navigate back to the Chainlink Automation app. In the Check Data field, enter 0x and paste in the ABI encoded address of the ExampleImplementation.sol contract.

  3. Click Register upkeep and confirm the transaction in your wallet.

4 Check emergency action

Now the Chainlink Automation network will watch your contract for these trigger parameters. If the price from the feed you provided is above the maxBalance threshold that was specified, the executeEmergencyAction() function will trigger. As defined in ExampleImplementation.sol, the function increments a counter:

/**
 * executes emergency action
 */
function executeEmergencyAction() external {
  counter += 1;
  circuitbrokenflag = true;
  emit emergencyActionPerformed(counter, feedAddress);
}
  1. Navigate to your upkeep in the Chainlink Automation app. If the executeEmergencyAction() function is triggered, you will see "Perform upkeep" logs listed in the History section.
  2. Navigate to Remix and expand the details for your deployed ExampleImplementation.sol contract. Click the counter button to view the value of the counter variable.
  3. If the counter was incremented once, you should see 0: uint256: 1 as the output:
5 Update the example implementation contract

If you want to update your ExampleImplementation.sol contract, you can redeploy it with updated values and then use the same Automation upkeep. For example, to update the maxBalance:

  1. Redeploy the ExampleImplementation.sol contract with your updated maxBalance value.

  2. ABI encode the address of your newly deployed ExampleImplementation.sol contract.

  3. In the Chainlink Automation app, within the Actions menu for your existing upkeep, click Edit check data:

  4. Enter 0x, paste the new ABI-encoded contract address, and click Change check data. MetaMask opens and prompts you to confirm the transaction.

You can use the same process to make other changes to your example implementation contract, like changing the logic in executeEmergencyAction() or changing the price feed that you're monitoring.

Cleanup

If you want to experiment further with this tutorial, you can pause the Automation upkeep so that it stops running while you work on updating your example implementation contract. Otherwise, you can cancel the upkeep to reclaim any unused testnet LINK back to your wallet. Both options are located in the Chainlink Automation app within the Actions menu on your upkeep's details page.

Stay updated on the latest Chainlink news