mirror of
https://github.com/lens-protocol/core.git
synced 2026-01-07 21:34:03 -05:00
575 lines
25 KiB
Solidity
575 lines
25 KiB
Solidity
// SPDX-License-Identifier: MIT
|
|
pragma solidity ^0.8.13;
|
|
|
|
import {ForkManagement} from 'script/helpers/ForkManagement.sol';
|
|
import 'forge-std/Script.sol';
|
|
import {LensV2UpgradeContract} from 'contracts/misc/LensV2UpgradeContract.sol';
|
|
import {FollowNFT} from 'contracts/FollowNFT.sol';
|
|
import {LensHandles} from 'contracts/namespaces/LensHandles.sol';
|
|
import {TokenHandleRegistry} from 'contracts/namespaces/TokenHandleRegistry.sol';
|
|
import {TransparentUpgradeableProxy} from '@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol';
|
|
import {Governance} from 'contracts/misc/access/Governance.sol';
|
|
import {LensV2UpgradeContract} from 'contracts/misc/LensV2UpgradeContract.sol';
|
|
import {ProxyAdmin} from 'contracts/misc/access/ProxyAdmin.sol';
|
|
import {LensHubInitializable} from 'contracts/misc/LensHubInitializable.sol';
|
|
import {ILensHub} from 'contracts/interfaces/ILensHub.sol';
|
|
import {ILensHandles} from 'contracts/interfaces/ILensHandles.sol';
|
|
import {ITokenHandleRegistry} from 'contracts/interfaces/ITokenHandleRegistry.sol';
|
|
import {ProfileCreationProxy} from 'contracts/misc/ProfileCreationProxy.sol';
|
|
import {PermissionlessCreator} from 'contracts/misc/PermissionlessCreator.sol';
|
|
import {CreditsFaucet} from 'contracts/misc/CreditsFaucet.sol';
|
|
import {CollectNFT} from 'contracts/modules/act/collect/CollectNFT.sol';
|
|
import {CollectPublicationAction} from 'contracts/modules/act/collect/CollectPublicationAction.sol';
|
|
import {SimpleFeeCollectModule} from 'contracts/modules/act/collect/SimpleFeeCollectModule.sol';
|
|
import {MultirecipientFeeCollectModule} from 'contracts/modules/act/collect/MultirecipientFeeCollectModule.sol';
|
|
import {FeeFollowModule} from './../contracts/modules/follow/FeeFollowModule.sol';
|
|
import {RevertFollowModule} from 'contracts/modules/follow/RevertFollowModule.sol';
|
|
import {DegreesOfSeparationReferenceModule} from 'contracts/modules/reference/DegreesOfSeparationReferenceModule.sol';
|
|
import {FollowerOnlyReferenceModule} from 'contracts/modules/reference/FollowerOnlyReferenceModule.sol';
|
|
import {TokenGatedReferenceModule} from 'contracts/modules/reference/TokenGatedReferenceModule.sol';
|
|
import {Types} from 'contracts/libraries/constants/Types.sol';
|
|
import {ModuleRegistry} from 'contracts/misc/ModuleRegistry.sol';
|
|
import {IModuleRegistry} from 'contracts/interfaces/IModuleRegistry.sol';
|
|
import {LitAccessControl} from 'contracts/misc/access/LitAccessControl.sol';
|
|
import {PublicActProxy} from './../contracts/misc/PublicActProxy.sol';
|
|
import {Governance} from './../contracts/misc/access/Governance.sol';
|
|
import {ProxyAdmin} from './../contracts/misc/access/ProxyAdmin.sol';
|
|
import {ERC2981CollectionRoyalties} from './../contracts/base/ERC2981CollectionRoyalties.sol';
|
|
|
|
import {ArrayHelpers} from 'test/helpers/ArrayHelpers.sol';
|
|
|
|
contract DeployFreshLensV2 is Script, ForkManagement, ArrayHelpers {
|
|
using stdJson for string;
|
|
|
|
string addressesFile = 'addressesV2.txt';
|
|
|
|
bytes32 constant ADMIN_SLOT = bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1);
|
|
string mnemonic;
|
|
|
|
uint256 internal PROFILE_GUARDIAN_COOLDOWN;
|
|
uint256 internal HANDLE_GUARDIAN_COOLDOWN;
|
|
|
|
struct LensAccount {
|
|
uint256 ownerPk;
|
|
address owner;
|
|
uint256 profileId;
|
|
}
|
|
|
|
LensAccount deployer;
|
|
LensAccount governance;
|
|
LensAccount proxyAdmin;
|
|
LensAccount treasury;
|
|
LensAccount profileCreator;
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
ModuleRegistry moduleRegistryImpl;
|
|
TransparentUpgradeableProxy moduleRegistryProxy;
|
|
ModuleRegistry moduleRegistry;
|
|
FollowNFT followNFT;
|
|
LensHubInitializable lensHubImpl;
|
|
TransparentUpgradeableProxy hubProxy;
|
|
ILensHub hub;
|
|
LensHandles handlesImpl;
|
|
TransparentUpgradeableProxy handlesProxy;
|
|
ILensHandles handles;
|
|
TokenHandleRegistry tokenHandleRegistryImpl;
|
|
TransparentUpgradeableProxy tokenHandleRegistryProxy;
|
|
ITokenHandleRegistry tokenHandleRegistry;
|
|
PermissionlessCreator permissionlessCreatorImpl;
|
|
TransparentUpgradeableProxy permissionlessCreatorProxy;
|
|
PermissionlessCreator permissionlessCreator;
|
|
CreditsFaucet creditsFaucet;
|
|
ProfileCreationProxy profileCreationProxy;
|
|
CollectNFT collectNFT;
|
|
CollectPublicationAction collectPublicationActionImpl;
|
|
TransparentUpgradeableProxy collectPublicationActionProxy;
|
|
CollectPublicationAction collectPublicationAction;
|
|
SimpleFeeCollectModule simpleFeeCollectModule;
|
|
MultirecipientFeeCollectModule multirecipientFeeCollectModule;
|
|
FeeFollowModule feeFollowModule;
|
|
RevertFollowModule revertFollowModule;
|
|
DegreesOfSeparationReferenceModule degreesOfSeparationReferenceModule;
|
|
FollowerOnlyReferenceModule followerOnlyReferenceModule;
|
|
TokenGatedReferenceModule tokenGatedReferenceModule;
|
|
LitAccessControl litAccessControlImpl;
|
|
TransparentUpgradeableProxy litAccessControlProxy;
|
|
LitAccessControl litAccessControl;
|
|
PublicActProxy publicActProxy;
|
|
Governance governanceContract;
|
|
ProxyAdmin proxyAdminContract;
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
function loadPrivateKeys() internal {
|
|
if (isEnvSet('MNEMONIC')) {
|
|
mnemonic = vm.envString('MNEMONIC');
|
|
}
|
|
|
|
if (bytes(mnemonic).length == 0) {
|
|
revert('Missing mnemonic');
|
|
}
|
|
|
|
console.log('\n- - - CURRENT BLOCK: ', block.number);
|
|
|
|
(deployer.owner, deployer.ownerPk) = deriveRememberKey(mnemonic, 0);
|
|
console.log('\n- - - DEPLOYER: %s', deployer.owner);
|
|
(governance.owner, governance.ownerPk) = deriveRememberKey(mnemonic, 1);
|
|
console.log('\n- - - GOVERNANCE: %s', governance.owner);
|
|
(proxyAdmin.owner, proxyAdmin.ownerPk) = deriveRememberKey(mnemonic, 2);
|
|
console.log('\n- - - PROXYADMIN: %s', proxyAdmin.owner);
|
|
(treasury.owner, treasury.ownerPk) = deriveRememberKey(mnemonic, 3);
|
|
console.log('\n- - - TREASURY: %s', treasury.owner);
|
|
profileCreator.owner = 0x6C1e1bC39b13f9E0Af9424D76De899203F47755F;
|
|
console.log('\n- - - PROFILE CREATOR: %s', profileCreator.owner);
|
|
}
|
|
|
|
function saveContractAddress(string memory contractName, address deployedAddress) internal {
|
|
// console.log('Saving %s (%s) into addresses under %s environment', contractName, deployedAddress, targetEnv);
|
|
string[] memory inputs = new string[](5);
|
|
inputs[0] = 'node';
|
|
inputs[1] = 'script/helpers/saveAddress.js';
|
|
inputs[2] = targetEnv;
|
|
inputs[3] = contractName;
|
|
inputs[4] = vm.toString(deployedAddress);
|
|
// bytes memory res =
|
|
vm.ffi(inputs);
|
|
// string memory output = abi.decode(res, (string));
|
|
// console.log(output);
|
|
}
|
|
|
|
function saveModule(
|
|
string memory moduleName,
|
|
address moduleAddress,
|
|
string memory lensVersion,
|
|
string memory moduleType
|
|
) internal {
|
|
// console.log('Saving %s (%s) into addresses under %s environment', moduleName, moduleAddress, targetEnv);
|
|
string[] memory inputs = new string[](7);
|
|
inputs[0] = 'node';
|
|
inputs[1] = 'script/helpers/saveAddress.js';
|
|
inputs[2] = targetEnv;
|
|
inputs[3] = moduleName;
|
|
inputs[4] = vm.toString(moduleAddress);
|
|
inputs[5] = lensVersion;
|
|
inputs[6] = moduleType;
|
|
// bytes memory res =
|
|
vm.ffi(inputs);
|
|
// string memory output = abi.decode(res, (string));
|
|
// console.log(output);
|
|
}
|
|
|
|
function saveValue(string memory contractName, string memory str) internal {
|
|
// console.log('Saving %s (%s) into addresses under %s environment', contractName, deployedAddress, targetEnv);
|
|
string[] memory inputs = new string[](5);
|
|
inputs[0] = 'node';
|
|
inputs[1] = 'script/helpers/saveAddress.js';
|
|
inputs[2] = targetEnv;
|
|
inputs[3] = contractName;
|
|
inputs[4] = str;
|
|
// bytes memory res =
|
|
vm.ffi(inputs);
|
|
// string memory output = abi.decode(res, (string));
|
|
// console.log(output);
|
|
}
|
|
|
|
function _logDeployedAddress(address deployedAddress, string memory addressLabel) internal {
|
|
console.log('\n+ + + ', addressLabel, ': ', deployedAddress);
|
|
vm.writeLine(addressesFile, string.concat(addressLabel, string.concat(': ', vm.toString(deployedAddress))));
|
|
saveContractAddress(addressLabel, deployedAddress);
|
|
}
|
|
|
|
function _logDeployedModule(address deployedAddress, string memory moduleName, string memory moduleType) internal {
|
|
string memory lensVersion = 'v2';
|
|
console.log('\n+ + + ', moduleName, ': ', deployedAddress);
|
|
vm.writeLine(addressesFile, string.concat(moduleName, string.concat(': ', vm.toString(deployedAddress))));
|
|
saveModule(moduleName, deployedAddress, lensVersion, moduleType);
|
|
}
|
|
|
|
function loadDeployParams() internal {
|
|
HANDLE_GUARDIAN_COOLDOWN = json.readUint(
|
|
string(abi.encodePacked('.', targetEnv, '.LensHandlesGuardianTimelock'))
|
|
);
|
|
if (HANDLE_GUARDIAN_COOLDOWN == 0) {
|
|
console.log('HANDLE_GUARDIAN_COOLDOWN not set');
|
|
revert('HANDLE_GUARDIAN_COOLDOWN not set');
|
|
}
|
|
console.log('HANDLE_GUARDIAN_COOLDOWN: %s', HANDLE_GUARDIAN_COOLDOWN);
|
|
|
|
PROFILE_GUARDIAN_COOLDOWN = json.readUint(
|
|
string(abi.encodePacked('.', targetEnv, '.LensProfilesGuardianTimelock'))
|
|
);
|
|
if (PROFILE_GUARDIAN_COOLDOWN == 0) {
|
|
console.log('PROFILE_GUARDIAN_COOLDOWN not set');
|
|
revert('PROFILE_GUARDIAN_COOLDOWN not set');
|
|
}
|
|
console.log('PROFILE_GUARDIAN_COOLDOWN: %s', PROFILE_GUARDIAN_COOLDOWN);
|
|
}
|
|
|
|
function _deployCore() internal {
|
|
moduleRegistryImpl = new ModuleRegistry();
|
|
_logDeployedAddress(address(moduleRegistryImpl), 'ModuleRegistryImpl');
|
|
moduleRegistryProxy = new TransparentUpgradeableProxy({
|
|
_logic: address(moduleRegistryImpl),
|
|
admin_: proxyAdmin.owner,
|
|
_data: ''
|
|
});
|
|
moduleRegistry = ModuleRegistry(address(moduleRegistryProxy));
|
|
_logDeployedAddress(address(moduleRegistry), 'ModuleRegistry');
|
|
|
|
uint256 currentDeployerNonce = vm.getNonce(deployer.owner);
|
|
/**
|
|
* FollowNFT (currentDeployerNonce)
|
|
* LensHubInitializable aka LensHubImpl (currentDeployerNonce + 1)
|
|
* TransparentUpgradeableProxy aka LensHubProxy (currentDeployerNonce + 2)
|
|
*/
|
|
uint256 lensHubProxyDeploymentNonce = currentDeployerNonce + 2;
|
|
address expectedLensHubProxyAddress = computeCreateAddress(deployer.owner, lensHubProxyDeploymentNonce);
|
|
|
|
followNFT = new FollowNFT(expectedLensHubProxyAddress);
|
|
_logDeployedAddress(address(followNFT), 'FollowNFT');
|
|
|
|
lensHubImpl = new LensHubInitializable({
|
|
followNFTImpl: address(followNFT),
|
|
collectNFTImpl: address(0), // No needed on a fresh V2 deployment, no publications will have legacy collect.
|
|
moduleRegistry: address(moduleRegistry),
|
|
tokenGuardianCooldown: PROFILE_GUARDIAN_COOLDOWN,
|
|
migrationParams: Types.MigrationParams({
|
|
lensHandlesAddress: address(0),
|
|
tokenHandleRegistryAddress: address(0),
|
|
legacyFeeFollowModule: address(0),
|
|
legacyProfileFollowModule: address(0),
|
|
newFeeFollowModule: address(0)
|
|
}) // No needed on a fresh V2 deployment, no migration needed.
|
|
});
|
|
_logDeployedAddress(address(lensHubImpl), 'LensHubImpl');
|
|
|
|
hubProxy = new TransparentUpgradeableProxy({
|
|
_logic: address(lensHubImpl),
|
|
admin_: proxyAdmin.owner,
|
|
_data: abi.encodeWithSelector(
|
|
LensHubInitializable.initialize.selector,
|
|
'Lens Protocol Profiles', // Name
|
|
'LPP', // Symbol
|
|
governance.owner
|
|
)
|
|
});
|
|
hub = ILensHub(address(hubProxy));
|
|
_logDeployedAddress(address(hub), 'LensHub');
|
|
|
|
handlesImpl = new LensHandles({
|
|
owner: governance.owner,
|
|
lensHub: address(hub),
|
|
tokenGuardianCooldown: HANDLE_GUARDIAN_COOLDOWN
|
|
});
|
|
_logDeployedAddress(address(handlesImpl), 'LensHandlesImpl');
|
|
|
|
handlesProxy = new TransparentUpgradeableProxy({
|
|
_logic: address(handlesImpl),
|
|
admin_: proxyAdmin.owner,
|
|
_data: ''
|
|
});
|
|
_logDeployedAddress(address(handlesProxy), 'LensHandles');
|
|
handles = ILensHandles(address(handlesProxy));
|
|
|
|
tokenHandleRegistryImpl = new TokenHandleRegistry({lensHub: address(hub), lensHandles: address(handles)});
|
|
_logDeployedAddress(address(tokenHandleRegistryImpl), 'TokenHandleRegistryImpl');
|
|
|
|
tokenHandleRegistryProxy = new TransparentUpgradeableProxy({
|
|
_logic: address(tokenHandleRegistryImpl),
|
|
admin_: proxyAdmin.owner,
|
|
_data: ''
|
|
});
|
|
_logDeployedAddress(address(tokenHandleRegistryProxy), 'TokenHandleRegistry');
|
|
tokenHandleRegistry = ITokenHandleRegistry(address(tokenHandleRegistryProxy));
|
|
|
|
permissionlessCreatorImpl = new PermissionlessCreator(
|
|
governance.owner,
|
|
address(hub),
|
|
address(handles),
|
|
address(tokenHandleRegistry)
|
|
);
|
|
permissionlessCreatorProxy = new TransparentUpgradeableProxy({
|
|
_logic: address(permissionlessCreatorImpl),
|
|
admin_: proxyAdmin.owner,
|
|
_data: ''
|
|
});
|
|
permissionlessCreator = PermissionlessCreator(address(permissionlessCreatorProxy));
|
|
_logDeployedAddress(address(permissionlessCreator), 'PermissionlessCreator');
|
|
|
|
if (isTestnet) {
|
|
// Credit faucet is added as provider in the permissionless creator later in this script.
|
|
creditsFaucet = new CreditsFaucet(address(permissionlessCreatorProxy));
|
|
_logDeployedAddress(address(creditsFaucet), 'CreditsFaucet');
|
|
|
|
profileCreationProxy = new ProfileCreationProxy(
|
|
governance.owner,
|
|
address(hub),
|
|
address(handles),
|
|
address(tokenHandleRegistry)
|
|
);
|
|
_logDeployedAddress(address(profileCreationProxy), 'ProfileCreationProxy');
|
|
}
|
|
|
|
currentDeployerNonce = vm.getNonce(deployer.owner);
|
|
/**
|
|
* CollectNFT (currentDeployerNonce)
|
|
* CollectPublicationAction aka CollectPublicationActionImpl (currentDeployerNonce + 1)
|
|
* TransparentUpgradeableProxy aka CollectPublicationActionProxy (currentDeployerNonce + 2)
|
|
*/
|
|
uint256 collectPublicationActionProxyDeploymentNonce = currentDeployerNonce + 2;
|
|
address expectedCollectPublicationActionProxyAddress = computeCreateAddress(
|
|
deployer.owner,
|
|
collectPublicationActionProxyDeploymentNonce
|
|
);
|
|
|
|
collectNFT = new CollectNFT({hub: address(hub), actionModule: expectedCollectPublicationActionProxyAddress});
|
|
_logDeployedAddress(address(collectNFT), 'CollectNFT');
|
|
|
|
collectPublicationActionImpl = new CollectPublicationAction({
|
|
hub: address(hub),
|
|
collectNFTImpl: address(collectNFT),
|
|
moduleOwner: governance.owner
|
|
});
|
|
|
|
collectPublicationActionProxy = new TransparentUpgradeableProxy({
|
|
_logic: address(collectPublicationActionImpl),
|
|
admin_: proxyAdmin.owner,
|
|
_data: ''
|
|
});
|
|
collectPublicationAction = CollectPublicationAction(address(collectPublicationActionProxy));
|
|
_logDeployedModule(address(collectPublicationAction), 'CollectPublicationAction', 'act');
|
|
}
|
|
|
|
function _deployFollowModules() internal {
|
|
feeFollowModule = new FeeFollowModule({
|
|
hub: address(hub),
|
|
moduleRegistry: address(moduleRegistry),
|
|
moduleOwner: governance.owner
|
|
});
|
|
_logDeployedModule(address(feeFollowModule), 'FeeFollowModule', 'follow');
|
|
|
|
revertFollowModule = new RevertFollowModule({moduleOwner: governance.owner});
|
|
_logDeployedModule(address(revertFollowModule), 'RevertFollowModule', 'follow');
|
|
}
|
|
|
|
function _deployCollectModules() internal {
|
|
simpleFeeCollectModule = new SimpleFeeCollectModule({
|
|
hub: address(hub),
|
|
actionModule: address(collectPublicationAction),
|
|
moduleRegistry: address(moduleRegistry),
|
|
moduleOwner: governance.owner
|
|
});
|
|
_logDeployedModule(address(simpleFeeCollectModule), 'SimpleFeeCollectModule', 'collect');
|
|
|
|
multirecipientFeeCollectModule = new MultirecipientFeeCollectModule({
|
|
hub: address(hub),
|
|
actionModule: address(collectPublicationAction),
|
|
moduleRegistry: address(moduleRegistry),
|
|
moduleOwner: governance.owner
|
|
});
|
|
_logDeployedModule(address(multirecipientFeeCollectModule), 'MultirecipientFeeCollectModule', 'collect');
|
|
}
|
|
|
|
function _deployReferenceModules() internal {
|
|
degreesOfSeparationReferenceModule = new DegreesOfSeparationReferenceModule({
|
|
hub: address(hub),
|
|
moduleOwner: governance.owner
|
|
});
|
|
_logDeployedModule(
|
|
address(degreesOfSeparationReferenceModule),
|
|
'DegreesOfSeparationReferenceModule',
|
|
'reference'
|
|
);
|
|
|
|
followerOnlyReferenceModule = new FollowerOnlyReferenceModule({
|
|
hub: address(hub),
|
|
moduleOwner: governance.owner
|
|
});
|
|
_logDeployedModule(address(followerOnlyReferenceModule), 'FollowerOnlyReferenceModule', 'reference');
|
|
}
|
|
|
|
function _deployPeripherialContracts() internal {
|
|
litAccessControlImpl = new LitAccessControl(address(hub), address(collectPublicationAction));
|
|
_logDeployedAddress(address(litAccessControlImpl), 'LitAccessControlImpl');
|
|
|
|
litAccessControlProxy = new TransparentUpgradeableProxy({
|
|
_logic: address(litAccessControlImpl),
|
|
admin_: proxyAdmin.owner,
|
|
_data: ''
|
|
});
|
|
litAccessControl = LitAccessControl(address(litAccessControlProxy));
|
|
_logDeployedAddress(address(litAccessControl), 'LitAccessControl');
|
|
|
|
publicActProxy = new PublicActProxy({lensHub: address(hub)});
|
|
_logDeployedAddress(address(publicActProxy), 'PublicActProxy');
|
|
}
|
|
|
|
// TODO: Use from test/ContractAddresses?
|
|
struct Currency {
|
|
address addy;
|
|
string symbol;
|
|
}
|
|
|
|
function _registerCurrencies() internal {
|
|
console.log('\n[Registering currencies]');
|
|
|
|
Currency[] memory currencies = abi.decode(
|
|
vm.parseJson(json, string(abi.encodePacked('.', targetEnv, '.Currencies'))),
|
|
(Currency[])
|
|
);
|
|
|
|
for (uint256 i = 0; i < currencies.length; i++) {
|
|
moduleRegistry.registerErc20Currency(currencies[i].addy);
|
|
console.log('\n* * * ', currencies[i].symbol, ' registered as currency: ', currencies[i].addy);
|
|
vm.writeLine(
|
|
addressesFile,
|
|
string.concat(currencies[i].symbol, string.concat(': ', vm.toString(currencies[i].addy)))
|
|
);
|
|
}
|
|
}
|
|
|
|
function _registerModules() internal {
|
|
// Follow modules
|
|
moduleRegistry.registerModule(address(feeFollowModule), uint256(IModuleRegistry.ModuleType.FOLLOW_MODULE));
|
|
console.log('\n* * * FeeFollowModule registered as follow module');
|
|
|
|
moduleRegistry.registerModule(address(revertFollowModule), uint256(IModuleRegistry.ModuleType.FOLLOW_MODULE));
|
|
console.log('\n* * * RevertFollowModule registered as follow module');
|
|
|
|
// Reference modules
|
|
moduleRegistry.registerModule(
|
|
address(degreesOfSeparationReferenceModule),
|
|
uint256(IModuleRegistry.ModuleType.REFERENCE_MODULE)
|
|
);
|
|
console.log('\n* * * DegreesOfSeparationReferenceModule registered');
|
|
|
|
moduleRegistry.registerModule(
|
|
address(followerOnlyReferenceModule),
|
|
uint256(IModuleRegistry.ModuleType.REFERENCE_MODULE)
|
|
);
|
|
console.log('\n* * * FollowerOnlyReferenceModule registered');
|
|
|
|
// Collect modules
|
|
moduleRegistry.registerModule(
|
|
address(collectPublicationAction),
|
|
uint256(IModuleRegistry.ModuleType.PUBLICATION_ACTION_MODULE)
|
|
);
|
|
console.log('\n* * * CollectPublicationAction registered as action module');
|
|
|
|
collectPublicationAction.registerCollectModule(address(simpleFeeCollectModule));
|
|
console.log('\n* * * SimpleFeeCollectModule registered as collect module');
|
|
|
|
collectPublicationAction.registerCollectModule(address(multirecipientFeeCollectModule));
|
|
console.log('\n* * * MultirecipientFeeCollectModule registered as collect module');
|
|
}
|
|
|
|
function deploy() internal {
|
|
loadDeployParams();
|
|
|
|
vm.startBroadcast(deployer.ownerPk);
|
|
{
|
|
_deployCore();
|
|
|
|
_deployCollectModules();
|
|
|
|
_deployFollowModules();
|
|
|
|
_deployReferenceModules();
|
|
|
|
_deployPeripherialContracts();
|
|
}
|
|
vm.stopBroadcast();
|
|
|
|
vm.startBroadcast(governance.ownerPk);
|
|
{
|
|
if (isTestnet) {
|
|
console.log('\n[Adding Credits Faucet as Credit Provider]');
|
|
permissionlessCreator.addCreditProvider(address(creditsFaucet));
|
|
|
|
hub.whitelistProfileCreator(address(profileCreationProxy), true);
|
|
console.log('\n* * * Profile creation proxy contract registered as profile creator');
|
|
}
|
|
|
|
_registerCurrencies();
|
|
|
|
hub.whitelistProfileCreator(address(permissionlessCreator), true);
|
|
console.log('\n* * * Permissionless creator contract registered as profile creator');
|
|
|
|
_registerModules();
|
|
|
|
hub.setState(Types.ProtocolState.Unpaused);
|
|
console.log('\n* * * Protocol unpaused');
|
|
|
|
hub.setTreasury(treasury.owner);
|
|
console.log('\n* * * Treasury set to: ', treasury.owner);
|
|
saveContractAddress('Treasury', treasury.owner);
|
|
|
|
uint256 treasuryFee = json.readUint(string(abi.encodePacked('.', targetEnv, '.TreasuryFee')));
|
|
if (treasuryFee > 10_000) {
|
|
revert('Treasury fee exceeding max BPS');
|
|
}
|
|
hub.setTreasuryFee(uint16(treasuryFee));
|
|
console.log('\n* * * Treasury fee set to: ', treasuryFee);
|
|
|
|
uint256 profileRoyaltyFee = json.readUint(string(abi.encodePacked('.', targetEnv, '.ProfileRoyaltyFee')));
|
|
ERC2981CollectionRoyalties(address(hub)).setRoyalty(profileRoyaltyFee);
|
|
|
|
uint256 handleRoyaltyFee = json.readUint(string(abi.encodePacked('.', targetEnv, '.HandleRoyaltyFee')));
|
|
ERC2981CollectionRoyalties(address(handles)).setRoyalty(handleRoyaltyFee);
|
|
|
|
uint256 anonymousProfileId = permissionlessCreator.createProfile({
|
|
createProfileParams: Types.CreateProfileParams({
|
|
to: deployer.owner,
|
|
followModule: address(0),
|
|
followModuleInitData: ''
|
|
}),
|
|
delegatedExecutors: new address[](0)
|
|
});
|
|
|
|
vm.writeLine(addressesFile, string.concat('AnonymousProfileId :', vm.toString(anonymousProfileId)));
|
|
console.log('\n* * * Anonymous profile created with id: ', anonymousProfileId);
|
|
saveValue('AnonymousProfileId', vm.toString(anonymousProfileId));
|
|
|
|
// TODO: Add PublicActProxy as a delegatedExecutor of anonymousProfileId
|
|
}
|
|
vm.stopBroadcast();
|
|
|
|
vm.startBroadcast(deployer.ownerPk);
|
|
{
|
|
// Deploy governance and proxy-admin controllable-by-contract contracts, and transfer ownership.
|
|
governanceContract = new Governance(address(hub), governance.owner);
|
|
_logDeployedAddress(address(governanceContract), 'GovernanceContract');
|
|
_logDeployedAddress(governance.owner, 'GovernanceContractAdmin');
|
|
|
|
proxyAdminContract = new ProxyAdmin(address(hub), address(0), proxyAdmin.owner);
|
|
_logDeployedAddress(address(proxyAdminContract), 'ProxyAdminContract');
|
|
_logDeployedAddress(proxyAdmin.owner, 'ProxyAdminContractAdmin');
|
|
}
|
|
vm.stopBroadcast();
|
|
|
|
vm.startBroadcast(governance.ownerPk);
|
|
{
|
|
hub.setGovernance(address(governanceContract));
|
|
// hub.setEmergencyAdmin(governance.owner); // TODO: WHO ?
|
|
}
|
|
vm.stopBroadcast();
|
|
|
|
vm.startBroadcast(proxyAdmin.ownerPk);
|
|
{
|
|
hubProxy.changeAdmin(address(proxyAdminContract));
|
|
}
|
|
vm.stopBroadcast();
|
|
}
|
|
|
|
function run(string memory targetEnv_) external {
|
|
targetEnv = targetEnv_;
|
|
loadJson();
|
|
checkNetworkParams();
|
|
loadPrivateKeys();
|
|
deploy();
|
|
// _writeBackendEnvFile();
|
|
// _interact();
|
|
}
|
|
}
|