Skip to content

Instantly share code, notes, and snippets.

@cygaar
Created September 8, 2022 15:46
Show Gist options
  • Save cygaar/ab428fec833d80f7216c3b5ddc0d3bc7 to your computer and use it in GitHub Desktop.
Save cygaar/ab428fec833d80f7216c3b5ddc0d3bc7 to your computer and use it in GitHub Desktop.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppellin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
contract ERC721VestedWithdrawals is Ownable, ReentrancyGuard, ERC721 {
uint256 public constant VEST_CADENCE = 90 days;
uint256 public constant VEST_PERIODS = 4;
uint256 public mintCompletionTime;
uint256 public totalMintFunds;
uint256 public amountWithdrawn;
/// @dev this hook should be called when the last NFT has been minted or
/// a sale is deemed as completed.
function _onMintCompletion() private {
mintCompletionTime = block.timestamp;
totalMintFunds = address(this).balance;
}
function vestedWithdraw() external onlyOwner nonReentrant {
require(mintCompletionTime != 0 && totalMintFunds != 0, "Sale not over");
uint256 withdrawableAmount;
uint256 vestedPeriods = (block.timestamp - mintCompletionTime) / VEST_CADENCE;
if (vestedPeriods >= VEST_PERIODS) {
withdrawableAmount = address(this).balance;
} else {
uint256 vestedAmount = (totalMintFunds * vestedPeriods) / VEST_PERIODS;
withdrawableAmount = vestedAmount - amountWithdrawn;
}
if (withdrawableAmount > 0) {
amountWithdrawn = vestedAmount;
(bool success, ) = msg.sender.call{value: withdrawableAmount}("");
require(success, "Withdrawal failed.");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment