struct VestingSchedule {
uint256 totalAmount; // Total tokens to be vested
uint256 releasedAmount; // Tokens already released
uint256 startTime; // Vesting start time
uint256 lockDuration; // Lock period in seconds
uint256 vestingDuration; // Vesting duration in seconds
}
mapping(address => VestingSchedule) public vestingSchedules;
event TokensLocked(address indexed beneficiary, uint256 totalAmount, uint256 startTime, uint256 lockDuration, uint256 vestingDuration);
event TokensReleased(address indexed beneficiary, uint256 amount);
constructor(address _token) {
token = IERC20(_token);
}
function lockTokens(
address beneficiary,
uint256 totalAmount,
uint256 lockDuration,
uint256 vestingDuration
) external {
require(beneficiary != address(0), "Invalid beneficiary address");
require(totalAmount > 0, "Total amount must be greater than zero");
require(vestingSchedules[beneficiary].totalAmount == 0, "Tokens already locked for this beneficiary");
token.transferFrom(msg.sender, address(this), totalAmount);
vestingSchedules[beneficiary] = VestingSchedule({
totalAmount: totalAmount,
releasedAmount: 0,
startTime: block.timestamp,
lockDuration: lockDuration,
vestingDuration: vestingDuration
});
emit TokensLocked(beneficiary, totalAmount, block.timestamp, lockDuration, vestingDuration);
}
function calculateVestedAmount(address beneficiary) public view returns (uint256) {
VestingSchedule memory schedule = vestingSchedules[beneficiary];
uint256 currentTime = block.timestamp;
if (currentTime < schedule.startTime + schedule.lockDuration) {
return 0;
}
if (currentTime >= schedule.startTime + schedule.lockDuration + schedule.vestingDuration) {
return schedule.totalAmount;
}
uint256 timeElapsed = currentTime - (schedule.startTime + schedule.lockDuration);
uint256 vested = (schedule.totalAmount * timeElapsed) / schedule.vestingDuration;
return vested;
}
function releaseTokens() external {
VestingSchedule storage schedule = vestingSchedules[msg.sender];
require(schedule.totalAmount > 0, "No tokens locked for this beneficiary");
uint256 vestedAmount = calculateVestedAmount(msg.sender);
uint256 releasableAmount = vestedAmount - schedule.releasedAmount;
require(releasableAmount > 0, "No tokens available for release");
schedule.releasedAmount += releasableAmount;
token.transfer(msg.sender, releasableAmount);
emit TokensReleased(msg.sender, releasableAmount);
lockTokens(
0xTeamMemberAddress,
150000000 * 10**18, // Total tokens for team
12 * 30 days, // 12 months lock period
24 * 30 days // 24 months vesting duration
);
lockTokens(
0xPublicSaleParticipant,
1000000 * 10**18, // Example: 1,000,000 tokens for a participant
0, // No lock period for public sale
6 * 30 days // 6 months vesting duration
);
lockTokens(
0xCommunityWallet,
300000000 * 10**18, // Tokens reserved for community rewards
0, // No lock period
48 * 30 days // 48 months vesting duration
);