Skip to content

Instantly share code, notes, and snippets.

@elmariachi111
Created March 21, 2023 22:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save elmariachi111/ec5056aee12487cbbbfe89998d5e658a to your computer and use it in GitHub Desktop.
Save elmariachi111/ec5056aee12487cbbbfe89998d5e658a to your computer and use it in GitHub Desktop.
Gpt4 token vesting
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
contract MultiBeneficiaryVestingToken {
using SafeMath for uint256;
struct VestingSchedule {
address beneficiary;
uint256 cliffDuration;
uint256 duration;
uint256 released;
bool isSet;
}
IERC20 public token;
address public owner;
uint256 public lockAmount;
uint256 public start;
VestingSchedule[] public vestingSchedules;
constructor(
IERC20 _token,
address _owner,
uint256 _lockAmount,
uint256 _start
) {
require(_owner != address(0), "MultiBeneficiaryVestingToken: owner is the zero address");
require(_start > block.timestamp, "MultiBeneficiaryVestingToken: start time is before current time");
token = _token;
owner = _owner;
lockAmount = _lockAmount;
start = _start;
}
function addVestingSchedule(
address _beneficiary,
uint256 _cliffDuration,
uint256 _duration
) public onlyOwner {
require(_beneficiary != address(0), "MultiBeneficiaryVestingToken: beneficiary is the zero address");
require(!_hasVestingSchedule(_beneficiary), "MultiBeneficiaryVestingToken: vesting schedule already set");
require(_cliffDuration <= _duration, "MultiBeneficiaryVestingToken: cliff is longer than duration");
VestingSchedule memory schedule = VestingSchedule({
beneficiary: _beneficiary,
cliffDuration: _cliffDuration,
duration: _duration,
released: 0,
isSet: true
});
vestingSchedules.push(schedule);
}
function release(address _beneficiary) public {
VestingSchedule storage schedule = _getVestingSchedule(_beneficiary);
uint256 amount = _vestedAmount(schedule).sub(schedule.released);
require(amount > 0, "MultiBeneficiaryVestingToken: no tokens to release");
schedule.released = schedule.released.add(amount);
token.transfer(schedule.beneficiary, amount);
}
function totalVestedAmount() public view returns (uint256) {
uint256 total = 0;
for (uint256 i = 0; i < vestingSchedules.length; i++) {
total = total.add(_vestedAmount(vestingSchedules[i]));
}
return total;
}
function _vestedAmount(VestingSchedule memory schedule) private view returns (uint256) {
uint256 currentBalance = token.balanceOf(address(this));
uint256 totalBalance = currentBalance.add(schedule.released);
if (block.timestamp < start.add(schedule.cliffDuration)) {
return 0;
} else if (block.timestamp >= start.add(schedule.duration)) {
return totalBalance;
} else {
return totalBalance.mul(block.timestamp.sub(start.add(schedule.cliffDuration))).div(schedule.duration);
}
}
function _getVestingSchedule(address _beneficiary) private view returns (VestingSchedule storage) {
require(_hasVestingSchedule(_beneficiary), "MultiBeneficiaryVestingToken: no vesting schedule set");
for (uint256 i =
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment