# Coordinator

## Events

### BatchExecution

```solidity
event BatchExecution(uint8 jobRegistryIndex, uint256 standardTax, uint256 zeroFeeTax, bool inRound)
```

Emitted upon batch execution of jobs via executeBatch.

### EpochInitiated

```solidity
event EpochInitiated(uint192 epoch, uint256 previousEpochPoolDistributed, uint256 protocolCut)
```

Emitted upon initiation of an epoch via initiateEpoch.

### CheckIn

```solidity
event CheckIn(address indexed executor, uint192 indexed epoch, uint8 round)
```

Emitted upon an executor checking in via executeBatch.

### Commitment

```solidity
event Commitment(address indexed executor, uint192 indexed epoch)
```

Emitted upon an executor committing to an epoch via commit.

### Reveal

```solidity
event Reveal(address indexed executor, uint192 indexed epoch, bytes32 newSeed)
```

Emitted upon an executor revealing their commitment for an epoch via reveal.

### InactiveExecutorSlashed

```solidity
event SlashInactiveExecutor(address indexed executor, address indexed slasher, uint192 indexed epoch, uint8 round, uint256 amount)
```

Emitted upon slashing of an executor who did not check in upon designation of a round in an epoch. Is emitted in slashInactiveExecutor.

### CommitterSlashed

```solidity
event SlashCommitter(address indexed executor, address indexed slasher, uint192 indexed epoch, uint256 amount)
```

### ExecutorActivated

```solidity
event ExecutorActivated(address indexed executor)
```

Emitted when an executor is activated. Is emitted in stake and may be emitted in topup.

### ExecutorDeactivated

```solidity
event ExecutorDeactivated(address indexed executor)
```

Emitted when an executor is deactivated. Is emitted in unstake and may be emitted from executeBatch,, slashCommitter and slashInactiveExecutor.

### ModulesRegistered

```solidity
event ModulesRegistered(address indexed executor, uint256 indexed modulesBitset)
```

Emitted upon executor registration of modules via stake and registerModules.

### ModulesDeregistered

```solidity
event ModulesDeregistered(address indexed executor, uint256 indexed modulesBitset)
```

Emitted upon executor deregistration of modules via unstake and deregisterModules.

## State-changing functions

### executeBatch

```solidity
function executeBatch(uint256[] calldata _indices, uint256[] calldata _gasLimits, address _feeRecipient, uint8 _jobRegistryIndex) external returns (uint256 standardTax, uint256 zeroFeeTax, uint96 successfulExecutions)
```

Executes a batch of jobs within a given job registry, transferring execution fees to the `_feeRecipient` and pays execution tax from the callers account. During designated rounds, only the designated executor for that round can execute jobs with both execution module and fee module supported by that executor. Furthermore, designated executors will check in on this call, preventing potential slashing. Lastly, the number of executions where standard execution tax applies is counted and stored for pool reward distribution during initateEpoch.

#### Arguments

| Name                | Type                 | Description                                                                                                                                |
| ------------------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `_indices`          | `uint256[] calldata` | Indices within the job registry of the jobs to be executed.                                                                                |
| `_gasLimits`        | `uint256[] calldata` | Gas limits for each `execute` calls within the job registry. Each gas limit correspond to the index in `_indices` at the same array index. |
| `_feeRecipient`     | `address`            | Address which the execution fees are transferred to.                                                                                       |
| `_jobRegistryIndex` | `uint8`              | Identifier for the job registry contract to execute jobs within.                                                                           |

#### Return data

| Name                   | Type      | Description                                                        |
| ---------------------- | --------- | ------------------------------------------------------------------ |
| `standardTax`          | `uint256` | Accumulated tax paid for executing jobs not in zero fee window.    |
| `zeroFeeTax`           | `uint256` | Accumulated tax paid for jobs in zero fee window.                  |
| `successfulExecutions` | `uint96`  | Total number of job executions where the execution did not revert. |

#### Notes

* If the caller is an initialized executor, the tax is withdrawn from the internal staking balance, otherwise it is transferred via a ERC-20 transferFrom call. In the latter case, the caller should have given the Coordinator token permissions to cover the execution tax (both standard and zero fee tax).
* If the caller is an active executor, the executor will be deactivated if their balance after paying execution taxes goes below the `stakingBalanceThresholdPerModule` times the number of registered modules.
* The total tax taken consists of `executionTax * a + zeroFeeExecutionTax * b` where `a` is the number of successful executions of jobs not in zero fee window and `b` is the number of successful jobs in zero fee window.

