LiquiFi security record

Ethereumliqui.fi

As of 3 Nov 2026, LiquiFi has 1 audit report on Trustblock, by Quantstamp, dated 27 Jan 2022. 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
LiquiFiSecurity firm: QuantstampDate: Scope: Files named in the reportNo open critical findingsOpen · certificate.quantstamp.com

Findings21

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

SeverityOpenAcknowledgedFixed
Critical000
High002
Medium011
Low2015
High`LinearModule.createPlan` Missing Input ValidationLiquiFi · Quantstamp · 27 Jan 2022Fixed

The function accepts a parameter called `_totalSupply` but does not utilize it properly. It neither checks whether `_cadenceSeconds * _cadenceAmount` is less than the `_totalSupply`, nor whether there are rounding issues that will lead to lost tokens. In case the company owner made a mistake with the inputs, the tokens might vest a lot faster than intended or require manual intervention of the contract owner to retrieve the locked tokens.

Open the report
HighVesting Cannot Be CancelledLiquiFi · Quantstamp · 27 Jan 2022Fixed

The contract does not have any functionality to allow a company to stop vesting a former employee. There are two kinds of employees, `activeEmployees` and `inactiveEmployees`. The contract keeps track of them but never utilizes this information in regard to enabling/disabling of vesting.

Open the report
MediumUse of Unsafe ERC20 InterfaceLiquiFi · Quantstamp · 27 Jan 2022Fixed

