2

I have a keeper performUpKeep function that is mission critical that only a keeper can call and not some random third party to activate the contract sooner. It appears that the Chainlink keepers continually change so how can I ensure only the keepers call the contract?

builderbob
  • 47
  • 3

2 Answers2

3

Ideally, you just need to validate that checkUpKeep is returning true, and you do some data validation on the input to make sure it can only do what you want it to. Per the chainlink github:

  • @dev The input to this method should not be trusted, and the caller of the * method should not even be restricted to any single registry. Anyone should * be able call it, and the input should be validated, there is no guarantee * that the data passed in is the performData returned from checkUpkeep. This * could happen due to malicious keepers, racing keepers, or simply a state * change while the performUpkeep transaction is waiting for confirmation. * Always validate the data passed in.

The below code is not advised to use

If you'd like to ignore this... (which you shouldn't) but you could add an onlyKeepers modifier to your performUpkeep function so only the Keepers registry can call your contract.

    address public keepersRegistry = xxxxxx;
    modifier onlyKeepers() {
        require(msg.sender == keepersRegistry, "Ownable: caller is not keepers registry");
        _;
    }

And then wrap your function in that.

function functionName() onlyKeepers {
....
}
Patrick Collins
  • 11,186
  • 5
  • 44
  • 97
2

Adding to the previous answer, as I'm not sure if it's correct.

The chainlink KeeperCompatibleInterface implementation specifies for the performUpkeep function :

    * @dev The input to this method should not be trusted, and the caller of the
    * method should not even be restricted to any single registry. Anyone should
    * be able call it, and the input should be validated, there is no guarantee
    * that the data passed in is the performData returned from checkUpkeep. This
    * could happen due to malicious keepers, racing keepers, or simply a state
    * change while the performUpkeep transaction is waiting for confirmation.
    * Always validate the data passed in.

Where the important bit is obviously :

 * @dev The input to this method should not be trusted, and the caller of the
 * method should not even be restricted to any single registry.

Given that you must implement a checkUpkeep function, you could simply secure yourself by checking the conditions of checkUpkeep again before calling the performUpkeep logic. If a third-party calls on your contract when an upkeep is required, just do it. If not, revert the transaction.

As specified here.

hroussille
  • 7,661
  • 2
  • 6
  • 29