As of 25 Oct 2026, TokenOps has 1 audit report on Trustblock, by Quantstamp, dated 20 Sep 2023. That report lists no open critical findings.
Record last updated . It holds audits and findings, contracts and incidents up to Oct 2026. Trustblock does not review code.
Newest first
| Audit | Security firm | Date | Scope | Critical findings | Report |
|---|---|---|---|---|---|
| TokenOps | Security firm: Quantstamp | Date: | Scope: Files named in the report | No open critical findings | Open · certificate.quantstamp.com |
Statuses are the security firm’s own, from each report.
| Severity | Open | Acknowledged | Fixed |
|---|---|---|---|
| Critical | 0 | 0 | 0 |
| High | 0 | 0 | 1 |
| Medium | 0 | 1 | 0 |
| Low | 0 | 1 | 2 |
An admin can revoke a grant through function `revokeGrant()`, resulting in the vesting being stopped and all yet unvested tokens being freed to be used for other grants. Importantly, the unvested, yet unwithdrawn tokens by end-users should still be able to be withdrawn by them, as the user has rightfully vested all tokens until then. However, this becomes impossible, as the user becomes unable to call the `withdraw()` function, as the modifier in the `hasActiveGrant()` function requires the `isActive` field to be `true` for a given user. This is however set to false during the revocation process. These vested, but unwithdrawn funds, therefore, become stuck in the contract, as these funds are contained in the sum of reserved tokens `numTokensReservedForVesting` for granted users, but are non-withdrawable by the user with the revoked grant, as they are not able to perform any withdrawals anymore. Notice that the `isActive` flag can also never be toggled again to true, making the vested, unwithdrawn funds permanently stuck.
Open the reportAn implementation of `AccessProtected` contract is used in `TokenVesting`, which essentially maintains the set of admins. However, while admins can add other admins, they can also remove every other admin, including themselves. If that would ever happen to be the case, no additional grants could ever be granted nor revoked. Furthermore, all unallocated tokens (i.e. tokens not contract balance - `numTokensReservedForVesting`) would be frozen.
Open the reportSmart contracts will often have operations that can only be executed by a limited amount of addresses with special privileges. The access control mechanism of the current contract is mainly enforced based on allowing specific actions to addresses stored as state variables of the associated contracts. The contract `AccessProtected.sol` gives the following privileges: an address with the role `admin` can grant that role to or revoke that role from any address via the function `setAdmin()`. The contract `TokenVesting.sol` gives the following privileges: 1. an address with the role `admin` can allocate tokens owned by the contract to a given recipient through a vesting agreement via the functions `createGrant()` (one by one) and `createGrantBatch()` (batch). 2. an address with the role `admin` can withdraw unallocated tokens owned by the contract via the function `withdrawAdmin()`. 3. an address with the role `admin` can revoke an active grant for a given address via the function `revokeGrant()`. 4. an address with the role `admin` can withdraw any ERC20 token owner by the contract and different than the vested token via the function `withdrawOtherToken()`.
Open the reportThe reports name a repository or files. Open a report to see its scope.
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.
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.
<head><script src="https://widget.trustblock.run/project-widget.min.js" defer></script></head><body><divdata-tb-project-widgetdata-tb-project-slug="tokenops"></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