From 4bb9f0167fe203ef944a028ab89ad3168e55da56 Mon Sep 17 00:00:00 2001 From: "juancito.eth" Date: Mon, 30 Oct 2023 21:39:11 -0300 Subject: [PATCH] test: add followModule migration tests --- test/migrations/Migrations.t.sol | 89 +++++++++++++++++++++++++++++++- 1 file changed, 88 insertions(+), 1 deletion(-) diff --git a/test/migrations/Migrations.t.sol b/test/migrations/Migrations.t.sol index 023218a..406beaa 100644 --- a/test/migrations/Migrations.t.sol +++ b/test/migrations/Migrations.t.sol @@ -12,10 +12,12 @@ import {TokenHandleRegistry} from 'contracts/namespaces/TokenHandleRegistry.sol' import {IERC721} from '@openzeppelin/contracts/token/ERC721/IERC721.sol'; import {IERC721Enumerable} from '@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol'; import {LensHubInitializable} from 'contracts/misc/LensHubInitializable.sol'; -import {MigrationLib} from 'contracts/libraries/MigrationLib.sol'; +import {LensV2Migration} from 'contracts/misc/LensV2Migration.sol'; +import {MigrationLib, ILegacyFeeFollowModule} from 'contracts/libraries/MigrationLib.sol'; import {Events} from 'contracts/libraries/constants/Events.sol'; import {Types} from 'contracts/libraries/constants/Types.sol'; import {StorageLib} from 'contracts/libraries/StorageLib.sol'; +import {IFollowModule} from 'contracts/interfaces/IFollowModule.sol'; import 'test/base/BaseTest.t.sol'; contract MigrationsTest is BaseTest { @@ -626,6 +628,70 @@ contract MigrationsTestNonFork is BaseTest { hub.batchMigrateFollowers(followerProfileIds, idOfProfileFollowed, followTokenIds); } + function testMigrateFollowModules_IfProfileHasLegacyFeeFollowModule() public notFork { + uint256 profileId = 69; + address legacyFeeFollowModule = makeAddr('legacyFeeFollowModule'); + address newFeeFollowModule = makeAddr('newFeeFollowModule'); + + Types.MigrationParams memory migrationParams = Types.MigrationParams({ + lensHandlesAddress: makeAddr('lensHandlesAddress'), + tokenHandleRegistryAddress: makeAddr('tokenHandleRegistryAddress'), + legacyFeeFollowModule: legacyFeeFollowModule, + legacyProfileFollowModule: makeAddr('legacyProfileFollowModule'), + newFeeFollowModule: newFeeFollowModule, + migrationAdmin: makeAddr('migrationAdmin') + }); + LensV2Migration migration = new LensV2Migration(migrationParams); + + _mockProfileFollowModule(profileId, legacyFeeFollowModule, address(migration)); + + bytes memory feeData = abi.encodeCall(ILegacyFeeFollowModule.getProfileData, (profileId)); + bytes memory feeRetData = abi.encode( + ILegacyFeeFollowModule.ProfileData({currency: address(0), amount: 0, recipient: address(0)}) + ); + vm.mockCall(address(legacyFeeFollowModule), 0, feeData, feeRetData); + + bytes memory initializeData = abi.encodeCall( + IFollowModule.initializeFollowModule, + (profileId, address(0), feeRetData) + ); + bytes memory initializeRetData = abi.encode(''); + vm.mockCall(address(newFeeFollowModule), 0, initializeData, initializeRetData); + + vm.expectEmit(true, false, false, true, address(migration)); + emit Events.FollowModuleSet(profileId, newFeeFollowModule, feeRetData, '', address(0), block.timestamp); + + migration.batchMigrateFollowModules(_toUint256Array(profileId)); + + address updatedFollowModule = _getFollowModule(profileId, address(migration)); + assertEq(updatedFollowModule, newFeeFollowModule); + } + + function testMigrateFollowModules_DeletesFollowModule_IfProfileHasLegacyProfileFollowModule() public notFork { + uint256 profileId = 69; + address legacyProfileFollowModule = makeAddr('legacyProfileFollowModule'); + + Types.MigrationParams memory migrationParams = Types.MigrationParams({ + lensHandlesAddress: makeAddr('lensHandlesAddress'), + tokenHandleRegistryAddress: makeAddr('tokenHandleRegistryAddress'), + legacyFeeFollowModule: makeAddr('legacyFeeFollowModule'), + legacyProfileFollowModule: legacyProfileFollowModule, + newFeeFollowModule: makeAddr('newFeeFollowModule'), + migrationAdmin: makeAddr('migrationAdmin') + }); + LensV2Migration migration = new LensV2Migration(migrationParams); + + _mockProfileFollowModule(profileId, legacyProfileFollowModule, address(migration)); + + vm.expectEmit(true, false, false, true, address(migration)); + emit Events.FollowModuleSet(profileId, address(0), '', '', address(0), block.timestamp); + + migration.batchMigrateFollowModules(_toUint256Array(profileId)); + + address updatedFollowModule = _getFollowModule(profileId, address(migration)); + assertEq(updatedFollowModule, address(0)); + } + function _mockTokenOwner(uint256 profileId, address owner) internal { bytes32 profileOwnerSlot = keccak256(abi.encode(profileId, StorageLib.TOKEN_DATA_MAPPING_SLOT)); vm.store(address(hub), profileOwnerSlot, bytes32(uint256(uint160(owner)))); @@ -641,6 +707,27 @@ contract MigrationsTestNonFork is BaseTest { vm.store(address(hub), handleSlot, bytes32Handle); } + function _getFollowModule(uint256 profileId, address storageContract) internal returns (address) { + bytes32 followModuleSlot = _getFollowModuleSlot(profileId); + return address(uint160(uint256(vm.load(address(storageContract), followModuleSlot)))); + } + + function _getFollowModuleSlot(uint256 profileId) internal returns (bytes32) { + bytes32 profileSlot = keccak256(abi.encode(profileId, StorageLib.PROFILES_MAPPING_SLOT)); + + uint256 followModuleOffset = 1; + return bytes32(uint256(profileSlot) + followModuleOffset); + } + + function _mockProfileFollowModule( + uint256 profileId, + address followModuleAddress, + address storageContract + ) internal { + bytes32 followModuleSlot = _getFollowModuleSlot(profileId); + vm.store(storageContract, followModuleSlot, bytes32(uint256(uint160(followModuleAddress)))); + } + function _mockProfileFollowNFT(uint256 profileId, address followNFTAddress) internal { bytes32 profileSlot = keccak256(abi.encode(profileId, StorageLib.PROFILES_MAPPING_SLOT));