@@ -3,43 +3,45 @@ pragma solidity ^0.8.0;
33
44import "./interface/IDropSinglePhase.sol " ;
55import "../lib/MerkleProof.sol " ;
6+ import "./Context.sol " ;
67import "@openzeppelin/contracts-upgradeable/utils/structs/BitMapsUpgradeable.sol " ;
78
8- abstract contract DropSinglePhase is IDropSinglePhase {
9+ abstract contract DropSinglePhase is IDropSinglePhase , Context {
10+
911 using BitMapsUpgradeable for BitMapsUpgradeable.BitMap;
1012
11- /// @dev The active conditions for claiming lazy minted tokens.
12- ClaimCondition public claimCondition;
13+ /*///////////////////////////////////////////////////////////////
14+ State variables
15+ //////////////////////////////////////////////////////////////*/
1316
14- mapping ( bytes32 => mapping ( address => uint256 )) private lastClaimTimestamp;
15- mapping ( bytes32 => BitMapsUpgradeable.BitMap) private usedAllowlistSpot ;
17+ /// @dev The active conditions for claiming tokens.
18+ ClaimCondition public claimCondition ;
1619
1720 /// @dev The ID for the active claim condition.
1821 bytes32 private conditionId;
1922
20- function _msgSender () internal virtual returns ( address ) {
21- return msg . sender ;
22- }
23+ /*///////////////////////////////////////////////////////////////
24+ Mappings
25+ //////////////////////////////////////////////////////////////*/
2326
24- function _beforeClaim (
25- address _receiver ,
26- uint256 _quantity ,
27- address _currency ,
28- uint256 _pricePerToken ,
29- AllowlistProof calldata _allowlistProof ,
30- bytes memory _data
31- ) internal virtual ;
27+ /**
28+ * @dev Map from an account and uid for a claim condition, to the last timestamp
29+ * at which the account claimed tokens under that claim condition.
30+ */
31+ mapping (bytes32 => mapping (address => uint256 )) private lastClaimTimestamp;
32+
33+ /**
34+ * @dev Map from a claim condition uid to whether an address in an allowlist
35+ * has already claimed tokens i.e. used their place in the allowlist.
36+ */
37+ mapping (bytes32 => BitMapsUpgradeable.BitMap) private usedAllowlistSpot;
3238
33- function _afterClaim (
34- address _receiver ,
35- uint256 _quantity ,
36- address _currency ,
37- uint256 _pricePerToken ,
38- AllowlistProof calldata _allowlistProof ,
39- bytes memory _data
40- ) internal virtual ;
4139
42- /// @dev Lets an account claim NFTs.
40+ /*///////////////////////////////////////////////////////////////
41+ Drop logic
42+ //////////////////////////////////////////////////////////////*/
43+
44+ /// @dev Lets an account claim tokens.
4345 function claim (
4446 address _receiver ,
4547 uint256 _quantity ,
@@ -51,6 +53,7 @@ abstract contract DropSinglePhase is IDropSinglePhase {
5153 _beforeClaim (_receiver, _quantity, _currency, _pricePerToken, _allowlistProof, _data);
5254
5355 bytes32 activeConditionId = conditionId;
56+
5457 /**
5558 * We make allowlist checks (i.e. verifyClaimMerkleProof) before verifying the claim's general
5659 * validity (i.e. verifyClaim) because we give precedence to the check of allow list quantity
@@ -83,46 +86,40 @@ abstract contract DropSinglePhase is IDropSinglePhase {
8386 lastClaimTimestamp[activeConditionId][_msgSender ()] = block .timestamp ;
8487
8588 // If there's a price, collect price.
86- collectPrice (_quantity, _currency, _pricePerToken);
89+ collectPriceOnClaim (_quantity, _currency, _pricePerToken);
8790
8891 // Mint the relevant NFTs to claimer.
89- uint256 startTokenId = transferClaimedTokens (_receiver, _quantity);
92+ uint256 startTokenId = transferTokensOnClaim (_receiver, _quantity);
9093
9194 emit TokensClaimed (claimCondition, _msgSender (), _receiver, _quantity, startTokenId);
9295
9396 _afterClaim (_receiver, _quantity, _currency, _pricePerToken, _allowlistProof, _data);
9497 }
9598
96- /// @dev Collects and distributes the primary sale value of NFTs being claimed.
97- function collectPrice (
98- uint256 _quantityToClaim ,
99- address _currency ,
100- uint256 _pricePerToken
101- ) internal virtual ;
99+ /// @dev Lets a contract admin set claim conditions.
100+ function setClaimConditions (ClaimCondition calldata _condition , bool _resetClaimEligibility , bytes memory ) external {
102101
103- /// @dev Transfers the NFTs being claimed.
104- function transferClaimedTokens (address _to , uint256 _quantityBeingClaimed )
105- internal
106- virtual
107- returns (uint256 startTokenId );
102+ bytes32 targetConditionId = conditionId;
103+ uint256 supplyClaimedAlready = claimCondition.supplyClaimed;
108104
109- function setClaimCondition (ClaimCondition calldata _condition , bool _resetClaimEligibility ) external {
110105 if (_resetClaimEligibility) {
111- conditionId = keccak256 (abi.encodePacked (msg .sender , block .number ));
106+ supplyClaimedAlready = 0 ;
107+ targetConditionId = keccak256 (abi.encodePacked (msg .sender , block .number ));
112108 }
113109
114- ClaimCondition memory currentConditoin = claimCondition ;
110+ require (supplyClaimedAlready <= _condition.maxClaimableSupply, " max supply claimed already " ) ;
115111
116112 claimCondition = ClaimCondition ({
117113 startTimestamp: block .timestamp ,
118114 maxClaimableSupply: _condition.maxClaimableSupply,
119- supplyClaimed: _resetClaimEligibility ? currentConditoin.supplyClaimed : _condition.supplyClaimed ,
115+ supplyClaimed: supplyClaimedAlready ,
120116 quantityLimitPerTransaction: _condition.supplyClaimed,
121117 waitTimeInSecondsBetweenClaims: _condition.waitTimeInSecondsBetweenClaims,
122118 merkleRoot: _condition.merkleRoot,
123119 pricePerToken: _condition.pricePerToken,
124120 currency: _condition.currency
125121 });
122+ conditionId = targetConditionId;
126123
127124 emit ClaimConditionUpdated (_condition, _resetClaimEligibility);
128125 }
@@ -152,12 +149,6 @@ abstract contract DropSinglePhase is IDropSinglePhase {
152149 currentClaimPhase.supplyClaimed + _quantity <= currentClaimPhase.maxClaimableSupply,
153150 "exceed max claimable supply. "
154151 );
155- // require(nextTokenIdToClaim + _quantity <= nextTokenIdToMint, "not enough minted tokens.");
156- // require(maxTotalSupply == 0 || nextTokenIdToClaim + _quantity <= maxTotalSupply, "exceed max total supply.");
157- // require(
158- // maxWalletClaimCount == 0 || walletClaimCount[_claimer] + _quantity <= maxWalletClaimCount,
159- // "exceed claim limit"
160- // );
161152
162153 uint256 timestampOfLastClaim = lastClaimTimestamp[conditionId][_claimer];
163154 require (
@@ -189,4 +180,41 @@ abstract contract DropSinglePhase is IDropSinglePhase {
189180 );
190181 }
191182 }
183+
184+ /*///////////////////////////////////////////////////////////////
185+ Virtual functions: to be implemented in derived contract
186+ //////////////////////////////////////////////////////////////*/
187+
188+ /// @dev Runs before every `claim` function call.
189+ function _beforeClaim (
190+ address _receiver ,
191+ uint256 _quantity ,
192+ address _currency ,
193+ uint256 _pricePerToken ,
194+ AllowlistProof calldata _allowlistProof ,
195+ bytes memory _data
196+ ) internal virtual {}
197+
198+ /// @dev Runs after every `claim` function call.
199+ function _afterClaim (
200+ address _receiver ,
201+ uint256 _quantity ,
202+ address _currency ,
203+ uint256 _pricePerToken ,
204+ AllowlistProof calldata _allowlistProof ,
205+ bytes memory _data
206+ ) internal virtual {}
207+
208+ /// @dev Collects and distributes the primary sale value of NFTs being claimed.
209+ function collectPriceOnClaim (
210+ uint256 _quantityToClaim ,
211+ address _currency ,
212+ uint256 _pricePerToken
213+ ) internal virtual ;
214+
215+ /// @dev Transfers the NFTs being claimed.
216+ function transferTokensOnClaim (
217+ address _to ,
218+ uint256 _quantityBeingClaimed
219+ ) internal virtual returns (uint256 startTokenId );
192220}
0 commit comments