HUMAN Protocol security record

Ethereum, Polygon (POS)humanprotocol.orgGitHub

As of 3 Nov 2026, HUMAN Protocol has 1 audit report on Trustblock, by CertiK, dated 21 Oct 2023. That report lists no open critical findings.

Critical findings
No open critical findings
In 1 report.
Open the latest report
Your label, live
Get the label for your site

Record last updated . It holds audits and findings, contracts and incidents up to Nov 2026. Trustblock does not review code.

Audits1

Newest first

AuditSecurity firmDateScopeCritical findingsReport
Human ProtocolSecurity firm: CertiKDate: Scope: Files named in the reportNo open critical findingsOpen · skynet.certik.com

Findings20

Statuses are the security firm’s own, from each report.

SeverityOpenAcknowledgedFixed
Critical000
High031
Medium001
Low1014
HighPotential Damage Due to Unprotected InitializerHuman Protocol · CertiK · 21 Oct 2023Fixed

The logic of `EscrowFactory` does not protect its initializer. An attacker can call the initializer and assume ownership of the logic contract, whereby she can perform privileged operations that either indirectly break the proxy by destroying the logic contract or trick unsuspecting users into believing that she is the owner of the upgradeable contract.

Open the report
MediumCheck Effect Interaction Pattern ViolatedHuman Protocol · CertiK · 21 Oct 2023Fixed

A reentrancy attack can occur when the contract creates a function that makes an external call to another untrusted contract before resolving any effects. If the attacker can control the untrusted contract, they can make a recursive call back to the original function, repeating interactions that would have otherwise not run after the external call resolved the effects.

Open the report
Low`bulkPayOut()` Can Still Be Called When Status IsHuman Protocol · CertiK · 21 Oct 2023Fixed

Technically it is still possible to call `bulkPayOut()` even if the current status is `Complete` or `Cancelled` because the function does not prevent the execution with these statuses. \ This could lead to potential errors from a user.

Open the report
LowFunction 'transferFrom' of Contract HMToken DoesHuman Protocol · CertiK · 21 Oct 2023Fixed

It is expected that calls of the form `transferFrom(from, dest, amount)` fail if the address value provided in the `from` in-parameter is the zero address.

Open the report
LowImproper Usage of `public` and `external` TypeHuman Protocol · CertiK · 21 Oct 2023Fixed

`public` functions that are never called by the contract could be declared as `external`. `external` functions are more efficient than `public` functions.

Open the report
LowInconsistency Between Comment and CodeHuman Protocol · CertiK · 21 Oct 2023Fixed

In the contract `Escrow.sol` the function `bulkPayOut()` perform a check on two input parameters as follow: ```solidity=159 bool writeOnchain = bytes(_hash).length != 0 || bytes(_url).length != 0; if (writeOnchain) { // Be sure they are both zero if one of them is finalResultsUrl = _url; finalResultsHash = _hash; } ``` However, the comment seems inconsistent with this check, indeed the conditional statement will not execute the block of code only if at most one of the two parameters is equal to zero. Then, if only one parameter is equal to zero, nothing in the logic of the function ensures that: ```solidity // Be sure they are both zero if one of them is ```

Open the report
LowLogic Issue in Function `increaseApproval()`Human Protocol · CertiK · 21 Oct 2023Fixed

In the function `increaseApproval()`, the following conditionnal statement: ```solidity=81 if (_oldValue.add(_delta) < _oldValue || _oldValue.add(_delta) >= MAX_UINT256) { // Truncate upon overflow. allowed[msg.sender][_spender] = MAX_UINT256.sub(1); ``` is equivalent to: ```solidity if (_oldValue.add(_delta) = MAX_UINT256) { allowed[msg.sender][_spender] = MAX_UINT256.sub(1); ``` because nothing is greater than `MAX_UINT256` and `add()` from `SafeMath` will revert if `_oldValue + _delta < _oldValue`.

Open the report
LowMisleading Function NameHuman Protocol · CertiK · 21 Oct 2023Fixed

The function `approveBulk()` does not allow a user to approve certain addresses to transfer certain values, contrary to what the name suggests, but it allows the user to increase the values already approved for this address. In particular, a user could believe he/she can reduce the allowances of a list of addresses, however, it is only possible to increase the allowances.

Open the report
LowMissing Emit EventsHuman Protocol · CertiK · 21 Oct 2023Fixed