Functions `Escrow.deposit()` and `Escrow.withdraw()` are using the _unsafe_ ERC20 interface functions of OpenZeppelin (`transferFrom()` and `transfer()`). Since [some ERC20 tokens do not return a value for these functions](https://medium.com/coinmonks/missing-return-value-bug-at-least-130-tokens-affected-d67bf08521ca) these calls might revert.

Open the report
Low`createPlan` Allows Overwriting PlansLiquiFi · Quantstamp · 27 Jan 2022Fixed

The `createPlan` function in the modules contracts does not check whether a plan with the provided ID already exists, allowing the owner to overwrite any existing plan.

Open the report
Low`EmployeeRegistry.isOwner()` Mishandling `address(0)`LiquiFi · Quantstamp · 27 Jan 2022Fixed

According to the comments, the function `EmployeeRegistry.isOwner()` should return `true` only if the provided address parameter is the owner of of the provided company id parameter and `false` otherwise. However, as the `exists` return value of `EnumerableMap.tryGet(companyOwners, _companyId)` is not checked, providing `address(0)` to any company id would lead to returning `owner == _employee` equal to `true` and therefore violating the comments assumption.

Open the report
Low`EmployeeRegistry.transferOwner` Might Lead to Unexpected StateLiquiFi · Quantstamp · 27 Jan 2022Fixed

There are two issues: 1. The function `transferOwner` does not check if `_newOwner` is an employee of the `_companyId`. The `_newOwner` could be an inactive employee, or even not an employee of that company. This would violate the assumption that a company owner should be an active employee of that company. 1. The function `transferOwner` does not check if `_newOwner` is not equal to `0x0`. This could lead to a disastrous result: A company has no owner to modify its data.

Open the report
Low`Escrow.deposit()` and `Escrow.withdraw()` Prone to ReentrancyLiquiFi · Quantstamp · 27 Jan 2022Fixed

Although `Escrow.sol` inherits from `ReentrancyGuardUpgradeable`, it does not make use of the `nonReentrant` modifier. Further, functions `deposit()` and `withdraw()` do not comply with the ["Checks-Effects-Interactions" pattern](https://docs.soliditylang.org/en/v0.8.11/security-considerations.html#use-the-checks-effects-interactions-pattern), by performing state variable changes **after** external function calls and not before (`escrowBalance[][]` being changed after calling `transferFrom()`, `balanceOf()` and `transfer()`). As these lower level functions are only callable by `owner` or `vestingControllerAddress` the potential impact is limited.

Open the report
LowFunctions Should Not be PayableLiquiFi · Quantstamp · 27 Jan 2022Fixed

The functions `createVestPlan` and `vest` are declared `payable`, allowing ether to be sent along the function calls. Since there is no function to retrieve the ether, it will lead to locked funds.

Open the report
LowGas For Loop ConcernsLiquiFi · Quantstamp · 27 Jan 2022Fixed

When smart contracts are deployed or their associated functions are invoked, the execution of these operations always consumes a certain quantity of gas, according to the amount of computation required to accomplish them. Modifying an unknown-size array that grows in size over time can result in a Denial-of-Service attack. Simply by having an excessively huge array, users can exceed the gas limit, therefore preventing the transaction from ever succeeding. For the loop on `L242`, the code does not restrict the number of vest plans that an employee in a company can have. This function might run out of gas and cannot be recovered from that state when the employee has too many vest plans. This could happen in case the company owner wants to deny an employee from accessing their vested tokens by adding many low-value vest plans.

Open the report
LowIncorrect Accounting for `EmployeeRegistry.employeeToCompanyIds`LiquiFi · Quantstamp · 27 Jan 2022Fixed

The function `EmployeeRegistry.addEmployee()` does not check the return value of the call `EnumerableSet.add(companyIdToEmployees[_companyId].activeEmployees, _employee);`, which would indicate whether the added employee was already in the set. Therefore, calling the function multiple times would lead to duplicate company id entries in `employeeToCompanyIds` after executing `employeeToCompanyIds[_employee].push(_companyId);`.

Open the report
Show 8 more
LowMismatched Interface SignaturesLiquiFi · Quantstamp · 27 Jan 2022Fixed

Some contracts implement the `IVest` or `IModule` interface without explicitly inheriting from them. This can lead to mismatched function signatures as is the case here. Some of the functions are missing the `view` specifier, none of them specify a return type and none of the modules implement a `getPlan` function.

Open the report
LowMissing Address Input ValidationLiquiFi · Quantstamp · 27 Jan 2022Fixed

It is important to validate inputs, even if they only come from trusted addresses in order to avoid human error. The following functions do not have proper validation of input parameters: - `Escrow.initialize` - `Vesting.initialize` - `{Escrow,CliffModule,LinearModule,StreamModule}.setVestingControllerAddress`

Open the report
LowMissing Initializer CallsLiquiFi · Quantstamp · 27 Jan 2022Fixed

Not all of the initializers from the inherited contracts are called. While this might not lead to issues with the current version, this can change in the future.

Open the report
LowName Clashes with OwnableLiquiFi · Quantstamp · 27 Jan 2022Fixed

The `EmployeeRegistry` contract has several functions related to company ownership that are simply referred to as `owner`. Since the contract also inherits from `Ownable`, this might lead to confusion.

Open the report
LowNo Access Control on `EmployeeRegistry.addEmployee()` and `EmployeeRegistry.archiveEmployee()`LiquiFi · Quantstamp · 27 Jan 2022Fixed

The `EmployeeRegistry` contract does not employ any access control for adding or archiving employees, enabling anyone to add arbitrary addresses as *active employees* to arbitrary company ids or mark them as inactive. As a result, the distinction between active and inactive employees is currently pointless.

Open the report
LowRedundant Storage VariablesLiquiFi · Quantstamp · 27 Jan 2022Fixed

There are several member variables that contain identical values, one typed and one `address`. This is redundant since the address can be accessed by casting it like this: `address(cliffModule)`. List of redundant variables: ```solidity address public employeeRegistryAddress; address public cliffModuleAddress; address public linearModuleAddress; address public realtimeModuleAddress; address public escrowAddress; ```

Open the report
LowSafeMath Library RedundantLiquiFi · Quantstamp · 27 Jan 2022Fixed

Starting from solidity version 0.8, overflows and underflows revert by default (see [docs](https://docs.soliditylang.org/en/v0.8.11/080-breaking-changes.html#silent-changes-of-the-semantics)), rendering the use of SafeMath unnecessary.

Open the report
LowUnnecessary `onlyOwner` ModifierLiquiFi · Quantstamp · 27 Jan 2022Fixed

The `getVestingControllerAddress` view function has the `onlyOwner` modifier. Since the `vestingControllerAddress` variable is public anyway, this serves no purpose.

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="liquifi"
></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