Lendefi DAO
  • Home
  • ❱ audit
    • Ecosystem
    • GovernanceToken
    • InvestmentManager
    • InvestorVesting
    • LendefiGovernor
    • PartnerVesting
    • TeamManager
    • TeamVesting
    • Treasury
    • Deploy
  • ❱ ecosystem
    • Ecosystem
    • GovernanceToken
    • InvestmentManager
    • InvestorVesting
    • LendefiGovernor
    • PartnerVesting
    • TeamManager
    • TeamVesting
    • Treasury
  • ❱ interfaces
    • IECOSYSTEM
    • IINVMANAGER
    • ILENDEFI
    • IPARTNERVESTING
    • ITEAMMANAGER
    • ITEAMVESTING
    • ITREASURY
    • IVESTING
  • ❱ deploys
  • ❱ tokenomics
Powered by GitBook
On this page
  • Scope
  • Executive Summary
  • Key Findings
  • Risk Assessment
  • Access Control ✅
  • Vesting Implementation ✅
  • Reentrancy Protection ✅
  • Detailed Findings
  • Low Severity
  • Informational
  • Conclusion
  1. ❱ audit

InvestorVesting

Scope

  • Contract: InvestorVesting.sol

  • Version: v1 (Solidity 0.8.23)

  • Framework: OpenZeppelin Contracts v5

Executive Summary

The InvestorVesting contract has been audited for security vulnerabilities and coding best practices. This contract implements a linear vesting schedule for Lendefi investors, allowing beneficiaries to claim tokens as they vest over time. The contract follows a conservative design approach and leverages tested OpenZeppelin libraries. No critical vulnerabilities were identified.

Key Findings

Severity
Number of Findings

Critical

0

High

0

Medium

0

Low

2

Informational

3

Risk Assessment

Access Control ✅

The contract employs a straightforward and secure access control model:

  • Uses Ownable2Step with the investor as the owner

    • Two-step ownership transfer provides protection against accidental transfer mistakes

    • Only the owner can receive vested tokens via the release() function

  • No cancellation mechanism included, giving investors certainty about their vesting schedule

Vesting Implementation ✅

The contract implements a secure linear vesting mechanism:

function _vestingSchedule(uint256 totalAllocation, uint64 timestamp) internal view virtual returns (uint256) {
    if (timestamp < start()) {
        return 0;
    } else if (timestamp >= end()) {
        return totalAllocation;
    }
    return (totalAllocation * (timestamp - start())) / duration();
}

Key security features:

  • Immutable parameters for start time, duration, and token address

  • Proper accounting of released tokens via _erc20Released mapping

  • Secure token transfers using SafeERC20

  • Appropriate boundary checks for timestamps

Reentrancy Protection ✅

The contract uses OpenZeppelin's ReentrancyGuard for state-changing external functions:

  • release() uses the nonReentrant modifier

  • The contract follows the checks-effects-interactions pattern, updating state variables before making external calls

Detailed Findings

Low Severity

  1. No Start Time Validation

    The constructor does not validate that the start timestamp is reasonable:

    _start = startTimestamp;

    While this allows flexibility for different vesting scenarios, it could lead to deployment errors if a very distant future or very far past timestamp is used accidentally.

    Recommendation: Consider adding validation to ensure reasonable start times, especially if this contract is deployed programmatically.

  2. No Duration Minimum

    The contract accepts any non-zero duration, potentially allowing extremely short vesting periods:

    _duration = durationSeconds;

    Recommendation: Consider adding a reasonable minimum duration (e.g., 1 day) to prevent instant vesting schedules which defeat the purpose of vesting.

Informational

  1. Release Function Can Be Called By Anyone

    The release() function is public and can be called by anyone, not just the owner:

    function release() public virtual nonReentrant {
        // ...
    }

    This is a standard pattern and not a vulnerability since tokens are always sent to the owner, but it should be noted that external parties can trigger token releases.

  2. No Recovery Mechanism for Other Tokens

    If tokens other than the vesting token are accidentally sent to the contract, there is no mechanism to recover them. This will result in those tokens being permanently locked in the contract.

  3. Single Token Support

    The contract is designed to vest only one token type (specified at deployment). If multiple token types need to be vested to the same investor, multiple contracts would need to be deployed.

Conclusion

The InvestorVesting contract implements a secure linear vesting mechanism with an appropriate ownership model for investor-focused token vesting. The design is straightforward and leverages proven OpenZeppelin components.

The contract successfully implements several security best practices:

  1. ✅ Two-step ownership transfers

  2. ✅ Immutable critical parameters

  3. ✅ Reentrancy protection

  4. ✅ Safe token transfers using SafeERC20

  5. ✅ Proper event emissions

  6. ✅ Clean mathematical implementation of linear vesting

The identified issues are minor and do not pose significant security risks to the contract's operation. Unlike the PartnerVesting contract, this one does not include a cancellation mechanism, which is appropriate for its intended purpose of providing investors with reliable vesting schedules.

The contract is suitable for its intended purpose of managing token vesting for Lendefi DAO investors and provides an appropriate balance of security and functionality.

PreviousInvestmentManagerNextLendefiGovernor

Last updated 2 months ago