Created
February 4, 2022 13:16
-
-
Save bll-bobbygill/c873543c16afd8b2e327731f8872cf7b to your computer and use it in GitHub Desktop.
Versions of MintedCrowdsale.sol and Crowdsale.sol that Work with OpenZeppelin 4.0
This file contains hidden or 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.4; | |
import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; | |
import "@openzeppelin/contracts/utils/Context.sol"; | |
import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; | |
import "@openzeppelin/contracts/utils/math/SafeMath.sol"; | |
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; | |
/** | |
* @title Crowdsale | |
* @dev Crowdsale is a base contract for managing a token crowdsale, | |
* allowing investors to purchase tokens with ether. This contract implements | |
* such functionality in its most fundamental form and can be extended to provide additional | |
* functionality and/or custom behavior. | |
* The external interface represents the basic interface for purchasing tokens, and conforms | |
* the base architecture for crowdsales. It is *not* intended to be modified / overridden. | |
* The internal interface conforms the extensible and modifiable surface of crowdsales. Override | |
* the methods to add functionality. Consider using 'super' where appropriate to concatenate | |
* behavior. | |
*/ | |
abstract contract Crowdsale is Context, ReentrancyGuard { | |
using SafeMath for uint256; | |
using SafeERC20 for IERC20; | |
// The token being sold | |
IERC20 private _token; | |
// Address where funds are collected | |
address payable private _wallet; | |
// How many token units a buyer gets per wei. | |
// The rate is the conversion between wei and the smallest and indivisible token unit. | |
// So, if you are using a rate of 1 with a ERC20Detailed token with 3 decimals called TOK | |
// 1 wei will give you 1 unit, or 0.001 TOK. | |
uint256 private _rate; | |
// Amount of wei raised | |
uint256 private _weiRaised; | |
/** | |
* Event for token purchase logging | |
* @param purchaser who paid for the tokens | |
* @param beneficiary who got the tokens | |
* @param value weis paid for purchase | |
* @param amount amount of tokens purchased | |
*/ | |
event TokensPurchased(address indexed purchaser, address indexed beneficiary, uint256 value, uint256 amount); | |
/** | |
* @param r Number of token units a buyer gets per wei | |
* @dev The rate is the conversion between wei and the smallest and indivisible | |
* token unit. So, if you are using a rate of 1 with a ERC20Detailed token | |
* with 3 decimals called TOK, 1 wei will give you 1 unit, or 0.001 TOK. | |
* @param w Address where collected funds will be forwarded to | |
* @param t Address of the token being sold | |
*/ | |
constructor (uint256 r, address payable w, IERC20 t) { | |
require(r > 0, "Crowdsale: rate is 0"); | |
require(w != address(0), "Crowdsale: wallet is the zero address"); | |
require(address(t) != address(0), "Crowdsale: token is the zero address"); | |
_rate = r; | |
_wallet = w; | |
_token = t; | |
} | |
/** | |
* @dev fallback function ***DO NOT OVERRIDE*** | |
* Note that other contracts will transfer funds with a base gas stipend | |
* of 2300, which is not enough to call buyTokens. Consider calling | |
* buyTokens directly when purchasing tokens from a contract. | |
*/ | |
receive() external payable { | |
buyTokens(_msgSender()); | |
} | |
/** | |
* @return the token being sold. | |
*/ | |
function token() public view returns (IERC20) { | |
return _token; | |
} | |
/** | |
* @return the address where funds are collected. | |
*/ | |
function wallet() public view returns (address payable) { | |
return _wallet; | |
} | |
/** | |
* @return the number of token units a buyer gets per wei. | |
*/ | |
function rate() public view returns (uint256) { | |
return _rate; | |
} | |
/** | |
* @return the amount of wei raised. | |
*/ | |
function weiRaised() public view returns (uint256) { | |
return _weiRaised; | |
} | |
/** | |
* @dev low level token purchase ***DO NOT OVERRIDE*** | |
* This function has a non-reentrancy guard, so it shouldn't be called by | |
* another `nonReentrant` function. | |
* @param beneficiary Recipient of the token purchase | |
*/ | |
function buyTokens(address beneficiary) public nonReentrant payable virtual { | |
uint256 weiAmount = msg.value; | |
_preValidatePurchase(beneficiary, weiAmount); | |
// calculate token amount to be created | |
uint256 tokens = _getTokenAmount(weiAmount); | |
// update state | |
_weiRaised = _weiRaised.add(weiAmount); | |
_processPurchase(beneficiary, tokens); | |
emit TokensPurchased(_msgSender(), beneficiary, weiAmount, tokens); | |
_updatePurchasingState(beneficiary, weiAmount); | |
_forwardFunds(); | |
_postValidatePurchase(beneficiary, weiAmount); | |
} | |
/** | |
* @dev Validation of an incoming purchase. Use require statements to revert state when conditions are not met. | |
* Use `super` in contracts that inherit from Crowdsale to extend their validations. | |
* Example from CappedCrowdsale.sol's _preValidatePurchase method: | |
* super._preValidatePurchase(beneficiary, weiAmount); | |
* require(weiRaised().add(weiAmount) <= cap); | |
* @param beneficiary Address performing the token purchase | |
* @param weiAmount Value in wei involved in the purchase | |
*/ | |
function _preValidatePurchase(address beneficiary, uint256 weiAmount) internal view virtual { | |
require(beneficiary != address(0), "Crowdsale: beneficiary is the zero address"); | |
require(weiAmount != 0, "Crowdsale: weiAmount is 0"); | |
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 | |
} | |
/** | |
* @dev Validation of an executed purchase. Observe state and use revert statements to undo rollback when valid | |
* conditions are not met. | |
* @param beneficiary Address performing the token purchase | |
* @param weiAmount Value in wei involved in the purchase | |
*/ | |
function _postValidatePurchase(address beneficiary, uint256 weiAmount) internal view virtual { | |
// solhint-disable-previous-line no-empty-blocks | |
} | |
/** | |
* @dev Source of tokens. Override this method to modify the way in which the crowdsale ultimately gets and sends | |
* its tokens. | |
* @param beneficiary Address performing the token purchase | |
* @param tokenAmount Number of tokens to be emitted | |
*/ | |
function _deliverTokens(address beneficiary, uint256 tokenAmount) internal virtual { | |
_token.safeTransfer(beneficiary, tokenAmount); | |
} | |
/** | |
* @dev Executed when a purchase has been validated and is ready to be executed. Doesn't necessarily emit/send | |
* tokens. | |
* @param beneficiary Address receiving the tokens | |
* @param tokenAmount Number of tokens to be purchased | |
*/ | |
function _processPurchase(address beneficiary, uint256 tokenAmount) internal virtual { | |
_deliverTokens(beneficiary, tokenAmount); | |
} | |
/** | |
* @dev Override for extensions that require an internal state to check for validity (current user contributions, | |
* etc.) | |
* @param beneficiary Address receiving the tokens | |
* @param weiAmount Value in wei involved in the purchase | |
*/ | |
function _updatePurchasingState(address beneficiary, uint256 weiAmount) internal virtual { | |
// solhint-disable-previous-line no-empty-blocks | |
} | |
/** | |
* @dev Override to extend the way in which ether is converted to tokens. | |
* @param weiAmount Value in wei to be converted into tokens | |
* @return Number of tokens that can be purchased with the specified _weiAmount | |
*/ | |
function _getTokenAmount(uint256 weiAmount) internal view virtual returns (uint256) { | |
return weiAmount.mul(_rate); | |
} | |
/** | |
* @dev Determines how ETH is stored/forwarded on purchases. | |
*/ | |
function _forwardFunds() internal { | |
_wallet.transfer(msg.value); | |
} | |
} |
This file contains hidden or 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.4; | |
import "./Crowdsale.sol"; | |
import "@openzeppelin/contracts/token/ERC20/presets/ERC20PresetMinterPauser.sol"; | |
/** | |
* @title MintedCrowdsale | |
* @dev Extension of Crowdsale contract whose tokens are minted in each purchase. | |
* Token ownership should be transferred to MintedCrowdsale for minting. | |
*/ | |
contract MintedCrowdsale is Crowdsale { | |
constructor( | |
uint256 r, | |
address payable w, | |
IERC20 t | |
) Crowdsale(r,w,t) { | |
} | |
/** | |
* @dev Overrides delivery by minting tokens upon purchase. | |
* @param beneficiary Token purchaser | |
* @param tokenAmount Number of tokens to be minted | |
*/ | |
function _deliverTokens(address beneficiary, uint256 tokenAmount) internal override { | |
// Potentially dangerous assumption about the type of the token. | |
ERC20PresetMinterPauser(address(token())).mint(beneficiary, tokenAmount); | |
} | |
function _processPurchase(address beneficiary, uint256 tokenAmount) | |
internal | |
override | |
{ | |
_deliverTokens(beneficiary, tokenAmount); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment