View Source: contracts/proxy/modules/ModulesProxyRegistry.sol
↗ Extends: IModulesProxyRegistry, ProxyOwnable ↘ Derived Contracts: ModulesProxy
Constants & Variables
bytes32 internal constant KEY_IMPLEMENTATION;
- constructor()
- addModule(address _impl)
- addModules(address[] _implementations)
- replaceModule(address _oldModuleImpl, address _newModuleImpl)
- replaceModules(address[] _implementationsFrom, address[] _implementationsTo)
- removeModule(address _impl)
- removeModules(address[] _implementations)
- getFuncImplementation(bytes4 _sig)
- canAddModule(address _impl)
- canNotAddModules(address[] _implementations)
- checkClashingFuncSelectors(address _newModule)
- isModuleRegistered(address _impl)
- _getFirstRegisteredModuleAddress(address _impl)
- _getFuncImplementation(bytes4 _sig)
- _addModule(address _impl)
- _addModules(address[] _implementations)
- _removeModule(address _impl)
- _removeModules(address[] _implementations)
- _replaceModule(address _oldModuleImpl, address _newModuleImpl)
- _setModuleFuncImplementation(bytes4 _sig, address _impl)
- _isFuncClashingWithProxyFunctions(bytes4 _sig)
- _canAddModule(address _impl)
- _getFunctionsList()
Constructor is internal to make contract abstract
function () internal nonpayable
Source Code
constructor() internal {
// abstract
}
⤾ overrides IModulesProxyRegistry.addModule
Add module functions. Overriding functions is not allowed. To replace modules use replaceModule function.
function addModule(address _impl) external nonpayable onlyProxyOwner
Arguments
Name | Type | Description |
---|---|---|
_impl | address | Module implementation address |
Source Code
function addModule(address _impl) external onlyProxyOwner {
_addModule(_impl);
}
⤾ overrides IModulesProxyRegistry.addModules
Add modules functions.
function addModules(address[] _implementations) external nonpayable onlyProxyOwner
Arguments
Name | Type | Description |
---|---|---|
_implementations | address[] | Modules implementation addresses |
Source Code
function addModules(address[] calldata _implementations) external onlyProxyOwner {
_addModules(_implementations);
}
⤾ overrides IModulesProxyRegistry.replaceModule
Replace module - remove the previous, add the new one
function replaceModule(address _oldModuleImpl, address _newModuleImpl) external nonpayable onlyProxyOwner
Arguments
Name | Type | Description |
---|---|---|
_oldModuleImpl | address | Module implementation address to remove |
_newModuleImpl | address | Module implementation address to add |
Source Code
function replaceModule(address _oldModuleImpl, address _newModuleImpl)
external
onlyProxyOwner
{
_replaceModule(_oldModuleImpl, _newModuleImpl);
}
⤾ overrides IModulesProxyRegistry.replaceModules
Add modules functions.
function replaceModules(address[] _implementationsFrom, address[] _implementationsTo) external nonpayable onlyProxyOwner
Arguments
Name | Type | Description |
---|---|---|
_implementationsFrom | address[] | Modules to replace |
_implementationsTo | address[] | Replacing modules |
Source Code
function replaceModules(
address[] calldata _implementationsFrom,
address[] calldata _implementationsTo
) external onlyProxyOwner {
require(
_implementationsFrom.length == _implementationsTo.length,
"ModulesProxyRegistry::replaceModules: arrays sizes must be equal"
); //MR10
// because the order of addresses is arbitrary, all modules are removed first to avoid collisions
_removeModules(_implementationsFrom);
_addModules(_implementationsTo);
}
⤾ overrides IModulesProxyRegistry.removeModule
To disable module - set all its functions implementation to address(0)
function removeModule(address _impl) external nonpayable onlyProxyOwner
Arguments
Name | Type | Description |
---|---|---|
_impl | address | implementation address |
Source Code
function removeModule(address _impl) external onlyProxyOwner {
_removeModule(_impl);
}
⤾ overrides IModulesProxyRegistry.removeModules
Add modules functions.
function removeModules(address[] _implementations) external nonpayable onlyProxyOwner
Arguments
Name | Type | Description |
---|---|---|
_implementations | address[] | Modules implementation addresses |
Source Code
function removeModules(address[] calldata _implementations) external onlyProxyOwner {
_removeModules(_implementations);
}
⤾ overrides IModulesProxyRegistry.getFuncImplementation
function getFuncImplementation(bytes4 _sig) external view
returns(address)
Arguments
Name | Type | Description |
---|---|---|
_sig | bytes4 | Function signature to get impmementation address for |
Returns
Function's contract implelementation address
Source Code
function getFuncImplementation(bytes4 _sig) external view returns (address) {
return _getFuncImplementation(_sig);
}
⤾ overrides IModulesProxyRegistry.canAddModule
Verifies if no functions from the module already registered
function canAddModule(address _impl) external view
returns(bool)
Arguments
Name | Type | Description |
---|---|---|
_impl | address | Module implementation address to verify |
Returns
True if module can be added
Source Code
function canAddModule(address _impl) external view returns (bool) {
return _canAddModule(_impl);
}
⤾ overrides IModulesProxyRegistry.canNotAddModules
Multiple modules verification if there are functions from the modules already registered
function canNotAddModules(address[] _implementations) public view
returns(address[])
Arguments
Name | Type | Description |
---|---|---|
_implementations | address[] | modules implementation addresses to verify |
Returns
addresses of registered modules
Source Code
function canNotAddModules(address[] memory _implementations)
public
view
returns (address[] memory)
{
for (uint256 i = 0; i < _implementations.length; i++) {
if (_canAddModule(_implementations[i])) {
delete _implementations[i];
}
}
return _implementations;
}
⤾ overrides IModulesProxyRegistry.checkClashingFuncSelectors
Used externally to verify module being added for clashing
function checkClashingFuncSelectors(address _newModule) external view
returns(clashingModules address[], clashingModulesFuncSelectors bytes4[], clashingProxyRegistryFuncSelectors bytes4[])
Arguments
Name | Type | Description |
---|---|---|
_newModule | address | module implementation which functions to verify |
Returns
Clashing functions signatures and corresponding modules (contracts) addresses
Source Code
function checkClashingFuncSelectors(address _newModule)
external
view
returns (
address[] memory clashingModules,
bytes4[] memory clashingModulesFuncSelectors,
bytes4[] memory clashingProxyRegistryFuncSelectors
)
{
require(
_newModule.isContract(),
"ModulesProxyRegistry::checkClashingFuncSelectors: address is not a contract"
); //MR06
bytes4[] memory newModuleFunctions = IFunctionsList(_newModule).getFunctionsList();
bytes4[] memory proxyRegistryFunctions = _getFunctionsList(); //registry functions list
uint256 clashingProxyRegistryFuncsSize;
uint256 clashingArraySize;
uint256 clashingArrayIndex;
uint256 clashingRegistryArrayIndex;
for (uint256 i = 0; i < newModuleFunctions.length; i++) {
address funcImpl = _getFuncImplementation(newModuleFunctions[i]);
if (funcImpl != address(0) && funcImpl != _newModule) {
clashingArraySize++;
} else if (_isFuncClashingWithProxyFunctions(newModuleFunctions[i]))
clashingProxyRegistryFuncsSize++;
}
clashingModules = new address[](clashingArraySize);
clashingModulesFuncSelectors = new bytes4[](clashingArraySize);
clashingProxyRegistryFuncSelectors = new bytes4[](clashingProxyRegistryFuncsSize);
if (clashingArraySize == 0 && clashingProxyRegistryFuncsSize == 0)
//return empty arrays
return (
clashingModules,
clashingModulesFuncSelectors,
clashingProxyRegistryFuncSelectors
);
for (uint256 i = 0; i < newModuleFunctions.length; i++) {
address funcImpl = _getFuncImplementation(newModuleFunctions[i]);
if (funcImpl != address(0)) {
clashingModules[clashingArrayIndex] = funcImpl;
clashingModulesFuncSelectors[clashingArrayIndex] = newModuleFunctions[i];
clashingArrayIndex++;
}
for (uint256 j = 0; j < proxyRegistryFunctions.length; j++) {
//ModulesProxyRegistry has a clashing function selector
if (proxyRegistryFunctions[j] == newModuleFunctions[i]) {
clashingProxyRegistryFuncSelectors[
clashingRegistryArrayIndex
] = proxyRegistryFunctions[j];
clashingRegistryArrayIndex++;
}
}
}
}
function isModuleRegistered(address _impl) external view
returns(bool)
Arguments
Name | Type | Description |
---|---|---|
_impl | address | deployment address to verify |
Returns
true if _impl address is a registered module
Source Code
function isModuleRegistered(address _impl) external view returns (bool) {
return _getFirstRegisteredModuleAddress(_impl) == _impl;
}
function _getFirstRegisteredModuleAddress(address _impl) internal view
returns(address)
Arguments
Name | Type | Description |
---|---|---|
_impl | address |
Source Code
function _getFirstRegisteredModuleAddress(address _impl) internal view returns (address) {
require(
_impl.isContract(),
"ModulesProxyRegistry::_getRegisteredModuleAddress: address is not a contract"
);
bytes4[] memory functions = IFunctionsList(_impl).getFunctionsList();
for (uint256 i = 0; i < functions.length; i++) {
address _moduleImpl = _getFuncImplementation(functions[i]);
if (_moduleImpl != address(0)) {
return (_moduleImpl);
}
}
return address(0);
}
function _getFuncImplementation(bytes4 _sig) internal view
returns(address)
Arguments
Name | Type | Description |
---|---|---|
_sig | bytes4 |
Source Code
function _getFuncImplementation(bytes4 _sig) internal view returns (address) {
//TODO: add querying Registry for logic address and then delegate call to it OR use proxy memory slots like this:
bytes32 key = keccak256(abi.encode(_sig, KEY_IMPLEMENTATION));
address implementation;
assembly {
implementation := sload(key)
}
return implementation;
}
function _addModule(address _impl) internal nonpayable
Arguments
Name | Type | Description |
---|---|---|
_impl | address |
Source Code
function _addModule(address _impl) internal {
require(_impl.isContract(), "ModulesProxyRegistry::_addModule: address is not a contract"); //MR01
bytes4[] memory functions = IFunctionsList(_impl).getFunctionsList();
for (uint256 i = 0; i < functions.length; i++) {
require(
_getFuncImplementation(functions[i]) == address(0),
"ModulesProxyRegistry::_addModule: function already registered - use replaceModule function"
); //MR02
require(functions[i] != bytes4(0), "does not allow empty function id"); // MR03
require(
!_isFuncClashingWithProxyFunctions(functions[i]),
"ModulesProxyRegistry::_addModule: has a function with the same signature"
); //MR09
_setModuleFuncImplementation(functions[i], _impl);
}
emit AddModule(_impl);
}
function _addModules(address[] _implementations) internal nonpayable
Arguments
Name | Type | Description |
---|---|---|
_implementations | address[] |
Source Code
function _addModules(address[] memory _implementations) internal {
for (uint256 i = 0; i < _implementations.length; i++) {
_addModule(_implementations[i]);
}
}
function _removeModule(address _impl) internal nonpayable onlyProxyOwner
Arguments
Name | Type | Description |
---|---|---|
_impl | address |
Source Code
function _removeModule(address _impl) internal onlyProxyOwner {
require(
_impl.isContract(),
"ModulesProxyRegistry::_removeModule: address is not a contract"
); //MR07
bytes4[] memory functions = IFunctionsList(_impl).getFunctionsList();
for (uint256 i = 0; i < functions.length; i++)
_setModuleFuncImplementation(functions[i], address(0));
emit RemoveModule(_impl);
}
function _removeModules(address[] _implementations) internal nonpayable
Arguments
Name | Type | Description |
---|---|---|
_implementations | address[] |
Source Code
function _removeModules(address[] memory _implementations) internal {
for (uint256 i = 0; i < _implementations.length; i++) {
_removeModule(_implementations[i]);
}
}
function _replaceModule(address _oldModuleImpl, address _newModuleImpl) internal nonpayable
Arguments
Name | Type | Description |
---|---|---|
_oldModuleImpl | address | |
_newModuleImpl | address |
Source Code
function _replaceModule(address _oldModuleImpl, address _newModuleImpl) internal {
if (_oldModuleImpl != _newModuleImpl) {
require(
_newModuleImpl.isContract(),
"ModulesProxyRegistry::_replaceModule - _newModuleImpl is not a contract"
); //MR03
require(
_oldModuleImpl.isContract(),
"ModulesProxyRegistry::_replaceModule - _oldModuleImpl is not a contract"
); //MR04
_removeModule(_oldModuleImpl);
_addModule(_newModuleImpl);
emit ReplaceModule(_oldModuleImpl, _newModuleImpl);
}
}
function _setModuleFuncImplementation(bytes4 _sig, address _impl) internal nonpayable
Arguments
Name | Type | Description |
---|---|---|
_sig | bytes4 | |
_impl | address |
Source Code
function _setModuleFuncImplementation(bytes4 _sig, address _impl) internal {
emit SetModuleFuncImplementation(_sig, _getFuncImplementation(_sig), _impl);
bytes32 key = keccak256(abi.encode(_sig, KEY_IMPLEMENTATION));
assembly {
sstore(key, _impl)
}
}
function _isFuncClashingWithProxyFunctions(bytes4 _sig) internal pure
returns(bool)
Arguments
Name | Type | Description |
---|---|---|
_sig | bytes4 |
Source Code
function _isFuncClashingWithProxyFunctions(bytes4 _sig) internal pure returns (bool) {
bytes4[] memory functionList = _getFunctionsList();
for (uint256 i = 0; i < functionList.length; i++) {
if (_sig == functionList[i])
//ModulesProxyRegistry has function with the same id
return true;
}
return false;
}
function _canAddModule(address _impl) internal view
returns(bool)
Arguments
Name | Type | Description |
---|---|---|
_impl | address |
Source Code
function _canAddModule(address _impl) internal view returns (bool) {
require(
_impl.isContract(),
"ModulesProxyRegistry::_canAddModule: address is not a contract"
); //MR06
bytes4[] memory functions = IFunctionsList(_impl).getFunctionsList();
for (uint256 i = 0; i < functions.length; i++)
if (_getFuncImplementation(functions[i]) != address(0)) return (false);
return true;
}
function _getFunctionsList() internal pure
returns(bytes4[])
Source Code
function _getFunctionsList() internal pure returns (bytes4[] memory) {
bytes4[] memory functionList = new bytes4[](13);
functionList[0] = this.getFuncImplementation.selector;
functionList[1] = this.addModule.selector;
functionList[2] = this.addModules.selector;
functionList[3] = this.removeModule.selector;
functionList[4] = this.removeModules.selector;
functionList[5] = this.replaceModule.selector;
functionList[6] = this.replaceModules.selector;
functionList[7] = this.canAddModule.selector;
functionList[8] = this.canNotAddModules.selector;
functionList[9] = this.setProxyOwner.selector;
functionList[10] = this.getProxyOwner.selector;
functionList[11] = this.checkClashingFuncSelectors.selector;
functionList[12] = this.isModuleRegistered.selector;
return functionList;
}
- Address
- Administered
- AdminRole
- AdvancedToken
- AdvancedTokenStorage
- Affiliates
- AffiliatesEvents
- ApprovalReceiver
- BProPriceFeed
- CheckpointsShared
- Constants
- Context
- DevelopmentFund
- DummyContract
- EnumerableAddressSet
- EnumerableBytes32Set
- EnumerableBytes4Set
- ERC20
- ERC20Detailed
- ErrorDecoder
- Escrow
- EscrowReward
- FeedsLike
- FeesEvents
- FeeSharingCollector
- FeeSharingCollectorProxy
- FeeSharingCollectorStorage
- FeesHelper
- FourYearVesting
- FourYearVestingFactory
- FourYearVestingLogic
- FourYearVestingStorage
- GenericTokenSender
- GovernorAlpha
- GovernorVault
- IApproveAndCall
- IChai
- IContractRegistry
- IConverterAMM
- IERC1820Registry
- IERC20_
- IERC20
- IERC777
- IERC777Recipient
- IERC777Sender
- IFeeSharingCollector
- IFourYearVesting
- IFourYearVestingFactory
- IFunctionsList
- ILiquidityMining
- ILiquidityPoolV1Converter
- ILoanPool
- ILoanToken
- ILoanTokenLogicBeacon
- ILoanTokenLogicModules
- ILoanTokenLogicProxy
- ILoanTokenModules
- ILoanTokenWRBTC
- ILockedSOV
- IMoCState
- IModulesProxyRegistry
- Initializable
- InterestUser
- IPot
- IPriceFeeds
- IPriceFeedsExt
- IProtocol
- IRSKOracle
- ISovryn
- ISovrynSwapNetwork
- IStaking
- ISwapsImpl
- ITeamVesting
- ITimelock
- IV1PoolOracle
- IVesting
- IVestingFactory
- IVestingRegistry
- IWrbtc
- IWrbtcERC20
- LenderInterestStruct
- LiquidationHelper
- LiquidityMining
- LiquidityMiningConfigToken
- LiquidityMiningProxy
- LiquidityMiningStorage
- LoanClosingsEvents
- LoanClosingsLiquidation
- LoanClosingsRollover
- LoanClosingsShared
- LoanClosingsWith
- LoanClosingsWithoutInvariantCheck
- LoanInterestStruct
- LoanMaintenance
- LoanMaintenanceEvents
- LoanOpenings
- LoanOpeningsEvents
- LoanParamsStruct
- LoanSettings
- LoanSettingsEvents
- LoanStruct
- LoanToken
- LoanTokenBase
- LoanTokenLogicBeacon
- LoanTokenLogicLM
- LoanTokenLogicProxy
- LoanTokenLogicStandard
- LoanTokenLogicStorage
- LoanTokenLogicWrbtc
- LoanTokenSettingsLowerAdmin
- LockedSOV
- MarginTradeStructHelpers
- Medianizer
- ModuleCommonFunctionalities
- ModulesCommonEvents
- ModulesProxy
- ModulesProxyRegistry
- MultiSigKeyHolders
- MultiSigWallet
- Mutex
- Objects
- OrderStruct
- OrigingVestingCreator
- OriginInvestorsClaim
- Ownable
- Pausable
- PausableOz
- PreviousLoanToken
- PreviousLoanTokenSettingsLowerAdmin
- PriceFeedRSKOracle
- PriceFeeds
- PriceFeedsLocal
- PriceFeedsMoC
- PriceFeedV1PoolOracle
- ProtocolAffiliatesInterface
- ProtocolLike
- ProtocolSettings
- ProtocolSettingsEvents
- ProtocolSettingsLike
- ProtocolSwapExternalInterface
- ProtocolTokenUser
- Proxy
- ProxyOwnable
- ReentrancyGuard
- RewardHelper
- RSKAddrValidator
- SafeERC20
- SafeMath
- SafeMath96
- setGet
- SharedReentrancyGuard
- SignedSafeMath
- SOV
- sovrynProtocol
- StakingAdminModule
- StakingGovernanceModule
- StakingInterface
- StakingProxy
- StakingRewards
- StakingRewardsProxy
- StakingRewardsStorage
- StakingShared
- StakingStakeModule
- StakingStorageModule
- StakingStorageShared
- StakingVestingModule
- StakingWithdrawModule
- State
- SwapsEvents
- SwapsExternal
- SwapsImplLocal
- SwapsImplSovrynSwap
- SwapsUser
- TeamVesting
- Timelock
- TimelockHarness
- TimelockInterface
- TokenSender
- UpgradableProxy
- USDTPriceFeed
- Utils
- VaultController
- Vesting
- VestingCreator
- VestingFactory
- VestingLogic
- VestingRegistry
- VestingRegistry2
- VestingRegistry3
- VestingRegistryLogic
- VestingRegistryProxy
- VestingRegistryStorage
- VestingStorage
- WeightedStakingModule
- WRBTC