From 842d7bde39e76a2e2d3e89a39e652a983a5bfb46 Mon Sep 17 00:00:00 2001 From: vicnaum Date: Thu, 18 Apr 2024 11:01:21 +0200 Subject: [PATCH] misc: deployment script for mintFeeModule --- script/DeployMintFeeModule.s.sol | 229 +++++++++++++++++++++++++++++++ 1 file changed, 229 insertions(+) create mode 100644 script/DeployMintFeeModule.s.sol diff --git a/script/DeployMintFeeModule.s.sol b/script/DeployMintFeeModule.s.sol new file mode 100644 index 0000000..920dbe8 --- /dev/null +++ b/script/DeployMintFeeModule.s.sol @@ -0,0 +1,229 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.13; + +import {ForkManagement} from 'script/helpers/ForkManagement.sol'; +import 'forge-std/Script.sol'; +import {ProtocolSharedRevenueDistribution, ProtocolSharedRevenueMinFeeMintModule} from 'contracts/modules/act/collect/ProtocolSharedRevenueMinFeeMintModule.sol'; +import {TransparentUpgradeableProxy} from '@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol'; +import {CollectPublicationAction} from 'contracts/modules/act/collect/CollectPublicationAction.sol'; +import {IModuleRegistry} from 'contracts/interfaces/IModuleRegistry.sol'; +import {LibString} from 'solady/utils/LibString.sol'; + +contract DeployMintFeeModule is Script, ForkManagement { + using stdJson for string; + + struct LensAccount { + uint256 ownerPk; + address owner; + uint256 profileId; + } + + LensAccount _deployer; + LensAccount governance; + + string mnemonic; + + address lensHub; + address collectPublicationAction; + address moduleRegistry; + address governanceOwner; + address proxyAdminContractAdmin; + address bonsai; + + ProtocolSharedRevenueMinFeeMintModule mintFeeModule; + + function loadPrivateKeys() internal { + if (isEnvSet('MNEMONIC')) { + mnemonic = vm.envString('MNEMONIC'); + } + + if (bytes(mnemonic).length == 0) { + revert('Missing mnemonic'); + } + + console.log('\n'); + + (_deployer.owner, _deployer.ownerPk) = deriveRememberKey(mnemonic, 0); + console.log('Deployer address: %s', address(_deployer.owner)); + + (governance.owner, governance.ownerPk) = deriveRememberKey(mnemonic, 1); + console.log('\n- - - GOVERNANCE: %s', governance.owner); + + console.log('\n'); + + console.log('Current block:', block.number); + } + + struct Currency { + address addy; + string symbol; + } + + // TODO: Use from test/ContractAddresses + struct Module { + address addy; + string name; + } + + // TODO: Move this somewhere common (also in UpgradeForkTest) + function findModuleHelper( + Module[] memory modules, + string memory moduleNameToFind + ) internal pure returns (Module memory) { + for (uint256 i = 0; i < modules.length; i++) { + if (LibString.eq(modules[i].name, moduleNameToFind)) { + return modules[i]; + } + } + revert('Module not found'); + } + + 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 _logDeployedModule(address deployedAddress, string memory moduleName, string memory moduleType) internal { + string memory lensVersion = 'v2'; + console.log('\n+ + + ', moduleName, ': ', deployedAddress); + saveModule(moduleName, deployedAddress, lensVersion, moduleType); + } + + function loadBaseAddresses() internal override { + lensHub = json.readAddress(string(abi.encodePacked('.', targetEnv, '.LensHub'))); + vm.label(lensHub, 'LensHub'); + console.log('Lens Hub Proxy: %s', lensHub); + + Module[] memory actModules = abi.decode( + vm.parseJson(json, string(abi.encodePacked('.', targetEnv, '.Modules.v2.act'))), + (Module[]) + ); + collectPublicationAction = findModuleHelper(actModules, 'CollectPublicationAction').addy; + vm.label(collectPublicationAction, 'CollectPublicationAction'); + console.log('CollectPublicationAction: %s', collectPublicationAction); + + moduleRegistry = json.readAddress(string(abi.encodePacked('.', targetEnv, '.ModuleRegistry'))); + vm.label(moduleRegistry, 'ModuleRegistry'); + console.log('ModuleRegistry: %s', moduleRegistry); + + governanceOwner = json.readAddress(string(abi.encodePacked('.', targetEnv, '.GovernanceContractAdmin'))); + vm.label(governanceOwner, 'GovernanceOwner'); + console.log('Governance Owner: %s', governanceOwner); + + proxyAdminContractAdmin = json.readAddress( + string(abi.encodePacked('.', targetEnv, '.ProxyAdminContractAdmin')) + ); + vm.label(proxyAdminContractAdmin, 'ProxyAdminContractAdmin'); + console.log('Proxy Admin Contract Admin: %s', proxyAdminContractAdmin); + + Currency[] memory currencies = abi.decode( + vm.parseJson(json, string(abi.encodePacked('.', targetEnv, '.Currencies'))), + (Currency[]) + ); + + for (uint256 i = 0; i < currencies.length; i++) { + if (LibString.eq(currencies[i].symbol, 'BONSAI')) { + bonsai = currencies[i].addy; + } + } + vm.label(bonsai, 'BONSAI'); + console.log('BONSAI: %s', bonsai); + } + + function run(string memory targetEnv_) external { + targetEnv = targetEnv_; + loadJson(); + checkNetworkParams(); + loadBaseAddresses(); + loadPrivateKeys(); + deploy(); + moduleRegistryActions(); + governanceActions(); + } + + function deploy() internal { + vm.startBroadcast(_deployer.ownerPk); + { + address mintFeeModuleImpl = address( + new ProtocolSharedRevenueMinFeeMintModule({ + hub: lensHub, + actionModule: collectPublicationAction, + moduleRegistry: moduleRegistry, + moduleOwner: governanceOwner + }) + ); + console.log( + '\n* * * Deployed ProtocolSharedRevenueMinFeeMintModule implementation at: ', + mintFeeModuleImpl + ); + console.log('With parameters:'); + console.log('\tHub: ', lensHub); + console.log('\tAction Module: ', collectPublicationAction); + console.log('\tModule Registry: ', moduleRegistry); + console.log('\tModule Owner: ', governanceOwner); + + mintFeeModule = ProtocolSharedRevenueMinFeeMintModule( + address( + new TransparentUpgradeableProxy( + mintFeeModuleImpl, + proxyAdminContractAdmin, + abi.encodeCall(mintFeeModule.initialize, (governanceOwner)) + ) + ) + ); + + _logDeployedModule(address(mintFeeModule), 'ProtocolSharedRevenueMinFeeMintModule', 'collect'); + } + vm.stopBroadcast(); + } + + function moduleRegistryActions() internal { + vm.startBroadcast(_deployer.ownerPk); + IModuleRegistry(moduleRegistry).registerErc20Currency(bonsai); + console.log('\n* * * BONSAI registered as currency: ', bonsai); + + CollectPublicationAction(collectPublicationAction).registerCollectModule(address(mintFeeModule)); + console.log('\n* * * MintFeeModule registered as collect module in CollectPublicationAction'); + vm.stopBroadcast(); + } + + function governanceActions() internal { + console.log('Owner of mintFeeModule:', mintFeeModule.owner()); + vm.startBroadcast(governance.ownerPk); + { + mintFeeModule.setMintFeeParams(bonsai, 10 ether); + console.log('\n* * * MintFeeModule mint fee set to 10 BONSAI'); + + mintFeeModule.setProtocolSharedRevenueDistribution( + ProtocolSharedRevenueDistribution({ + creatorSplit: 5000, + protocolSplit: 2000, + creatorClientSplit: 1500, + executorClientSplit: 1500 + }) + ); + console.log('\n* * * MintFeeModule revenue distribution set to:'); + console.log('\tCreator: 50%'); + console.log('\tProtocol: 20%'); + console.log('\tCreator Client: 15%'); + console.log('\tExecutor Client: 15%'); + } + vm.stopBroadcast(); + } +}