-
Notifications
You must be signed in to change notification settings - Fork 8
/
LensSeaDropCollection.sol
170 lines (150 loc) · 6.41 KB
/
LensSeaDropCollection.sol
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
import {ERC721SeaDropCloneable} from '@seadrop/clones/ERC721SeaDropCloneable.sol';
import {ISeaDrop} from '@seadrop/interfaces/ISeaDrop.sol';
import {PublicDrop} from '@seadrop/lib/SeaDropStructs.sol';
import {IModuleGlobals} from 'contracts/interfaces/IModuleGlobals.sol';
contract LensSeaDropCollection is ERC721SeaDropCloneable {
error OnlySeaDropActionModule();
error FeesDoNotCoverLensTreasury();
error InvalidParams();
uint16 private constant ROYALTIES_BPS = 1_000;
IModuleGlobals immutable MODULE_GLOBALS;
address immutable SEADROP_ACTION_MODULE;
address immutable DEFAULT_SEADROP;
// TODO: Might use the ActionRestricted inheritance instead.
modifier onlySeaDropActionModule() {
if (msg.sender != SEADROP_ACTION_MODULE) {
revert OnlySeaDropActionModule();
}
_;
}
constructor(
address seaDropActionModule,
address moduleGlobals,
address defaultSeaDrop
) {
SEADROP_ACTION_MODULE = seaDropActionModule;
MODULE_GLOBALS = IModuleGlobals(moduleGlobals);
DEFAULT_SEADROP = defaultSeaDrop;
}
function initialize(
address owner,
string calldata name,
string calldata symbol,
address[] calldata allowedSeaDrops,
MultiConfigureStruct calldata config
) external onlySeaDropActionModule {
_validateInitializationData(allowedSeaDrops, config);
super.initialize({
__name: name,
__symbol: symbol,
allowedSeaDrop: allowedSeaDrops,
initialOwner: address(this)
});
this.multiConfigure(config);
this.setRoyaltyInfo(RoyaltyInfo({royaltyAddress: owner, royaltyBps: ROYALTIES_BPS}));
_transferOwnership(owner);
}
function _validateInitializationData(address[] calldata allowedSeaDrops, MultiConfigureStruct calldata config)
internal
view
{
// Makes sure that the default used SeaDrop is allowed as the first element of the array.
if (allowedSeaDrops.length == 0 || allowedSeaDrops[0] != DEFAULT_SEADROP) {
revert InvalidParams();
}
// Makes sure that the SeaDropMintPublicationAction is allowed as a fee recipient.
if (config.allowedFeeRecipients.length == 0 || config.allowedFeeRecipients[0] != SEADROP_ACTION_MODULE) {
revert InvalidParams();
}
// Makes sure that the SeaDropMintPublicationAction is allowed as a payer.
if (config.allowedPayers.length == 0 || config.allowedPayers[0] != SEADROP_ACTION_MODULE) {
revert InvalidParams();
}
// NOTE: Validations of fee BPS, disallowed fee recipients or payers are done in the respective overridden
// functions that will be called by the `multiConfigure` function afterward.
}
/**
* @notice Update the allowed SeaDrop contracts.
* Only the owner or administrator can use this function.
*
* @param allowedSeaDrop The allowed SeaDrop addresses.
*/
function updateAllowedSeaDrop(address[] calldata allowedSeaDrop) external virtual override onlyOwner {
// Makes sure that the default used SeaDrop is allowed as the first element of the array.
if (allowedSeaDrop.length == 0 || allowedSeaDrop[0] != DEFAULT_SEADROP) {
revert InvalidParams();
}
_updateAllowedSeaDrop(allowedSeaDrop);
}
/**
* @notice Update the public drop data for this NFT contract on SeaDrop.
* Only the owner can use this function.
*
* @param seaDropImpl The allowed SeaDrop contract.
* @param publicDrop The public drop data.
*/
function updatePublicDrop(address seaDropImpl, PublicDrop calldata publicDrop) external virtual override {
// We only enforce the fees to cover the Lens Treasury fees when using the default SeaDrop, as it is the SeaDrop
// chosen by Lens.
if (seaDropImpl == DEFAULT_SEADROP && publicDrop.feeBps < MODULE_GLOBALS.getTreasuryFee()) {
revert FeesDoNotCoverLensTreasury();
}
// Ensure the sender is only the owner or this contract itself.
_onlyOwnerOrSelf();
// Ensure the SeaDrop is allowed.
_onlyAllowedSeaDrop(seaDropImpl);
// Update the public drop data on SeaDrop.
ISeaDrop(seaDropImpl).updatePublicDrop(publicDrop);
}
/**
* @notice Update the allowed fee recipient for this NFT contract
* on SeaDrop.
* Only the owner can set the allowed fee recipient.
*
* @param seaDropImpl The allowed SeaDrop contract.
* @param feeRecipient The new fee recipient.
* @param allowed If the fee recipient is allowed.
*/
function updateAllowedFeeRecipient(
address seaDropImpl,
address feeRecipient,
bool allowed
) external virtual override {
// We only enforce the SeaDropMintPublicationAction to be used as a fee recipient when using the default SeaDrop.
if (seaDropImpl == DEFAULT_SEADROP && !allowed && feeRecipient == SEADROP_ACTION_MODULE) {
revert InvalidParams();
}
// Ensure the sender is only the owner or this contract itself.
_onlyOwnerOrSelf();
// Ensure the SeaDrop is allowed.
_onlyAllowedSeaDrop(seaDropImpl);
// Update the allowed fee recipient.
ISeaDrop(seaDropImpl).updateAllowedFeeRecipient(feeRecipient, allowed);
}
/**
* @notice Update the allowed payers for this NFT contract on SeaDrop.
* Only the owner can use this function.
*
* @param seaDropImpl The allowed SeaDrop contract.
* @param payer The payer to update.
* @param allowed Whether the payer is allowed.
*/
function updatePayer(
address seaDropImpl,
address payer,
bool allowed
) external virtual override {
// We only enforce the SeaDropMintPublicationAction to be enabled as a payer when using the default SeaDrop.
if (seaDropImpl == DEFAULT_SEADROP && !allowed && payer == SEADROP_ACTION_MODULE) {
revert InvalidParams();
}
// Ensure the sender is only the owner or this contract itself.
_onlyOwnerOrSelf();
// Ensure the SeaDrop is allowed.
_onlyAllowedSeaDrop(seaDropImpl);
// Update the payer.
ISeaDrop(seaDropImpl).updatePayer(payer, allowed);
}
}