-
Notifications
You must be signed in to change notification settings - Fork 588
Expand file tree
/
Copy pathERC20DropVote.sol
More file actions
135 lines (114 loc) · 5.08 KB
/
ERC20DropVote.sol
File metadata and controls
135 lines (114 loc) · 5.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.0;
/// @author thirdweb
import "../external-deps/openzeppelin/token/ERC20/extensions/ERC20Votes.sol";
import "../extension/ContractMetadata.sol";
import "../extension/Multicall.sol";
import "../extension/Ownable.sol";
import "../extension/PrimarySale.sol";
import "../extension/DropSinglePhase.sol";
import { CurrencyTransferLib } from "../lib/CurrencyTransferLib.sol";
/**
* BASE: ERC20Votes
* EXTENSION: DropSinglePhase
*
* The `ERC20Drop` contract uses the `DropSinglePhase` extensions, along with `ERC20Votes`.
* It implements the ERC20 standard, along with the following additions to standard ERC20 logic:
*
* - Ownership of the contract, with the ability to restrict certain functions to
* only be called by the contract's owner.
*
* - Multicall capability to perform multiple actions atomically
*
* - EIP 2612 compliance: See {ERC20-permit} method, which can be used to change an account's ERC20 allowance by
* presenting a message signed by the account.
*
* The `drop` mechanism in the `DropSinglePhase` extension is a distribution mechanism tokens. It lets
* you set restrictions such as a price to charge, an allowlist etc. when an address atttempts to mint tokens.
*
*/
contract ERC20DropVote is ContractMetadata, Multicall, Ownable, ERC20Votes, PrimarySale, DropSinglePhase {
/*//////////////////////////////////////////////////////////////
Constructor
//////////////////////////////////////////////////////////////*/
constructor(
address _defaultAdmin,
string memory _name,
string memory _symbol,
address _primarySaleRecipient
) ERC20Permit(_name, _symbol) {
_setupOwner(_defaultAdmin);
_setupPrimarySaleRecipient(_primarySaleRecipient);
}
/*//////////////////////////////////////////////////////////////
ERC20 logic
//////////////////////////////////////////////////////////////*/
/**
* @notice Lets an owner a given amount of their tokens.
* @dev Caller should own the `_amount` of tokens.
*
* @param _amount The number of tokens to burn.
*/
function burn(uint256 _amount) external virtual {
require(balanceOf(msg.sender) >= _amount, "not enough balance");
_burn(msg.sender, _amount);
}
/*//////////////////////////////////////////////////////////////
Internal (overrideable) functions
//////////////////////////////////////////////////////////////*/
/// @dev Collects and distributes the primary sale value of tokens being claimed.
function _collectPriceOnClaim(
address _primarySaleRecipient,
uint256 _quantityToClaim,
address _currency,
uint256 _pricePerToken
) internal virtual override {
if (_pricePerToken == 0) {
require(msg.value == 0, "!Value");
return;
}
uint256 totalPrice = (_quantityToClaim * _pricePerToken) / 1 ether;
require(totalPrice > 0, "quantity too low");
bool validMsgValue;
if (_currency == CurrencyTransferLib.NATIVE_TOKEN) {
validMsgValue = msg.value == totalPrice;
} else {
validMsgValue = msg.value == 0;
}
require(validMsgValue, "Invalid msg value");
address saleRecipient = _primarySaleRecipient == address(0) ? primarySaleRecipient() : _primarySaleRecipient;
CurrencyTransferLib.transferCurrency(_currency, msg.sender, saleRecipient, totalPrice);
}
/// @dev Transfers the tokens being claimed.
function _transferTokensOnClaim(
address _to,
uint256 _quantityBeingClaimed
) internal virtual override returns (uint256) {
_mint(_to, _quantityBeingClaimed);
return 0;
}
/// @dev Checks whether platform fee info can be set in the given execution context.
function _canSetClaimConditions() internal view virtual override returns (bool) {
return msg.sender == owner();
}
/// @dev Returns whether contract metadata can be set in the given execution context.
function _canSetContractURI() internal view virtual override returns (bool) {
return msg.sender == owner();
}
/// @dev Returns whether tokens can be minted in the given execution context.
function _canMint() internal view virtual returns (bool) {
return msg.sender == owner();
}
/// @dev Returns whether owner can be set in the given execution context.
function _canSetOwner() internal view virtual override returns (bool) {
return msg.sender == owner();
}
/// @dev Returns whether primary sale recipient can be set in the given execution context.
function _canSetPrimarySaleRecipient() internal view virtual override returns (bool) {
return msg.sender == owner();
}
/// @notice Returns the sender in the given execution context.
function _msgSender() internal view virtual override(Multicall, Context) returns (address) {
return msg.sender;
}
}