Skip to content

Same validation is being executed in Keeper and VRF#

Informational

In Keeper.sol there is a performUpkeep function, which makes a call to requestVRF function that is in VRF.sol. Both of these functions perform the same check, which can be seen in performUpkeep on lines 34 - 40, and in requestVRF on lines 102 - 107. There is no need to perform these checks in both of the functions, because of their dependence on each other. If requestVRF fails, performUpkeep fails too.

function performUpkeep(bytes calldata performData) external override {
    uint256 canvasId = abi.decode(performData, (uint256));
    Schema.VRFHelper memory info = ICanvas(canvasAddress).getVRFHelper(canvasId);

    if (
      !info.vrfPending &&
      info.tokenIdCounter - info.randomizedTraitsCounter > 0 &&
      info.vrfLastRunTimestamp + (info.vrfMinuteInterval * 60) < block.timestamp
    ) {
      CanvasVRF(vrfAddress).requestVRF(canvasId);
    }
}
function requestVRF(uint256 canvasId) external {
    Schema.VRFHelper memory info = ICanvas(canvasAddress).getVRFHelper(canvasId);

    if (info.vrfPending ||
        info.tokenIdCounter - info.randomizedTraitsCounter == 0 ||
        info.vrfLastRunTimestamp + (info.vrfMinuteInterval * 60) > block.timestamp)
      revert VRFNotNeeded();

    uint256 requestId = vrfCoordinator.requestRandomWords(keyHash, canvasIdToSubscriptionId[canvasId], 7, 300000, 1);

    vrfToCanvasId[requestId] = canvasId;
    ICanvas(canvasAddress).setVrfResult(canvasId, 0, "requested");
}

Recommendation#

Remove the validation from performUpkeep function and just execute the call to requestVRF.

function performUpkeep(bytes calldata performData) external override {
    uint256 canvasId = abi.decode(performData, (uint256));
    CanvasVRF(vrfAddress).requestVRF(canvasId);
}
Or if you do not want performUpkeep to revert you can do it like this:
function performUpkeep(bytes calldata performData) external override {
    uint256 canvasId = abi.decode(performData, (uint256));
    vrfAddress.call(
      abi.encodeWithSignature(('requestVRF(uint256)'),
      canvasId
    ));
}