Created
May 22, 2023 10:37
-
-
Save FoobarProtocol/56ce6e8a59af13a00b93797d96a8977c to your computer and use it in GitHub Desktop.
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/ERC20.sol"; | |
contract MyToken is ERC20 { | |
uint256 public immutable precision; | |
uint256 public immutable vestingPeriod; | |
uint256 public vestingPeriodFinish; | |
uint256 public issuanceRate; | |
uint256 public lastIssuanceTime; | |
address public asset; | |
constructor( | |
string memory name, | |
string memory symbol, | |
uint256 _precision, | |
uint256 _vestingPeriod, | |
address _asset | |
) ERC20(name, symbol) { | |
precision = _precision; | |
vestingPeriod = _vestingPeriod; | |
asset = _asset; | |
lastIssuanceTime = block.timestamp; | |
issuanceRate = 0; | |
vestingPeriodFinish = block.timestamp + vestingPeriod; | |
} | |
function deposit(uint256 amount, address receiver) external returns (uint256) { | |
require(amount > 0, "Amount must be greater than zero"); | |
require(receiver != address(0), "Invalid receiver address"); | |
// Transfer the underlying asset to the contract | |
require( | |
IERC20(asset).transferFrom(msg.sender, address(this), amount), | |
"Failed to transfer asset to contract" | |
); | |
// Calculate the new issuance rate based on the amount deposited | |
uint256 timeElapsed = block.timestamp - lastIssuanceTime; | |
issuanceRate += (amount * precision) / (timeElapsed * 1e18); | |
// Mint the tokens to the receiver | |
uint256 shares = (amount * precision) / issuanceRate; | |
_mint(receiver, shares); | |
// Update the last issuance time | |
lastIssuanceTime = block.timestamp; | |
return shares; | |
} | |
function mint(uint256 shares, address receiver) external returns (uint256) { | |
require(shares > 0, "Shares must be greater than zero"); | |
require(receiver != address(0), "Invalid receiver address"); | |
// Calculate the amount of underlying asset to mint | |
uint256 timeElapsed = block.timestamp - lastIssuanceTime; | |
uint256 amount = (shares * issuanceRate) / precision; | |
// Check that enough time has elapsed since last issuance | |
require(block.timestamp >= vestingPeriodFinish || timeElapsed >= vestingPeriod, "Vesting period not finished"); | |
// Burn the tokens from the sender | |
_burn(msg.sender, shares); | |
// Transfer the underlying asset to the receiver | |
require(IERC20(asset).transfer(receiver, amount), "Failed to transfer asset to receiver"); | |
// Update the last issuance time if the vesting period is finished | |
if (block.timestamp >= vestingPeriodFinish) { | |
lastIssuanceTime = block.timestamp; | |
issuanceRate = 0; | |
vestingPeriodFinish = block.timestamp + vestingPeriod; | |
} | |
return amount; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment