DCIPs/assets/eip-5725/contracts/reference/VestingNFT.sol

100 lines
2.9 KiB
Solidity

// SPDX-License-Identifier: CC0-1.0
pragma solidity ^0.8.17;
import "../ERC5725.sol";
contract VestingNFT is ERC5725 {
using SafeERC20 for IERC20;
struct VestDetails {
IERC20 payoutToken; /// @dev payout token
uint256 payout; /// @dev payout token remaining to be paid
uint128 startTime; /// @dev when vesting starts
uint128 endTime; /// @dev when vesting end
}
mapping(uint256 => VestDetails) public vestDetails; /// @dev maps the vesting data with tokenIds
/// @dev tracker of current NFT id
uint256 private _tokenIdTracker;
/**
* @dev Initializes the contract by setting a `name` and a `symbol` to the token.
*/
constructor(string memory name, string memory symbol) ERC721(name, symbol) {}
/**
* @notice Creates a new vesting NFT and mints it
* @dev Token amount should be approved to be transferred by this contract before executing create
* @param to The recipient of the NFT
* @param amount The total assets to be locked over time
* @param releaseTimestamp When the full amount of tokens get released
* @param token The ERC20 token to vest over time
*/
function create(
address to,
uint256 amount,
uint128 releaseTimestamp,
IERC20 token
) public virtual {
require(to != address(0), "to cannot be address 0");
require(releaseTimestamp > block.timestamp, "release must be in future");
uint256 newTokenId = _tokenIdTracker;
vestDetails[newTokenId] = VestDetails({
payoutToken: token,
payout: amount,
startTime: uint128(block.timestamp),
endTime: releaseTimestamp
});
_tokenIdTracker++;
_mint(to, newTokenId);
IERC20(payoutToken(newTokenId)).safeTransferFrom(msg.sender, address(this), amount);
}
/**
* @dev See {IERC5725}.
*/
function vestedPayoutAtTime(uint256 tokenId, uint256 timestamp)
public
view
override(ERC5725)
validToken(tokenId)
returns (uint256 payout)
{
if (timestamp >= _endTime(tokenId)) {
return _payout(tokenId);
}
return 0;
}
/**
* @dev See {ERC5725}.
*/
function _payoutToken(uint256 tokenId) internal view override returns (address) {
return address(vestDetails[tokenId].payoutToken);
}
/**
* @dev See {ERC5725}.
*/
function _payout(uint256 tokenId) internal view override returns (uint256) {
return vestDetails[tokenId].payout;
}
/**
* @dev See {ERC5725}.
*/
function _startTime(uint256 tokenId) internal view override returns (uint256) {
return vestDetails[tokenId].startTime;
}
/**
* @dev See {ERC5725}.
*/
function _endTime(uint256 tokenId) internal view override returns (uint256) {
return vestDetails[tokenId].endTime;
}
}