lens-modules 1.0.5 → 1.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
pragma solidity ^0.8.15;
|
|
4
|
+
|
|
5
|
+
import {IModuleRegistry} from '../interfaces/IModuleRegistry.sol';
|
|
6
|
+
import {IERC20Metadata} from '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';
|
|
7
|
+
import {ILensModule} from '../modules/interfaces/ILensModule.sol';
|
|
8
|
+
|
|
9
|
+
import {IPublicationActionModule} from '../interfaces/IPublicationActionModule.sol';
|
|
10
|
+
import {IFollowModule} from '../interfaces/IFollowModule.sol';
|
|
11
|
+
import {IReferenceModule} from '../interfaces/IReferenceModule.sol';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @title ModuleRegistry
|
|
15
|
+
* @author Lens Protocol
|
|
16
|
+
* @notice A registry for modules and currencies
|
|
17
|
+
* @custom:upgradeable Transparent upgradeable proxy without initializer.
|
|
18
|
+
*/
|
|
19
|
+
contract ModuleRegistry is IModuleRegistry {
|
|
20
|
+
bytes4 private constant LENS_MODULE_INTERFACE_ID = bytes4(keccak256(abi.encodePacked('LENS_MODULE')));
|
|
21
|
+
|
|
22
|
+
event ModuleRegistered(
|
|
23
|
+
address indexed moduleAddress,
|
|
24
|
+
uint256 indexed moduleType,
|
|
25
|
+
string metadata,
|
|
26
|
+
uint256 timestamp
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
event erc20CurrencyRegistered(
|
|
30
|
+
address indexed erc20CurrencyAddress,
|
|
31
|
+
string name,
|
|
32
|
+
string symbol,
|
|
33
|
+
uint8 decimals,
|
|
34
|
+
uint256 timestamp
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
error NotLensModule();
|
|
38
|
+
error ModuleDoesNotSupportType(uint256 moduleType);
|
|
39
|
+
|
|
40
|
+
mapping(address moduleAddress => uint256 moduleTypesBitmap) internal registeredModules;
|
|
41
|
+
|
|
42
|
+
mapping(address erc20CurrencyAddress => bool) internal registeredErc20Currencies;
|
|
43
|
+
|
|
44
|
+
// Modules
|
|
45
|
+
|
|
46
|
+
function verifyModule(address moduleAddress, uint256 moduleType) external returns (bool) {
|
|
47
|
+
registerModule(moduleAddress, moduleType);
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function registerModule(address moduleAddress, uint256 moduleType) public returns (bool registrationWasPerformed) {
|
|
52
|
+
// This will fail if moduleType is out of range for `IModuleRegistry.ModuleType`
|
|
53
|
+
require(
|
|
54
|
+
moduleType > 0 && moduleType <= uint256(type(IModuleRegistry.ModuleType).max),
|
|
55
|
+
'Module Type out of bounds'
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
bool isAlreadyRegisteredAsThatType = registeredModules[moduleAddress] & (1 << moduleType) != 0;
|
|
59
|
+
if (isAlreadyRegisteredAsThatType) {
|
|
60
|
+
return false;
|
|
61
|
+
} else {
|
|
62
|
+
if (!ILensModule(moduleAddress).supportsInterface(LENS_MODULE_INTERFACE_ID)) {
|
|
63
|
+
revert NotLensModule();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
validateModuleSupportsType(moduleAddress, moduleType);
|
|
67
|
+
|
|
68
|
+
string memory metadata = ILensModule(moduleAddress).getModuleMetadataURI();
|
|
69
|
+
emit ModuleRegistered(moduleAddress, moduleType, metadata, block.timestamp);
|
|
70
|
+
registeredModules[moduleAddress] |= (1 << moduleType);
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function validateModuleSupportsType(address moduleAddress, uint256 moduleType) internal view {
|
|
76
|
+
bool supportsInterface;
|
|
77
|
+
if (moduleType == uint256(IModuleRegistry.ModuleType.PUBLICATION_ACTION_MODULE)) {
|
|
78
|
+
supportsInterface = ILensModule(moduleAddress).supportsInterface(
|
|
79
|
+
type(IPublicationActionModule).interfaceId
|
|
80
|
+
);
|
|
81
|
+
} else if (moduleType == uint256(IModuleRegistry.ModuleType.FOLLOW_MODULE)) {
|
|
82
|
+
supportsInterface = ILensModule(moduleAddress).supportsInterface(type(IFollowModule).interfaceId);
|
|
83
|
+
} else if (moduleType == uint256(IModuleRegistry.ModuleType.REFERENCE_MODULE)) {
|
|
84
|
+
supportsInterface = ILensModule(moduleAddress).supportsInterface(type(IReferenceModule).interfaceId);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (!supportsInterface) {
|
|
88
|
+
revert ModuleDoesNotSupportType(moduleType);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function getModuleTypes(address moduleAddress) public view returns (uint256) {
|
|
93
|
+
return registeredModules[moduleAddress];
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function isModuleRegistered(address moduleAddress) external view returns (bool) {
|
|
97
|
+
return registeredModules[moduleAddress] != 0;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function isModuleRegisteredAs(address moduleAddress, uint256 moduleType) public view returns (bool) {
|
|
101
|
+
require(moduleType <= type(uint8).max);
|
|
102
|
+
return registeredModules[moduleAddress] & (1 << moduleType) != 0;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Currencies
|
|
106
|
+
|
|
107
|
+
function verifyErc20Currency(address currencyAddress) external returns (bool) {
|
|
108
|
+
registerErc20Currency(currencyAddress);
|
|
109
|
+
return true;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function registerErc20Currency(address currencyAddress) public returns (bool registrationWasPerformed) {
|
|
113
|
+
bool isAlreadyRegistered = registeredErc20Currencies[currencyAddress];
|
|
114
|
+
if (isAlreadyRegistered) {
|
|
115
|
+
return false;
|
|
116
|
+
} else {
|
|
117
|
+
uint8 decimals = IERC20Metadata(currencyAddress).decimals();
|
|
118
|
+
string memory name = IERC20Metadata(currencyAddress).name();
|
|
119
|
+
string memory symbol = IERC20Metadata(currencyAddress).symbol();
|
|
120
|
+
|
|
121
|
+
emit erc20CurrencyRegistered(currencyAddress, name, symbol, decimals, block.timestamp);
|
|
122
|
+
registeredErc20Currencies[currencyAddress] = true;
|
|
123
|
+
return true;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function isErc20CurrencyRegistered(address currencyAddress) external view returns (bool) {
|
|
128
|
+
return registeredErc20Currencies[currencyAddress];
|
|
129
|
+
}
|
|
130
|
+
}
|