// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@thirdweb-dev/contracts/base/ERC20Base.sol";
import "@thirdweb-dev/contracts/extension/SignatureMintERC20.sol";
import "@thirdweb-dev/contracts/lib/CurrencyTransferLib.sol";
contract ERC20SignatureMint is ERC20Base, SignatureMintERC20 {
/*//////////////////////////////////////////////////////////////
Constructor
//////////////////////////////////////////////////////////////*/
constructor(address _defaultAdmin, string memory _name, string memory _symbol)
ERC20Base(_defaultAdmin, _name, _symbol)
{}
/// @dev Mints tokens according to the provided mint request.
function mintWithSignature(
MintRequest calldata _req,
bytes calldata _signature
) external payable virtual returns (address signer) {
require(_req.quantity > 0, "Minting zero tokens.");
// Verify and process payload.
signer = _processRequest(_req, _signature);
address receiver = _req.to;
// Collect price
_collectPriceOnClaim(
_req.primarySaleRecipient,
_req.quantity,
_req.currency,
_req.pricePerToken
);
// Mint tokens.
_mint(receiver, _req.quantity);
emit TokensMintedWithSignature(signer, receiver, _req);
}
/// @dev Returns whether a given address is authorized to sign mint requests.
function _canSignMintRequest(address _signer)
internal
view
virtual
override
returns (bool)
{
return _signer == owner();
}
/// @dev Collects and distributes the primary sale value of tokens being claimed.
function _collectPriceOnClaim(
address _primarySaleRecipient,
uint256 _quantityToClaim,
address _currency,
uint256 _pricePerToken
) internal virtual {
if (_pricePerToken == 0) {
return;
}
uint256 totalPrice = (_quantityToClaim * _pricePerToken) / 1 ether;
require(totalPrice > 0, "quantity too low");
if (_currency == CurrencyTransferLib.NATIVE_TOKEN) {
require(msg.value == totalPrice, "Must send total price.");
}
address saleRecipient = _primarySaleRecipient;
CurrencyTransferLib.transferCurrency(
_currency,
msg.sender,
saleRecipient,
totalPrice
);
}
}