PayrollManager
Last updated
Last updated
Inherits: NoncesUpgradeable, ReentrancyGuardUpgradeable, Patchable, StateAware, AdminControlled, MezzEIP712, MezzERC721Upgradeable, IPayrollManager
Author: Daniel Yamagata
A soulbound ERC721 contract that manages the payroll of a company. The contract is controlled by the company's board of directors and a set of admins set by the board. Some actions require a 24-hour time delay before they are executable. This was done such that a compromised admin cannot drain a company's funds instantaneously. Rather, the action can be canceled by the board or another admin before its execution. These actions include:
Changing an employee's cash salary
Extending an employee's equity payments
Setting a new equity payment schedule for an employee
Paying cash directly to an employee
Paying equity directly to an employee
The tokens are never burned, even after an employee resigns or is terminated. This was done such to preserve the on-chain data that an employee once worked at a company. Whether or not an employee resigned or was terminated is tracked accordingly.
Reverts if the token ID does not correspond to a current employee
Initializes the Payroll Manager. The 'initTreasury' is set as the controller of the contract. Can only be called once.
The payroll manager is initialized upon a company's deployment within the Mezz Deployer
Parameters
initTreasury
address
The treasury that will control the payroll manager
Hires an employee with an annual salary and equity. An employee's start date must be at least 24 hours after calling this function. Only callable by 'admins' or the board of directors, who are the signers of the treasury
An employee signature must be included such that they accept their offer. This prevents companies from defrauding others by claiming that they have hired a certain employee. It also confirms that the employee has accepted the terms of the agreement, so that they do not have to be altered at a later time
Parameters
data
DataTypes.HireData
The data needed to hire an employee, defined as DataTypes.HireData
employeeSignature
bytes
The signature of the employee. The employee should sign the hash of 'getHireTransactionHash' with the terms of their agreement
Returns
<none>
uint256
The ID of the payroll token
Terminates the employees associated with 'tokenId'. Collects all collectible cash for 'tokenId'. Only callable by an admin
Increases the unpaid time off for the employees associated with 'tokenId' by 'timeOff'. Only callable by an admin. Collects any collectible cash associated with 'tokenIds'
Collects the cash owed to an employee. If the treasury does not have a sufficcient cash balance, the cash owed to an employee is updated, such that it will be collectible at a later time. The cash is transferred to the employee's specified recipient, which may be different from the employee, themself.
This function is not access controlled. Any account can collect cash on behalf of an employee.
Parameters
tokenId
uint256
The ID of the payroll token
Returns
<none>
uint256
The amount of cash paid, which may be different than the amount that was collectible. This is due to potential transfer fees that may be incurred by the cash asset.
Collects the equity owed to an employee. The common shares are transferred to the employee's specified recipient. Equity compensation will always be in the form of the company's common shares. This function is callable by any account
This function is not access controlled. Any account can collect cash on behalf of an employee. This function is will revert if the employee's vesting schedule has been completed or if they did not have a vesting schedule to begin with.
Parameters
tokenId
uint256
The ID of the payroll token
Returns
<none>
uint256
The amount of equity released
Changes the recipient of the employee's salary to 'newRecipient'. Only callable by the owner of 'tokenId'
Resigns the employee associated with 'tokenId'. Only callable by the token owner. The employee will continue to earn their salary until their 'salaryEndDate'
The 'salaryEndDate' cannot exceed 1 year into the future and cannot be in the past
Parameters
tokenId
uint256
The ID of the payroll token
salaryEndDate
uint256
The date that the employee will stop earning their salary
Resigns the employee associated with 'tokenId'. A signature from the employee is required. The employee will continue to earn their salary until their 'salaryEndDate'
Parameters
tokenId
uint256
The ID of the payroll token
salaryEndDate
uint256
The date that the employee will stop earning their salary
employeeSignature
bytes
The signature of the employee. The employee should sign the hash of 'getResignTransactionHash'
Proposes a series of 'actions' to be executed in the future. Each action has a corresponding 'params' which are the abi-encoded arguments of the actions' corresponding function. Only callable by an admin.
Parameters
actions
bytes4[]
The actions to be executed
params
bytes[]
The abi-encoded arguments of the actions' corresponding function
Proposed actions require a minimum delay of 24 hours before their execution. This is done such that a compromised admin cannot drain the company's funds instantaneously. Rather, the action can be canceled by another admin within the 24-hour window. Once the delay has passed, any account can execute the action. Actions that include a delay are:
Changing an employee's cash salary
Extending an employee's equity payments
Setting a new equity payment schedule for an employee
Paying cash directly to an employee
Paying equity directly to an employee This function will revert if the action has already been proposed.
Parameters
action
bytes4
The action to be executed, represented as the selector of the function
params
bytes
The abi-encoded parameters of the action.
Returns
<none>
bytes32
The ID of the action, which is the hash of the action and its parameters
Cancels a pending action. Only callable by an admin
Parameters
actionId
bytes32
The ID of the action to be canceled
Changes the cash salary of the employee with 'tokenId' to 'newCashSalary'
Parameters
tokenId
uint256
The ID of the payroll token
newCashSalary
uint256
The new annual cash salary of the employee
Extends the equity payments of 'tokenId' by 'equityExtension' and increases the duration by 'durationExtension'
Must be proposed by an admin and executed after a 24 hour delay This function will revert if the vesting schedule associated with 'tokenId' is non-existent, which can occur if the employee never had a vesting schedule to begin with or their vesting schedule has been completed
Parameters
tokenId
uint256
The ID of the payroll token
equityExtension
uint256
The number of shares to be added to the employee's equity payments
durationExtension
uint32
The number of seconds to be added to the employee's vesting schedule
employeeSignature
bytes
The signature of the employee. The employee should sign the hash of 'getEquityExtensionTransactionHash' The employee signature is needed such that an employer cannot arbitrarily increase the of an employee's vesting schedule without the consent of the employee
Sets a new equity payment schedule for 'tokenId'
Must be proposed by an admin and executed after a 24 hour delay This function will revert if 'tokenId' has an existing vesting schedule
Parameters
tokenId
uint256
The ID of the payroll token
data
DataTypes.NewEquityPaymentsData
The new equity payment data as a DataTypes.NewEquityPaymentsData struct
- data.equityAmount: The total number of shares to be paid to the employee
- data.startDate: The start date of the employee, represented as a unix timestamp
- data.vestingDuration: The number of seconds that it will take for the employee to be able to claim all of their shares
- data.vestingCliff: The number of seconds that it will take for the employee to be able to claim their first shares
- data.vestingInitialUnlock: The number of shares that the employee will be able to claim at the end of their cliff
Pays 'cashPaymentAmount' to the recipient of 'tokenId' in the cash asset of the employee, which should be the company's denomination asset. The recipient may be different from the employee, themself
Must be proposed by an admin and executed after a 24 hour delay 'cashPaymentAmount' cannot exceed $10 million
Parameters
tokenId
uint256
The ID of the payroll token
cashPaymentAmount
uint256
The amount of cash to be paid to the employee
encodedDetails
bytes32
Details regarding the cash payment as a bit-field. Must be either encoded to include either or both: DataTypes.PaymentDetails.Bonus or DataTypes.PaymentDetails.ContractorPayment. 'Encoding' is done by shifting left 1 by the value of the Payment Details enum
Returns
<none>
uint256
The amount paid, which may be different than the 'cashPaymentAmount' due to ERC20 transfer fees
Pays 'equityPaymentAmount' to the recipient of 'tokenId' in the form of the company's common shares
Must be proposed by an admin and executed after a 24 hour delay 'equityPaymentAmount' cannot exceed the treasury common shares
Parameters
tokenId
uint256
The ID of the payroll token
equityPaymentAmount
uint256
The amount of equity to be paid to the employee
encodedDetails
bytes32
Details regarding the equity payment as a bit-field. Must be either encoded to include either or both: DataTypes.PaymentDetails.Bonus or DataTypes.PaymentDetails.ContractorPayment. 'Encoding' is done by shifting left 1 by the value of the Payment Details enum
Updates the document related to the employee with 'tokenId' in the Document Registry. Only callable by the board or an admin
Returns
<none>
uint256
The new version of the document
Returns the amount of cash collectible by 'tokenId'
This function will revert if 'tokenId' has not been minted
Returns the amount of equity collectible by 'tokenId'
This function will revert if 'tokenId' has not been minted
Returns true if 'tokenId' is a current employee, false otherwise
This function will revert if 'tokenId' has not been minted. It will return false if the employee's end date has passed. An end date is set during an employee's termination or resignation
Returns the salary of 'tokenId' in the form of a DataTypes.Salary struct
To query the vesting schedule of the employee, call 'getVestingSchedule()' of the company's token timelock with the salary's 'tokenTimelockTokenId'
Returns the action id of an 'action' given its abi-encoded 'params'
Returns true if the pending action associated with 'actionId' is ready to execute, false otherwise
Will return false instead of reverting, even if the pending action does not exist
Returns true if the pending action associated with 'actionId' exists, false otherwise
Returns the action IDs of all outstanding pending actions as a bytes32 array
Returns the snapshot of the pending action associated with 'actionId' The snapshot is the unix timestamp at which the action can be executed
Returns the transaction hash of the encoded hire data
This hash is to be signed by the employee before being hired
Parameters
employee
address
The employee to hire
annualCash
uint256
The annual cash salary of the employee
equityAmount
uint256
The total number of shares to be paid to the employee over 'vestingDuration'
startDate
uint48
The start date of the employee, represented as a unix timestamp
vestingDuration
uint32
The number of seconds that it will take for the employee to be able to claim all of their shares
vestingCliff
uint32
The number of seconds that it will take for the employee to be able to claim their first shares
vestingInitialUnlock
uint256
The number of shares that the employee will be able to claim at the end of their cliff
employeeNonce
uint256
The nonce of the employee, which is used to prevent replay attacks
Encodes hire data as a struct hash following the EIP-712 encoding standards
Reference: https://eips.ethereum.org/EIPS/eip-712
Returns the transaction hash of the encoded resign data
This hash is to be signed by the employee when resigning via signature
Parameters
tokenId
uint256
The ID of the payroll token
endDate
uint256
The date that the employee will stop earning their salary
employeeNonce
uint256
The nonce of the employee, which is used to prevent replay attacks
Encodes resign data as a struct hash following the EIP-712 encoding standards
Reference: https://eips.ethereum.org/EIPS/eip-712
Returns the transaction hash of the encoded equity extension data
This hash is to be signed by the employee when extending their equity payments
Parameters
tokenId
uint256
The ID of the payroll token
equityExtension
uint256
The total number of shares to be paid to the employee over 'vestingDuration'
durationExtension
uint32
The number of seconds to be added to the employee's vesting schedule
employeeNonce
uint256
The nonce of the employee, which is used to prevent replay attacks
Encodes equity extension data as a struct hash following the EIP-712 encoding standards
Reference: https://eips.ethereum.org/EIPS/eip-712
Returns the name of the Payroll Manager
Returns the symbol of the Payroll Manager
Returns the version of the implementation as a uint256
Returns the coreId of the implementation as a bytes32
The core ID is the keccak256 hash of the contract name followed by a version under the following syntax: "mezzanine.coreId.ContractName.vX" For example, the core ID of the 2nd version of the Treasury would be the following: keccak256(abi.encodePacked("mezzanine.coreId.Treasury.v2"))
Returns the addresses of employees for a given set of token IDs
Returns the collectible cash for a given set of token IDs
Overridden ERC721 approve() such that approvals are disabled
Overridden ERC721 transferFrom() such that transfers are disabled
Overridden ERC721 update such that burning is disabled
ERC165 support
Reference: https://eips.ethereum.org/EIPS/eip-721
Upgrades 'this' to a newer version via the Mezz Migrator. Only callable by the Treasury, whose signers are the board of directors
Will revert if the protocol state is 'Paused' or 'Frozen'
Parameters
newVersion
uint256
The new version to upgrade to
data
bytes
The data to be passed to the new implementation, which likely should be a reinitializer function if used
Access control for 'resetToPatchedLatestVersion()'