Created
March 21, 2023 22:24
-
-
Save elmariachi111/ec5056aee12487cbbbfe89998d5e658a to your computer and use it in GitHub Desktop.
Gpt4 token vesting
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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