HypeHUB Vesting Contract

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol";

contract HypeToken is ERC20, Ownable, ERC20Burnable, ERC20Permit {
    uint256 public immutable maxSupply = 100_000_000 * 10 ** decimals();

    constructor() ERC20("Hype Token", "HPE") ERC20Permit("Hype Token") {
        _mint(msg.sender, maxSupply);
    }
}

// Vesting Contract for Team & Advisors
contract TeamVesting {
    IERC20 public immutable token;
    address public immutable beneficiary;
    uint256 public immutable startTime;
    uint256 public constant totalAllocation = 2_000_000 * 10 ** 18;
    uint256 public constant vestingDuration = 365 days;
    uint256 public released;

    constructor(address _token, address _beneficiary) {
        token = IERC20(_token);
        beneficiary = _beneficiary;
        startTime = block.timestamp;
    }

    function release() external {
        require(block.timestamp >= startTime, "Vesting hasn't started");
        uint256 elapsed = block.timestamp - startTime;
        if (elapsed > vestingDuration) elapsed = vestingDuration;

        uint256 vested = (totalAllocation * elapsed) / vestingDuration;
        uint256 releasable = vested - released;
        require(releasable > 0, "No tokens to release");

        released += releasable;
        token.transfer(beneficiary, releasable);
    }
}

// Vesting Contract for Ecosystem Reserve (24 months, 1-month cliff)
contract EcosystemVesting {
    IERC20 public immutable token;
    address public immutable beneficiary;
    uint256 public immutable startTime;
    uint256 public constant cliff = 30 days;
    uint256 public constant vestingDuration = 730 days; // 24 months
    uint256 public constant totalAllocation = 8_000_000 * 10 ** 18;
    uint256 public released;

    constructor(address _token, address _beneficiary) {
        token = IERC20(_token);
        beneficiary = _beneficiary;
        startTime = block.timestamp;
    }

    function release() external {
        require(block.timestamp >= startTime + cliff, "Cliff not reached");
        uint256 elapsed = block.timestamp - startTime;
        if (elapsed > vestingDuration) elapsed = vestingDuration;

        uint256 vested = (totalAllocation * elapsed) / vestingDuration;
        uint256 releasable = vested - released;
        require(releasable > 0, "No tokens to release");

        released += releasable;
        token.transfer(beneficiary, releasable);
    }
}

Last updated