// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; contract SellTixVesting is Ownable { using SafeMath for uint256; struct VestingSchedule { uint256 totalAmount; uint256 startTime; uint256 cliffDuration; uint256 vestingDuration; uint256 amountClaimed; } mapping(address => VestingSchedule) public teamVestingSchedules; mapping(address => VestingSchedule) public platformVestingSchedules; mapping(address => VestingSchedule) public marketingVestingSchedules; function setTeamVesting(address _beneficiary, uint256 _amount) external onlyOwner { teamVestingSchedules[_beneficiary] = VestingSchedule({ totalAmount: _amount, startTime: block.timestamp, cliffDuration: 365 days, vestingDuration: 730 days, amountClaimed: 0 }); } function setPlatformVesting(address _beneficiary, uint256 _amount) external onlyOwner { platformVestingSchedules[_beneficiary] = VestingSchedule({ totalAmount: _amount, startTime: block.timestamp, cliffDuration: 0, vestingDuration: 730 days, amountClaimed: _amount.mul(20).div(100) // 20% unlocked at TGE }); } function setMarketingVesting(address _beneficiary, uint256 _amount) external onlyOwner { marketingVestingSchedules[_beneficiary] = VestingSchedule({ totalAmount: _amount, startTime: block.timestamp, cliffDuration: 0, vestingDuration: 365 days, amountClaimed: _amount.mul(30).div(100) // 30% unlocked at TGE }); } function calculateVestedAmount(VestingSchedule memory schedule) internal view returns (uint256) { if (block.timestamp < schedule.startTime.add(schedule.cliffDuration)) { return 0; } if (block.timestamp >= schedule.startTime.add(schedule.vestingDuration)) { return schedule.totalAmount; } return schedule.totalAmount.mul( block.timestamp.sub(schedule.startTime) ).div(schedule.vestingDuration); } function claimTeamTokens() external { VestingSchedule storage schedule = teamVestingSchedules[msg.sender]; uint256 vestedAmount = calculateVestedAmount(schedule); uint256 claimableAmount = vestedAmount.sub(schedule.amountClaimed); require(claimableAmount > 0, "No tokens to claim"); schedule.amountClaimed = schedule.amountClaimed.add(claimableAmount); token.transfer(msg.sender, claimableAmount); } }