Audit · firm’s term: audit report
QuillAudits reviewed dKloud on 5 Mar 2025: 9 findings, 0 critical; all marked fixed.
Report hosted on quillaudits.com.
Trustblock does not review code.
Statuses are the security firm’s own, from its report.
| Severity | Open | Acknowledged | Fixed |
|---|---|---|---|
| Critical | 0 | 0 | 0 |
| High | 0 | 0 | 2 |
| Medium | 0 | 0 | 3 |
| Low | 0 | 0 | 4 |
The contract calculates a special amountInFinalPeriod value in createBeneficiarySchedule() to ac count for division remainders, but this value is never used when calculating claimable amounts. Instead, the function always uses amountPerPeriod even for the final period. This bug permanently locks remainder tokens in the contract: Any amounts not perfectly divisible by the period count will have remainders These remainder tokens become permanently inaccessible to beneficiaries Across all beneficiaries, this could represent a significant amount of locked tokens
The claim() function is publicly accessible and allows any caller to execute claims on behalf of any beneficiary. This represents a significant access control vulnerability since there is no validation that the caller is either the beneficiary or an authorized representative
<code>deactivatedSchedules</code> mapping is used to track whether a vesting schedule is deactivated, but it is not initialized in the initialize function or anywhere else in the contract. This means that all schedules are considered active by default, as the default value for a bool in a mapping is false. This could lead to unintended behavior if the contract relies on this mapping to deactivate schedules
The contract contains fields and validation for revoked schedules but lacks any function to actually revoke a beneficiary's schedule. This creates a critical functional gap in the vesting management system. The contract lacks a critical administrative function needed for proper management of vesting schedules: No ability to revoke schedules for non-compliant beneficiaries No way to handle exceptional circumstances requiring revocation
The logic to mark a vesting schedule as completed uses a strict equality check that will fail due to rounding errors in the vesting calculations. Due to integer division in multiple places (TGE calculations, period calculations), claimedAmount will almost never be exactly equal to totalAmount, preventing schedules from being marked as completed
The contract implements a highly centralized administrative model where the contract owner has<br>unrestricted control over critical functions without any checks and balances.<br>The owner has unilateral power to pause the contract, preventing beneficiaries from claiming their tokens, and can upgrade the contract implementation.
The contract creates vesting schedules in such a way where a particular amount is exactly divisible among beneficiaries. However, real life scenarios will pose rounding errors over various places. This inherent assumption can be broken causing less amount to be available to beneficiaries.
The contract implements a custom nonReentrantPerCaller modifier instead of using OpenZeppelin's standard nonReentrant modifier. While the intention is to prevent multiple operations from the same beneficiary at the same time, the implementation doesn't provide any additional protection beyond what the standard modifier would offer
whenNotPaused modifier is only implemented in the _beforeTokenTransfer function, but it's missing<br>from other critical functions that should be paused during emergency situations. The main functions<br>impacted include:<br>1. mint - Token minting continues even when the contract is paused<br>2. batchTransfer - Batch transfers can still be executed during pause state
The report names a repository or files. Open the report to see its scope.
Repository and files the report names (2)
350 projects reviewed · 459 reports · latest Apr 2025
See QuillAudits’s auditsSomething 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