Chainlink Controller Factory

The ChainlinkControllerFactory deploys controllers that use Chainlink oracles for price data. The controllers compare a "truth" price with a "tracking" price. If the price delta exceeds a specified tolerance during a check, the controller triggers the associated safety module.

There are two types of Chainlink controllers that the factory can deploy:

  1. Dual-oracle controllers: compare the price feeds of two Chainlink oracles.

  2. Peg-protection controllers: compare the price feed of a Chainlink oracle with a fixed price, or "peg".

Here is a searchable list of available Chainlink oracle addresses, aka "Data Feeds".

Determine Controller Parameters

The parameters required to deploy a dual-oracle controller a peg-protection controller:

struct ControllerMetadata {
  // The name that should be used for SafetyModules that use the controller
  string name;
  // A human-readable description of the controller.
  string description;
  // The URI of a logo image to represent the controller.
  string logoURI;
  // Any extra data that should be included in the controller's metadata.
  string extraData;
}

/// @notice Call this function to deploy a ChainlinkController.
/// @param truthOracle_ The address of the desired truthOracle for the controller.
/// @param trackingOracle_ The address of the desired trackingOracle for the controller.
/// @param priceTolerance_ The priceTolerance that the deployed controller will
/// have. See ChainlinkController.priceTolerance() for more information.
/// @param truthFrequencyTolerance_ The frequency tolerance that the deployed controller will
/// have for the truth oracle. See ChainlinkController.truthFrequencyTolerance() for more information.
/// @param trackingFrequencyTolerance_ The frequency tolerance that the deployed controller will
/// have for the tracking oracle. See ChainlinkController.trackingFrequencyTolerance() for more information.
/// @param metadata_ See ControllerMetadata for more info.
function deployController(
  AggregatorV3Interface truthOracle_,
  AggregatorV3Interface trackingOracle_,
  uint256 priceTolerance_,
  uint256 truthFrequencyTolerance_,
  uint256 trackingFrequencyTolerance_,
  ControllerMetadata memory metadata_
) external returns (ISafetyModuleController controller_);

/// @notice Call this function to deploy a ChainlinkController with a
/// FixedPriceAggregator as its truthOracle. This is useful if you were
/// building a market in which you wanted to track whether or not a stablecoin
/// asset had become depegged.
/// @param _price The fixed price, or peg, with which to compare the trackingOracle price.
/// @param _decimals The number of decimals of the fixed price. This should
/// match the number of decimals used by the desired _trackingOracle.
/// @param _trackingOracle The address of the desired trackingOracle for the controller.
/// @param _priceTolerance The priceTolerance that the deployed controller will
/// have. See ChainlinkController.priceTolerance() for more information.
/// @param _frequencyTolerance The frequency tolerance that the deployed controller will
/// have for the tracking oracle. See ChainlinkController.trackingFrequencyTolerance() for more information.
function deployController(
  int256 _price,
  uint8 _decimals,
  AggregatorV3Interface _trackingOracle,
  uint256 _priceTolerance,
  uint256 _frequencyTolerance,
  ControllerMetadata memory _metadata
) external returns (ISafetyModuleController _controller);

Decimals must match:

  • For a dual-oracle controller, both oracles must use the same number of decimals.

  • For a peg-protection controller, the tracking oracle must return prices with the same number of decimals specified for the peg.

If the truthOracle returns a price of 0, the controller will treat the priceTolerance as exceeded, regardless of the trackingOracle price.

Deploy Controller

For instance, to deploy a dual-oracle controller comparing the mainnet ETH/USD price to the mainnet stETH/USD price and triggering the safety module when the price deviates by more than 10%, use:

factory.deployController(
  AggregatorV3Interface(0x5f4ec3df9cbd43714fe2740f5e3616155c5b8419), // ETH/USD
  AggregatorV3Interface(0xcfe54b5cd566ab89272946f602d76ea879cab4a8), // stETH/USD
  0.1e4, // A >10% price deviation will cause the controller to trigger the Safety Module.
  600, // Truth price must have published within the last 10 minutes to be valid.
  600, // Tracking price must have published within the last 10 minutes to be valid.
  ControllerMetadata("name", "description", "logoURI", "extraData")
);

To deploy a peg-protection controller comparing the mainnet USDT/USD price to a fixed $1 peg, triggering the safety module if the price differs by more than 1%, use:

factory.deployController(
  1e8,    // Fixed price of $1, denominated in 8 decimals.
  8,      // 8 decimal places will be used for the peg, matching the oracle.
  AggregatorV3Interface(0x3e7d1eab13ad0104d2750b8863b489d65364e32d), // USDT/USD oracle
  0.01e4, // A 1% price tolerance.
  3600,    // Price data may be at most 1 hour old.
  ControllerMetadata("name", "category", "description", "logoURI")
);

If an existing controller has the desired configuration, a new controller will not be deployed, and the existing controller's address will be returned.

For the addresses of factories deployed to various chains, see the Contracts Deployment Registry.

Last updated