Skip to main content


Contract: JBDirectory​‌

Interface: IJBDirectory

Update the controller that manages how terminals interact with the ecosystem.

A controller can be set if:

  • the message sender is the project owner or an operator having the correct authorization.
  • the message sender is the project's current controller.
  • or, an allowedlisted address is setting a controller for a project that doesn't already have a controller.


function setControllerOf(uint256 _projectId, address _controller)
(msg.sender == address(controllerOf[_projectId]) ||
(isAllowedToSetFirstController[msg.sender] &&
controllerOf[_projectId] == IJBController(address(0))))
) { ... }
  • Arguments:
    • _projectId is the ID of the project to set a new controller for.
    • _controller is the new controller to set.
  • Through the requirePermissionAllowingOverride modifier, the function is only accessible by the project's owner, from an operator that has been given the JBOperations.SET_CONTROLLER permission by the project owner for the provided _projectId, from the project's current controller, or from an allow-listed controller if the project doesn't already have a controller set.
  • The function overrides a function definition from the IJBDirectory interface.
  • The function doesn't return anything


  1. Project IDs are assigned incrementally. If the provided project ID is greater than the number of projects, it must not be a valid project ID.

    // The project must exist.
    if (projects.count() < _projectId) revert INVALID_PROJECT_ID_IN_DIRECTORY();

    Internal references:

    External references:

  2. Get a reference to the project's current funding cycle.

    // Get a reference to the project's current funding cycle.
    JBFundingCycle memory _fundingCycle = fundingCycleStore.currentOf(_projectId);

    Internal references:

    External references:

  3. Make sure the project's current funding cycle is set to allow setting its controller, or the request to set the controller is coming from the project's current controller or is setting the first controller.

    // Setting controller must be allowed if not called from the current controller or if the project already has a controller.
    if (
    msg.sender != address(controllerOf[_projectId]) &&
    controllerOf[_projectId] != address(0) &&

    Library references:

    Internal references:

  4. Store the provided controller as the controller of the project.

    // Set the new controller.
    controllerOf[_projectId] = _controller;

    Internal references:

  5. Emit a SetController event with the relevant parameters.

    emit SetController(_projectId, _controller, msg.sender);

    Event references: