Skip to content

Commit d96518c

Browse files
Krishang NadgaudaKrishang Nadgauda
authored andcommitted
Merge branch 'thirdweb-implementations' into nkrishang/signature-drop
2 parents 8532f41 + adb9138 commit d96518c

20 files changed

+2203
-146
lines changed

contracts/drop/SignatureDrop.sol

Lines changed: 41 additions & 143 deletions
Original file line numberDiff line numberDiff line change
@@ -24,29 +24,31 @@ import "../lib/FeeType.sol";
2424

2525
// ========== Features ==========
2626

27-
import "../feature/interface/IThirdwebPlatformFee.sol";
28-
import "../feature/interface/IThirdwebPrimarySale.sol";
29-
import "../feature/interface/IThirdwebRoyalty.sol";
30-
import "../feature/interface/IThirdwebOwnable.sol";
27+
import "../feature/ContractMetadata.sol";
28+
import "../feature/PlatformFee.sol";
29+
import "../feature/Royalty.sol";
30+
import "../feature/PrimarySale.sol";
31+
import "../feature/Ownable.sol";
3132
import "../feature/DelayedReveal.sol";
3233
import "../feature/LazyMint.sol";
34+
import "../feature/PermissionsEnumerable.sol";
3335
import "../feature/SignatureMintERC721Upgradeable.sol";
3436

3537
contract SignatureDrop is
3638
Initializable,
37-
IThirdwebContract,
38-
IThirdwebOwnable,
39-
IThirdwebRoyalty,
40-
IThirdwebPrimarySale,
41-
IThirdwebPlatformFee,
39+
ContractMetadata,
40+
PlatformFee,
41+
Royalty,
42+
PrimarySale,
43+
Ownable,
44+
DelayedReveal,
45+
LazyMint,
46+
PermissionsEnumerable,
47+
SignatureMintERC721Upgradeable,
4248
IDropClaimCondition,
4349
ReentrancyGuardUpgradeable,
4450
ERC2771ContextUpgradeable,
4551
MulticallUpgradeable,
46-
AccessControlEnumerableUpgradeable,
47-
DelayedReveal,
48-
LazyMint,
49-
SignatureMintERC721Upgradeable,
5052
ERC721AUpgradeable
5153
{
5254
using StringsUpgradeable for uint256;
@@ -69,27 +71,6 @@ contract SignatureDrop is
6971
/// @dev The thirdweb contract with fee related information.
7072
ITWFee private immutable thirdwebFee;
7173

72-
/// @dev Owner of the contract (purpose: OpenSea compatibility)
73-
address private _owner;
74-
75-
/// @dev The address that receives all primary sales value.
76-
address public primarySaleRecipient;
77-
78-
/// @dev The address that receives all platform fees from all sales.
79-
address private platformFeeRecipient;
80-
81-
/// @dev The % of primary sales collected as platform fees.
82-
uint16 private platformFeeBps;
83-
84-
/// @dev The (default) address that receives all royalty value.
85-
address private royaltyRecipient;
86-
87-
/// @dev The (default) % of a sale to take as royalty (in basis points).
88-
uint16 private royaltyBps;
89-
90-
/// @dev Contract level metadata.
91-
string public contractURI;
92-
9374
/// @dev The tokenId of the next NFT that will be minted / lazy minted.
9475
uint256 public nextTokenIdToMint;
9576

@@ -106,9 +87,6 @@ contract SignatureDrop is
10687
/// @dev Mapping from claimer => condition Id => timestamp of last claim.
10788
mapping(address => mapping(bytes32 => uint256)) private lastClaimTimestamp;
10889

109-
/// @dev Token ID => royalty recipient and bps for token
110-
mapping(uint256 => RoyaltyInfo) private royaltyInfoForToken;
111-
11290
/*///////////////////////////////////////////////////////////////
11391
Events
11492
//////////////////////////////////////////////////////////////*/
@@ -153,18 +131,17 @@ contract SignatureDrop is
153131
__SignatureMintERC721_init();
154132

155133
// Initialize this contract's state.
156-
royaltyRecipient = _royaltyRecipient;
157-
royaltyBps = uint16(_royaltyBps);
158-
platformFeeRecipient = _platformFeeRecipient;
159-
platformFeeBps = uint16(_platformFeeBps);
160-
primarySaleRecipient = _saleRecipient;
161134
contractURI = _contractURI;
162-
_owner = _defaultAdmin;
135+
owner = _defaultAdmin;
163136

164137
_setupRole(DEFAULT_ADMIN_ROLE, _defaultAdmin);
165138
_setupRole(MINTER_ROLE, _defaultAdmin);
166139
_setupRole(TRANSFER_ROLE, _defaultAdmin);
167140
_setupRole(TRANSFER_ROLE, address(0));
141+
142+
setPlatformFeeInfo(_platformFeeRecipient, _platformFeeBps);
143+
setDefaultRoyaltyInfo(_royaltyRecipient, _royaltyBps);
144+
setPrimarySaleRecipient(_saleRecipient);
168145
}
169146

170147
/*///////////////////////////////////////////////////////////////
@@ -181,13 +158,6 @@ contract SignatureDrop is
181158
return uint8(VERSION);
182159
}
183160

184-
/**
185-
* @dev Returns the address of the current owner.
186-
*/
187-
function owner() public view returns (address) {
188-
return hasRole(DEFAULT_ADMIN_ROLE, _owner) ? _owner : address(0);
189-
}
190-
191161
/*///////////////////////////////////////////////////////////////
192162
ERC 165 / 721 / 2981 logic
193163
//////////////////////////////////////////////////////////////*/
@@ -202,24 +172,12 @@ contract SignatureDrop is
202172
public
203173
view
204174
virtual
205-
override(ERC721AUpgradeable, AccessControlEnumerableUpgradeable)
175+
override(ERC721AUpgradeable)
206176
returns (bool)
207177
{
208178
return super.supportsInterface(interfaceId) || type(IERC2981Upgradeable).interfaceId == interfaceId;
209179
}
210180

211-
/// @dev Returns the royalty recipient and amount, given a tokenId and sale price.
212-
function royaltyInfo(uint256 tokenId, uint256 salePrice)
213-
external
214-
view
215-
virtual
216-
returns (address receiver, uint256 royaltyAmount)
217-
{
218-
(address recipient, uint256 bps) = getRoyaltyInfoForToken(tokenId);
219-
receiver = recipient;
220-
royaltyAmount = (salePrice * bps) / MAX_BPS;
221-
}
222-
223181
/*///////////////////////////////////////////////////////////////
224182
Lazy minting + delayed-reveal logic
225183
//////////////////////////////////////////////////////////////*/
@@ -366,6 +324,8 @@ contract SignatureDrop is
366324
return;
367325
}
368326

327+
(address platformFeeRecipient, uint16 platformFeeBps) = getPlatformFeeInfo();
328+
369329
uint256 totalPrice = _quantityToClaim * _pricePerToken;
370330
uint256 platformFees = (totalPrice * platformFeeBps) / MAX_BPS;
371331
(address twFeeRecipient, uint256 twFeeBps) = thirdwebFee.getFeeInfo(address(this), FeeType.PRIMARY_SALE);
@@ -380,7 +340,7 @@ contract SignatureDrop is
380340
CurrencyTransferLib.transferCurrency(
381341
_currency,
382342
_msgSender(),
383-
primarySaleRecipient,
343+
primarySaleRecipient(),
384344
totalPrice - platformFees - twFee
385345
);
386346
}
@@ -390,91 +350,29 @@ contract SignatureDrop is
390350
return hasRole(MINTER_ROLE, _signer);
391351
}
392352

393-
/*///////////////////////////////////////////////////////////////
394-
Getter functions
395-
//////////////////////////////////////////////////////////////*/
396-
397-
/// @dev Lets a contract admin set the recipient for all primary sales.
398-
function setPrimarySaleRecipient(address _saleRecipient) external onlyRole(DEFAULT_ADMIN_ROLE) {
399-
primarySaleRecipient = _saleRecipient;
400-
emit PrimarySaleRecipientUpdated(_saleRecipient);
401-
}
402-
403-
/// @dev Lets a contract admin update the default royalty recipient and bps.
404-
function setDefaultRoyaltyInfo(address _royaltyRecipient, uint256 _royaltyBps)
405-
external
406-
onlyRole(DEFAULT_ADMIN_ROLE)
407-
{
408-
require(_royaltyBps <= MAX_BPS, "> MAX_BPS");
409-
410-
royaltyRecipient = _royaltyRecipient;
411-
royaltyBps = uint16(_royaltyBps);
412-
413-
emit DefaultRoyalty(_royaltyRecipient, _royaltyBps);
353+
/// @dev Returns whether platform fee info can be set in the given execution context.
354+
function _canSetPlatformFeeInfo() internal view override returns (bool) {
355+
return hasRole(DEFAULT_ADMIN_ROLE, _msgSender());
414356
}
415357

416-
/// @dev Lets a contract admin set the royalty recipient and bps for a particular token Id.
417-
function setRoyaltyInfoForToken(
418-
uint256 _tokenId,
419-
address _recipient,
420-
uint256 _bps
421-
) external onlyRole(DEFAULT_ADMIN_ROLE) {
422-
require(_bps <= MAX_BPS, "> MAX_BPS");
423-
424-
royaltyInfoForToken[_tokenId] = RoyaltyInfo({ recipient: _recipient, bps: _bps });
425-
426-
emit RoyaltyForToken(_tokenId, _recipient, _bps);
358+
/// @dev Returns whether primary sale recipient can be set in the given execution context.
359+
function _canSetPrimarySaleRecipient() internal view override returns (bool) {
360+
return hasRole(DEFAULT_ADMIN_ROLE, _msgSender());
427361
}
428362

429-
/// @dev Lets a contract admin update the platform fee recipient and bps
430-
function setPlatformFeeInfo(address _platformFeeRecipient, uint256 _platformFeeBps)
431-
external
432-
onlyRole(DEFAULT_ADMIN_ROLE)
433-
{
434-
require(_platformFeeBps <= MAX_BPS, "> MAX_BPS.");
435-
436-
platformFeeBps = uint16(_platformFeeBps);
437-
platformFeeRecipient = _platformFeeRecipient;
438-
439-
emit PlatformFeeInfoUpdated(_platformFeeRecipient, _platformFeeBps);
440-
}
441-
442-
/// @dev Lets a contract admin set a new owner for the contract. The new owner must be a contract admin.
443-
function setOwner(address _newOwner) external onlyRole(DEFAULT_ADMIN_ROLE) {
444-
require(hasRole(DEFAULT_ADMIN_ROLE, _newOwner), "!ADMIN");
445-
address _prevOwner = _owner;
446-
_owner = _newOwner;
447-
448-
emit OwnerUpdated(_prevOwner, _newOwner);
449-
}
450-
451-
/// @dev Lets a contract admin set the URI for contract-level metadata.
452-
function setContractURI(string calldata _uri) external onlyRole(DEFAULT_ADMIN_ROLE) {
453-
contractURI = _uri;
454-
}
455-
456-
/*///////////////////////////////////////////////////////////////
457-
Setter functions
458-
//////////////////////////////////////////////////////////////*/
459-
460-
/// @dev Returns the royalty recipient and bps for a particular token Id.
461-
function getRoyaltyInfoForToken(uint256 _tokenId) public view returns (address, uint16) {
462-
RoyaltyInfo memory royaltyForToken = royaltyInfoForToken[_tokenId];
463-
464-
return
465-
royaltyForToken.recipient == address(0)
466-
? (royaltyRecipient, uint16(royaltyBps))
467-
: (royaltyForToken.recipient, uint16(royaltyForToken.bps));
363+
/// @dev Returns whether owner can be set in the given execution context.
364+
function _canSetOwner() internal view override returns (bool) {
365+
return hasRole(DEFAULT_ADMIN_ROLE, _msgSender());
468366
}
469367

470-
/// @dev Returns the platform fee recipient and bps.
471-
function getPlatformFeeInfo() external view returns (address, uint16) {
472-
return (platformFeeRecipient, uint16(platformFeeBps));
368+
/// @dev Returns whether royalty info can be set in the given execution context.
369+
function _canSetRoyaltyInfo() internal view override returns (bool) {
370+
return hasRole(DEFAULT_ADMIN_ROLE, _msgSender());
473371
}
474372

475-
/// @dev Returns the default royalty recipient and bps.
476-
function getDefaultRoyaltyInfo() external view returns (address, uint16) {
477-
return (royaltyRecipient, uint16(royaltyBps));
373+
/// @dev Returns whether contract metadata can be set in the given execution context.
374+
function _canSetContractURI() internal view override returns (bool) {
375+
return hasRole(DEFAULT_ADMIN_ROLE, _msgSender());
478376
}
479377

480378
/*///////////////////////////////////////////////////////////////
@@ -513,7 +411,7 @@ contract SignatureDrop is
513411
internal
514412
view
515413
virtual
516-
override(ContextUpgradeable, ERC2771ContextUpgradeable)
414+
override(ContextUpgradeable, ERC2771ContextUpgradeable, Context)
517415
returns (address sender)
518416
{
519417
return ERC2771ContextUpgradeable._msgSender();
@@ -523,7 +421,7 @@ contract SignatureDrop is
523421
internal
524422
view
525423
virtual
526-
override(ContextUpgradeable, ERC2771ContextUpgradeable)
424+
override(ContextUpgradeable, ERC2771ContextUpgradeable, Context)
527425
returns (bytes calldata)
528426
{
529427
return ERC2771ContextUpgradeable._msgData();

contracts/feature/Context.sol

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// SPDX-License-Identifier: MIT
2+
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
3+
4+
pragma solidity ^0.8.0;
5+
6+
/**
7+
* @dev Provides information about the current execution context, including the
8+
* sender of the transaction and its data. While these are generally available
9+
* via msg.sender and msg.data, they should not be accessed in such a direct
10+
* manner, since when dealing with meta-transactions the account sending and
11+
* paying for execution may not be the actual sender (as far as an application
12+
* is concerned).
13+
*
14+
* This contract is only required for intermediate, library-like contracts.
15+
*/
16+
abstract contract Context {
17+
function _msgSender() internal view virtual returns (address) {
18+
return msg.sender;
19+
}
20+
21+
function _msgData() internal view virtual returns (bytes calldata) {
22+
return msg.data;
23+
}
24+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
pragma solidity ^0.8.0;
3+
4+
import "../interfaces/IThirdwebContract.sol";
5+
import "@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol";
6+
7+
abstract contract ContractMetadata is IThirdwebContract {
8+
9+
/// @dev Contract level metadata.
10+
string public contractURI;
11+
12+
/// @dev Lets a contract admin set the URI for contract-level metadata.
13+
function setContractURI(string calldata _uri) external {
14+
require(_canSetContractURI(), "Not authorized");
15+
contractURI = _uri;
16+
}
17+
18+
/// @dev Returns whether contract metadata can be set in the given execution context.
19+
function _canSetContractURI() internal virtual returns (bool);
20+
}

contracts/feature/Ownable.sol

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
pragma solidity ^0.8.0;
3+
4+
import "./interface/IThirdwebOwnable.sol";
5+
6+
abstract contract Ownable is IThirdwebOwnable {
7+
8+
/// @dev Owner of the contract (purpose: OpenSea compatibility)
9+
address public owner;
10+
11+
/// @dev Lets a contract admin set a new owner for the contract. The new owner must be a contract admin.
12+
function setOwner(address _newOwner) external {
13+
require(_canSetOwner(), "Not authorized");
14+
15+
address _prevOwner = owner;
16+
owner = _newOwner;
17+
18+
emit OwnerUpdated(_prevOwner, _newOwner);
19+
}
20+
21+
/// @dev Returns whether owner can be set in the given execution context.
22+
function _canSetOwner() internal virtual returns (bool);
23+
}

0 commit comments

Comments
 (0)