Hi @Roodiger welcome to the community
You can take inspiration from the IncreasingPriceCrowdsale.sol
You could override the _getTokenAmount
function of Crowdsale to use the current rate and then have a function getCurrentRate
which has your rate calculation based on how many tokens have been sold.
I have created an example crowdsale contract below. The getCurrentRate
function would need to be updated to include the rate calculation you want to use. Currently it just multiplies the _initialRate
by one.
I recommend that any such contract be fully tested and audited.
For testing, I suggest using the following guide:
pragma solidity ^0.5.0;
import "openzeppelin-solidity/contracts/crowdsale/Crowdsale.sol";
import "openzeppelin-solidity/contracts/token/ERC20/IERC20.sol";
/**
* @title MyCrowdsale
* @dev This is a crowdsale.
*/
contract MyCrowdsale is Crowdsale {
using SafeMath for uint256;
uint256 private _initialRate;
constructor (
uint256 initialRate,
address payable wallet,
IERC20 token
)
public
Crowdsale(initialRate, wallet, token) {
_initialRate = initialRate;
}
/**
* The base rate function is overridden to revert, since this crowdsale doesn't use it, and
* all calls to it are a mistake.
*/
function rate() public view returns (uint256) {
revert("MyCrowdsale: rate() called");
}
/**
* @return the initial rate of the crowdsale.
*/
function initialRate() public view returns (uint256) {
return _initialRate;
}
/**
* @dev Returns the current rate of tokens per wei.
* @return The number of tokens a buyer gets per wei
*/
function getCurrentRate() public view returns (uint256) {
// calculate the current rate
return _initialRate.mul(1);
}
/**
* @dev Overrides parent method taking into account variable rate.
* @param weiAmount The value in wei to be converted into tokens
* @return The number of tokens _weiAmount wei will buy at present time
*/
function _getTokenAmount(uint256 weiAmount) internal view returns (uint256) {
uint256 currentRate = getCurrentRate();
return currentRate.mul(weiAmount);
}
}