Coordinator

This page covers technical information on the Coordinator contract.

Events

BatchExecution

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

Emitted upon batch execution of jobs via executeBatch.

EpochInitiated

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

Emitted upon initiation of an epoch via initiateEpoch.

CheckIn

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

Emitted upon an executor checking in via executeBatch.

Commitment

event Commitment(address indexed executor, uint192 indexed epoch)

Emitted upon an executor committing to an epoch via commit.

Reveal

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

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

InactiveExecutorSlashed

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

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

ExecutorActivated

event ExecutorActivated(address indexed executor)

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

ExecutorDeactivated

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

event ModulesRegistered(address indexed executor, uint256 indexed modulesBitset)

Emitted upon executor registration of modules via stake and registerModules.

ModulesDeregistered

event ModulesDeregistered(address indexed executor, uint256 indexed modulesBitset)

Emitted upon executor deregistration of modules via unstake and deregisterModules.

State-changing functions

executeBatch

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 and potentially CheckIn and ExecutorDeactivated.

stake

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 and ModulesRegistered.

unstake

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 or registerModules.

Emits ModulesDeregistered and potentially ExecutorDeactivated.

topup

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.

slashInactiveExecutor

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 and potentially ExecutorDeactivated.

slashCommitter

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 and potentially ExecutorDeactivated.

initiateEpoch

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.

commit

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 during the same epoch, they are subject to slashing via 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.

reveal

function reveal(bytes calldata _signature) external

Reveals the ERC-191 signature that was committed to via commit, and uses the signature to shuffle the epoch seed.

Arguments

Name
Type
Definition

_signature

bytes

Notes

  • Can only be called in the reveal phase of the epoch.

  • Can only be called by an active executor who has called commit during the same epoch.

  • Shuffles the seed of the current epoch by keccak256 hashing the current seed together with the _signature.

Emits Reveal.

registerModules

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.

deregisterModules

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 or registerModules.

  • This call does not transfer funds. However, the minimum staking threshold has lowered.

Emits ModulesDeregistered.

withdrawStakingBalance

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 should be used instead.

withdrawProtocolBalance

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.

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.

Last updated