There should always be events emitted in the sensitive functions that are controlled by centralization roles.

Open the report
LowMissing Zero Address ValidationHuman Protocol · CertiK · 21 Oct 2023Fixed

Addresses should be checked before assignment or external calls to make sure they are not zero addresses.

Open the report
Show 6 more
LowPotential Logical Issue in `bulkPayOut()`Human Protocol · CertiK · 21 Oct 2023Fixed

In the function `bulkPayOut()`, in the following piece of code: ```solidity=157 for (uint256 i; i < _amounts.length; i++) { aggregatedBulkAmount += _amounts[i]; } require(aggregatedBulkAmount < BULK_MAX_VALUE, "Bulk value too high"); ``` it is possible to bypass the check if the sum of the `_amounts[i]` is greater than `max(uint256)`.

Open the report
LowRedundant CheckHuman Protocol · CertiK · 21 Oct 2023Fixed

In the function `setup()`, in the following piece of code: ```solidity=85 uint256 totalStake = _reputationOracleStake.add(_recordingOracleStake); require( totalStake >= 0 && totalStake <= 100, "Stake out of bounds" ); ``` `totalStake` is an `uint256`, hence it cannot be less than zero. ----- In the function `complete()`, in the following check: ```solidity=123 require( msg.sender == reputationOracle || areTrustedHandlers[msg.sender], "Address calling is not trusted" ); ``` the `reputationOracle` is always a trusted handler, hence requiring `areTrustedHandlers[msg.sender]` is enough.

Open the report
LowToo Many DigitsHuman Protocol · CertiK · 21 Oct 2023Fixed

Literals with many digits are difficult to read and review.

Open the report
LowUnclear Logic of `bulkPayOut()`Human Protocol · CertiK · 21 Oct 2023Fixed

In the `Escrow.sol` contract, the `bulkPayOut()` function from the new commit: [afedc405f537b2449bb9ec18b9815664431f2bcc](https://github.com/humanprotocol/human-protocol/tree/afedc405f537b2449bb9ec18b9815664431f2bcc/packages/core/contracts) behaves differently than before. Previously the function was not expected to fail if one of the transfers did not work, this was made using the `transferQuiet()` function, now all transfers are made using `_safeTransfer()` meaning all transfers much succeed. \ This change seems to have also interfered with the `bulkPaid` logic since now: ```solidity=257 bulkPaid = true; balance = getBalance(); if (bulkPaid) { ``` the *if* block will always be executed. Also, a new state variable has been introduced, `remainingSolutions`, which is impacting the potential state transition occurring at the end of `bulkPayOut()`.

Open the report
LowUnnecessary Use of `SafeMath` FunctionsHuman Protocol · CertiK · 21 Oct 2023Fixed

In the linked code, arithmetical operations are performed after a conditional statement has occurred preventing any risk of integer underflow/overflow.

Open the report
LowUnoptimized CodeHuman Protocol · CertiK · 21 Oct 2023Fixed

In the function `transferQuiet()`, the following block: ```solidity=150 if (_to == address(0)) return false; // Preclude burning tokens to uninitialized address. if (_to == address(this)) return false; // Preclude sending tokens to the contract. if (balances[msg.sender] < _value) return false; ``` is equivalent to : ```solidity if ((_to == address(0)) || (_to == address(this)) || (balances[msg.sender] < _value)) return false; ```

Open the report

Contracts

No deployed address is recorded for these audits.

The reports name a repository or files. Open a report to see its scope.

The repositories and files the reports name

Show this on your site

Is this your project? Show this record on your own website. The label states what the record holds, links to this page and updates by itself. It is free and needs no sign-in.

Content

Facts

Automatic: the three strongest facts of this project’s own record (its last audit and two more), highlighted. They update with the record. Picking a fact turns Automatic off.

Fixed as
Language

Style

Layout
Theme
Accent
Corners

Format

Size
Date
Embed as
HTML
<head>
<script src="https://widget.trustblock.run/project-widget.min.js" defer></script>
</head>
<body>
<div
data-tb-project-widget
data-tb-project-slug="human-protocol"
></div>
</body>

Paste the code where the label should appear. It uses no API credit and updates by itself.

Something wrong on this page? A missing report, a wrong date, a finding that was fixed since. Tell us and we check it against its source.

Tell us