Emits [BatchExecution](#batchexecution) and potentially [CheckIn](#checkin) and [ExecutorDeactivated](#executordeactivated).

### stake

```solidity
function stake(uint256 _modulesBitset) external returns (uint256 stakingAmount)
```

Staking tokens to register for modules and thereby activating the caller as an executor.

#### Arguments

| Name             | Type      | Description                                                                                                                                                     |
| ---------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `_modulesBitset` | `uint256` | A bitset containing 1's a the positions corresponding to the module numbers to register for. For example `000...0101 = 5` means registering for module 0 and 2. |

#### Return data

| Name            | Type      | Description                                          |
| --------------- | --------- | ---------------------------------------------------- |
| `stakingAmount` | `uint256` | Total number of tokens  transferred from the caller. |

#### Notes

* Cannot be called during alternating open competition and designated rounds and during slashing window phase of an epoch.
* Requires registration of at least two modules. If caller does not register for at least one execution module and one fee module then they will not be able to execute any jobs during designated rounds.
* Cannot be called if the caller is already an initialized executor.
* The exact amount staked (`stakingAmount`) is `stakingAmountPerModule` times the number modules to register. The staking token is `stakingToken`.
* Caller has to approve at least the staking amount of tokens to the Coordinator contract.

Emits [ExecutorActivated](#executoractivated) and [ModulesRegistered](#modulesregistered).

### unstake

```solidity
function unstake() external
```

Unstakes the caller, deregistering modules, deactivating the executor if it is active and transferring internal executor balance to the caller. After unstaking all executor data is deleted and the caller executor be slashed going further.

#### Notes

* Cannot be called during reveal phase, alternating open competition and designated rounds and during slashing window.
* Can only be called when the minimum registration period is over. That is, at least `minimumRegistrationPeriod` seconds has to have passed since the last registration of a module via [stake](#stake) or registerModules.

Emits [ModulesDeregistered](#modulesderegistered) and potentially [ExecutorDeactivated](#executordeactivated).

### topup

```solidity
function topup(uint256 _amount) external
```

Tops up the internal balance of the caller with the `_amount` if they are an initialized executor and activates the executor if they were previously inactive.

#### Arguments

| Name      | Type      | Description                                 |
| --------- | --------- | ------------------------------------------- |
| `_amount` | `uint256` | The amount of tokens to top up the balance. |

#### Notes

* Cannot be called during alternating open competition and designated rounds and during slashing window phase of an epoch.
* Can only be called if the caller is an initialized executor.
* Topup amount has to be enough such that the final is balance is at least `stakingAmountPerModule` times the number of registered modules.

Potentially emits [ExecutorActivated](#executoractivated).

### slashInactiveExecutor

```solidity
function slashInactiveExecutor(address _executor, uint8 _round, address _recipient) external
```

Slashes an executor that did not check in for a designated round during the current epoch, sending half of the slashing rewards to the executor.

#### Arguments

| Name         | Type      | Description                                              |
| ------------ | --------- | -------------------------------------------------------- |
| `_executor`  | `address` | The address of the executor to slash.                    |
| `_round`     | `uint8`   | The round number to slash the executor for.              |
| `_recipient` | `address` | The recipient to transfer the slashing reward tokens to. |

#### Notes

* Can only be called during the slashing window of an epoch.
* Can only slash an executor who was designated for `_round` during the current epoch but did not check in during this round.
* The exact slashing amount is `inactiveSlashingAmountPerModule` times the number of registered modules by the executor. Half of this amount is transferred to the `_recipient` and half goes to the protocol.
* If `_recipient` is an initialized executor, the executor's internal balance is increased, otherwise an ERC-20 transfer will happen.
* The slashed executor will be deactivated if their balance after slashing goes below the `stakingBalanceThresholdPerModule` times the number of registered modules.

Emits [InactiveExecutorSlashed](#inactiveexecutorslashed) and potentially [ExecutorDeactivated](#executordeactivated).

### slashCommitter

```solidity
function slashCommitter(address _executor, address _recipient) external
```

Slashes an executor that did committed without revealing during the current epoch, sending half of the slashing rewards to the executor.

#### Arguments

| Name         | Type      | Description                                              |
| ------------ | --------- | -------------------------------------------------------- |
| `_executor`  | `address` | The address of the executor to slash.                    |
| `_recipient` | `address` | The recipient to transfer the slashing reward tokens to. |

#### Notes

* Can only be called during the slashing window of an epoch.
* Can only slash an executor who committed via the commit function without calling reveal during the current epoch.
* The exact slashing amount is `commitSlashingAmountPerModule` times the number of registered modules by the executor. Half of this amount is transferred to the `_recipient` and half goes to the protocol.
* If `_recipient` is an initialized executor, the executor's internal balance is increased, otherwise an ERC-20 transfer will happen.
* The slashed executor will be deactivated if their balance after slashing goes below the `stakingBalanceThresholdPerModule` times the number of registered modules.

Emits [CommitterSlashed](#committerslashed) and potentially [ExecutorDeactivated](#executordeactivated).

### initiateEpoch

```solidity
function initiateEpoch() external
```

Initiates a new epoch, distributing pool rewards to previous epoch's designated executors. It also sets the seed of the new epoch.

#### Notes

* Can only be called after the previous epoch has finished.
* Takes protocol cut of `epochPoolBalance` before it is distributed.
* Distributes the remaining of `epochPoolBalance` to designated executors of the previous epoch (the current epoch before initiating a new one) as follows:\
  The executor is rewarded by `maxRewardPerExecution` times the number of execution during their designated rounds (not counting zero fee executions). However this amount is capped by the executors proportional share of the remaining pool balance, i.e. if the executor is designated 2 out of 5 rounds, then their reward is capped by 2/5ths of the remaining pool balance.

Emits [EpochInitiated](#epochinitiated).

### commit

```solidity
function commit(bytes32 _commitment) external
```

Commits to an ERC-191 signature of the current epoch number and chain ID to participate in seed shuffling. It stores the commitment on-chain.

#### Arguments

| Name          | Type      | Description                                                                                                     |
| ------------- | --------- | --------------------------------------------------------------------------------------------------------------- |
| `_commitment` | `bytes32` | A keccak256 hash of an ERC-191 signature of the current epoch number and chain ID packed, signed by the caller. |

#### Notes

* Can only be called during the commitment phase of an epoch.
* Can only be called by an active executor.
* If the executor commits and does not [reveal](#reveal-1) during the same epoch, they are subject to slashing via [slashInactiveExecutor](#slashinactiveexecutor).

Specifically, `_commitment` is:

```
keccak256(encodePacked("\x19EthereumSignedMessage:\32", keccak256(encodePacked(epochNumber, chainID))))
```

Where `epochNumber` is the current epoch number and `chainID` is the ID of the chain of the Coordinator contract. The `_commitment` is this hash signed by the executors private key.

Emits [Commitment](#commitment).

### reveal

```solidity
function reveal(bytes calldata _signature) external
```

Reveals the ERC-191 signature that was committed to via [commit](#commit), and uses the signature to shuffle the epoch seed.&#x20;

#### Arguments

| Name         | Type    | Definition                                                                                                   |
| ------------ | ------- | ------------------------------------------------------------------------------------------------------------ |
| `_signature` | `bytes` | The ERC-191 signature of the epoch number and chain ID committed to in the same epoch via [commit](#commit). |

#### Notes

* Can only be called in the reveal phase of the epoch.
* Can only be called by an active executor who has called [commit](#commit) during the same epoch.
* Shuffles the seed of the current epoch by keccak256 hashing the current seed together with the `_signature`.

Emits [Reveal](#reveal).

### registerModules

```solidity
function registerModules(uint256 _modulesBitset) external returns (uint256 stakingAmount) 
```

Registers modules and stakes tokens proportional to the number of modules registered.

#### Arguments

| Name             | Type      | Description                                                                                                                                                     |
| ---------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `_modulesBitset` | `uint256` | A bitset containing 1's a the positions corresponding to the module numbers to register for. For example `000...0101 = 5` means registering for module 0 and 2. |

#### Return data

| Name            | Type      | Description                                          |
| --------------- | --------- | ---------------------------------------------------- |
| `stakingAmount` | `uint256` | Total number of tokens  transferred from the caller. |

#### Notes

* Can only be called by an initialized executor.
* The exact amount staked (`stakingAmount`) is `stakingAmountPerModule` times the number modules to register. The staking token is `stakingToken`.
* Caller has to approve at least the staking amount of tokens to the Coordinator contract.
* An inactive executor calling this function cannot become active because the minimum number of stake required to be active also increases proportionally with registered modules.

Emits [ModulesRegistered](#modulesregistered).

### deregisterModules

```solidity
function deregisterModules(uint256 _modulesBitset) external
```

Deregisters modules given.

#### Arguments

| Name             | Type      | Description                                                                                                                                                 |
| ---------------- | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `_modulesBitset` | `uint256` | A bitset containing 1's a the positions corresponding to the module numbers to deregister. For example `000...0101 = 5` means deregistering module 0 and 2. |

#### Notes

* Can only be called by an initialized executor that has already registered for the modules in `_modulesBitset`.
* The executor has to have registered at least two modules after the deregistration.
* Can only be called after `minimumRegistrationPeriod` seconds after the last module registration either via [stake](#stake) or [registerModules](#registermodules).
* This call does not transfer funds. However, the minimum staking threshold has lowered.

Emits [ModulesDeregistered](#modulesderegistered).

### withdrawStakingBalance

```solidity
function withdrawStakingBalance(uint256 _amount) external
```

Withdraws executor internal staking balance to the caller, doing an ERC-20 transfer of the staking token.

#### Arguments

| Name      | Type      | Description                                                 |
| --------- | --------- | ----------------------------------------------------------- |
| `_amount` | `uint256` | The amount to withdraw from the executor's staking balance. |

#### Notes

* Can only be called by an initialized executor.
* The internal executor balance after withdrawing has to be at least `stakingAmountPerModule` times the number of registered modules. If the executor wants to withdraw their whole balance,  [unstake](#unstake) should be used instead.

### withdrawProtocolBalance

```solidity
function withdrawProtocolBalance() external returns (uint256 amount)
```

Withdraws protocol's internal balance to the contract owner. This balance stems from execution tax an epoch pool balance cuts.&#x20;

#### Return data

| Name     | Type      | Description                              |
| -------- | --------- | ---------------------------------------- |
| `amount` | `uint256` | The amount of tokens that was withdrawn. |

#### Notes

* Can only be called by the `owner` address of the Coordinator contract.
* This will not affect executors' internal balance.
