mirror of
https://github.com/lens-protocol/core.git
synced 2026-01-08 21:58:06 -05:00
feat: Profile Migration Fork Tests
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -24,8 +24,6 @@ coverage.json
|
||||
.coverage_contracts
|
||||
lcov*
|
||||
|
||||
addresses.json
|
||||
|
||||
# Compiler files
|
||||
forge-cache/
|
||||
out/
|
||||
|
||||
46
addresses.json
Normal file
46
addresses.json
Normal file
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"mainnet": {
|
||||
"chainId": 137,
|
||||
"network": "polygon",
|
||||
"LensHubProxy": "0xDb46d1Dc155634FbC732f92E853b10B288AD5a1d",
|
||||
"LensHubImplementation": "0x96f1ba24294ffe0dfcd832d8376da4a4645a4cd6",
|
||||
"ModuleGlobals": "0x3Df697FF746a60CBe9ee8D47555c88CB66f03BB9",
|
||||
"FreeCollectModule": "0x23b9467334bEb345aAa6fd1545538F3d54436e96",
|
||||
"PoolAddressesProvider": "0xa97684ead0e402dC232d5A977953DF7ECBaB3CDb",
|
||||
"MultirecipientFeeCollectModule": "0xfa9da21d0a18c7b7de4566481c1e8952371f880a",
|
||||
"StepwiseCollectModule": "0x210c94877dcfceda8238acd382372278844a54d7",
|
||||
"ERC4626FeeCollectModule": "0x394fd100b13197787023ef4cf318cde456545db7",
|
||||
"AaveFeeCollectModule": "0xa94713d0688c8a483c3352635cec4e0ce88d6a29",
|
||||
"TokenGatedReferenceModule": "0x3d7f4f71a90fe5a9d13fab2716080f2917cf88f3"
|
||||
},
|
||||
"testnet": {
|
||||
"chainId": 80001,
|
||||
"network": "mumbai",
|
||||
"LensHubProxy": "0x60Ae865ee4C725cd04353b5AAb364553f56ceF82",
|
||||
"LensHubImplementation": "0x45cf9Ba12b43F6c8B7148E06A6f84c5B9ad3Dd44",
|
||||
"ModuleGlobals": "0x1353aAdfE5FeD85382826757A95DE908bd21C4f9",
|
||||
"FreeCollectModule": "0x0BE6bD7092ee83D44a6eC1D949626FeE48caB30c",
|
||||
"PoolAddressesProvider": "0x5343b5bA672Ae99d627A1C87866b8E53F47Db2E6",
|
||||
"MultirecipientFeeCollectModule": "0x99d6c3eabf05435e851c067d2c3222716f7fcfe5",
|
||||
"StepwiseCollectModule": "0x7a7b8e7699e0492da1d3c7eab7e2f3bf1065aa40",
|
||||
"ERC4626FeeCollectModule": "0x79697402bd2caa19a53d615fb1a30a98e35b84d5",
|
||||
"AaveFeeCollectModule": "0x912860ed4ed6160c48a52d52fcab5c059d34fe5a",
|
||||
"TokenGatedReferenceModule": "0xb4ba8dccd35bd3dcc5d58dbb9c7dff9c9268add9",
|
||||
"InteractionLogic": "0x845242e2Cd249af8D4f0D7085DefEAc3381815E3"
|
||||
},
|
||||
"sandbox": {
|
||||
"chainId": 80001,
|
||||
"network": "mumbai",
|
||||
"LensHubProxy": "0x7582177F9E536aB0b6c721e11f383C326F2Ad1D5",
|
||||
"LensHubImplementation": "0x1b30F214c192EF4B7F8c9926c47C4161016955DA",
|
||||
"ModuleGlobals": "0xcbCC5b9611d22d11403373432642Df9Ef7Dd81AD",
|
||||
"FreeCollectModule": "0x11C45Cbc6fDa2dbe435C0079a2ccF9c4c7051595",
|
||||
"PoolAddressesProvider": "0x5343b5bA672Ae99d627A1C87866b8E53F47Db2E6",
|
||||
"MultirecipientFeeCollectModule": "0x1cff6c45b0de2fff70670ef4dc67a92a1ccfe0bb",
|
||||
"StepwiseCollectModule": "0x6928d6127dfa0da401737e6ff421fcf62d5617a3",
|
||||
"ERC4626FeeCollectModule": "0x31126c602cf88193825a99dcd1d17bf1124b1b4f",
|
||||
"AaveFeeCollectModule": "0x666e06215747879ee68b3e5a317dcd8411de1897",
|
||||
"TokenGatedReferenceModule": "0x86d35562ceb9f10d7c2c23c098dfeacb02f53853",
|
||||
"MockSandboxGovernance": "0x1677d9cC4861f1C85ac7009d5F06f49c928CA2AD"
|
||||
}
|
||||
}
|
||||
@@ -5,9 +5,11 @@ pragma solidity ^0.8.19;
|
||||
contract ImmutableOwnable {
|
||||
address immutable OWNER;
|
||||
address immutable LENS_HUB;
|
||||
address immutable MIGRATOR;
|
||||
|
||||
error OnlyOwner();
|
||||
error OnlyOwnerOrHub();
|
||||
error OnlyOwnerOrHubOrMigrator();
|
||||
|
||||
modifier onlyOwner() {
|
||||
if (msg.sender != OWNER) {
|
||||
@@ -23,8 +25,16 @@ contract ImmutableOwnable {
|
||||
_;
|
||||
}
|
||||
|
||||
constructor(address owner, address lensHub) {
|
||||
modifier onlyOwnerOrHubOrMigrator() {
|
||||
if (msg.sender != OWNER && msg.sender != LENS_HUB && msg.sender != MIGRATOR) {
|
||||
revert OnlyOwnerOrHubOrMigrator();
|
||||
}
|
||||
_;
|
||||
}
|
||||
|
||||
constructor(address owner, address lensHub, address migrator) {
|
||||
OWNER = owner;
|
||||
LENS_HUB = lensHub;
|
||||
MIGRATOR = migrator;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,13 @@ import {LensHub} from 'contracts/LensHub.sol';
|
||||
import {LensHandles} from 'contracts/misc/namespaces/LensHandles.sol';
|
||||
import {TokenHandleRegistry} from 'contracts/misc/namespaces/TokenHandleRegistry.sol';
|
||||
|
||||
struct ProfileMigrationData {
|
||||
uint256 profileId;
|
||||
address profileDestination;
|
||||
string handle;
|
||||
bytes32 handleHash;
|
||||
}
|
||||
|
||||
contract ProfileMigration is Ownable {
|
||||
LensHub public immutable lensHub;
|
||||
LensHandles public immutable lensHandles;
|
||||
@@ -26,13 +33,6 @@ contract ProfileMigration is Ownable {
|
||||
tokenHandleRegistry = TokenHandleRegistry(tokenHandleRegistryAddress);
|
||||
}
|
||||
|
||||
struct ProfileMigrationData {
|
||||
uint256 profileId;
|
||||
address profileDestination;
|
||||
string handle;
|
||||
bytes32 handleHash;
|
||||
}
|
||||
|
||||
// TODO: Assume we pause everything - creating, transfer, etc.
|
||||
function _migrateProfile(ProfileMigrationData calldata profileMigrationData) internal {
|
||||
lensHub.migrateProfile(profileMigrationData.profileId, profileMigrationData.handleHash);
|
||||
@@ -6,7 +6,7 @@ import {ERC721} from '@openzeppelin/contracts/token/ERC721/ERC721.sol';
|
||||
import {VersionedInitializable} from 'contracts/base/upgradeability/VersionedInitializable.sol';
|
||||
import {ImmutableOwnable} from 'contracts/misc/migrations/ImmutableOwnable.sol';
|
||||
|
||||
library Events {
|
||||
library HandlesEvents {
|
||||
event HandleMinted(string handle, string namespace, uint256 handleId, address to);
|
||||
}
|
||||
|
||||
@@ -17,7 +17,11 @@ contract LensHandles is ERC721, VersionedInitializable, ImmutableOwnable {
|
||||
string constant NAMESPACE = 'lens';
|
||||
bytes32 constant NAMESPACE_HASH = keccak256(bytes(NAMESPACE));
|
||||
|
||||
constructor(address owner, address lensHub) ERC721('', '') ImmutableOwnable(owner, lensHub) {}
|
||||
constructor(
|
||||
address owner,
|
||||
address lensHub,
|
||||
address migrator
|
||||
) ERC721('', '') ImmutableOwnable(owner, lensHub, migrator) {}
|
||||
|
||||
function name() public pure override returns (string memory) {
|
||||
return string.concat(symbol(), ' Handles');
|
||||
@@ -37,12 +41,12 @@ contract LensHandles is ERC721, VersionedInitializable, ImmutableOwnable {
|
||||
* @param to The address where the handle is being minted to.
|
||||
* @param localName The local name of the handle.
|
||||
*/
|
||||
function mintHandle(address to, string calldata localName) external onlyOwnerOrHub returns (uint256) {
|
||||
function mintHandle(address to, string calldata localName) external onlyOwnerOrHubOrMigrator returns (uint256) {
|
||||
bytes32 localNameHash = keccak256(bytes(localName));
|
||||
bytes32 handleHash = keccak256(abi.encodePacked(localNameHash, NAMESPACE_HASH));
|
||||
uint256 handleId = uint256(handleHash);
|
||||
_mint(to, handleId);
|
||||
emit Events.HandleMinted(localName, NAMESPACE, handleId, to);
|
||||
emit HandlesEvents.HandleMinted(localName, NAMESPACE, handleId, to);
|
||||
return handleId;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import {IERC721} from '@openzeppelin/contracts/token/ERC721/IERC721.sol';
|
||||
import {VersionedInitializable} from 'contracts/base/upgradeability/VersionedInitializable.sol';
|
||||
|
||||
// TODO: Move to Errors file
|
||||
library Errors {
|
||||
library RegistryErrors {
|
||||
error NotHandleOwner();
|
||||
error NotTokenOwner();
|
||||
error NotHandleOrTokenOwner();
|
||||
@@ -26,7 +26,7 @@ struct Handle {
|
||||
}
|
||||
|
||||
// TODO: Move to Events file
|
||||
library Events {
|
||||
library RegistryEvents {
|
||||
event HandleLinked(Handle handle, Token token);
|
||||
event HandleUnlinked(Handle handle, Token token);
|
||||
}
|
||||
@@ -53,14 +53,14 @@ contract TokenHandleRegistry is VersionedInitializable {
|
||||
|
||||
modifier onlyHandleOwner(Handle memory handle, address transactionExecutor) {
|
||||
if (IERC721(handle.collection).ownerOf(handle.id) != transactionExecutor) {
|
||||
revert Errors.NotHandleOwner();
|
||||
revert RegistryErrors.NotHandleOwner();
|
||||
}
|
||||
_;
|
||||
}
|
||||
|
||||
modifier onlyTokenOwner(Token memory token, address transactionExecutor) {
|
||||
if (IERC721(token.collection).ownerOf(token.id) != transactionExecutor) {
|
||||
revert Errors.NotTokenOwner();
|
||||
revert RegistryErrors.NotTokenOwner();
|
||||
}
|
||||
_;
|
||||
}
|
||||
@@ -75,7 +75,7 @@ contract TokenHandleRegistry is VersionedInitializable {
|
||||
!(IERC721(handle.collection).ownerOf(handle.id) == transactionExecutor ||
|
||||
IERC721(token.collection).ownerOf(token.id) == transactionExecutor)
|
||||
) {
|
||||
revert Errors.NotHandleOrTokenOwner();
|
||||
revert RegistryErrors.NotHandleOrTokenOwner();
|
||||
}
|
||||
_;
|
||||
}
|
||||
@@ -91,12 +91,12 @@ contract TokenHandleRegistry is VersionedInitializable {
|
||||
|
||||
// V1->V2 Migration function
|
||||
function migrationLinkHandleWithToken(uint256 handleId, uint256 tokenId) external {
|
||||
require(msg.sender == migrator, 'Only migrator');
|
||||
require(msg.sender == migrator || msg.sender == LENS_HUB, 'Only migrator or hub');
|
||||
Handle memory handle = Handle({collection: LENS_HANDLES, id: handleId});
|
||||
Token memory token = Token({collection: LENS_HUB, id: tokenId});
|
||||
handleToToken[_handleHash(handle)] = token;
|
||||
tokenToHandle[_tokenHash(token)] = handle;
|
||||
emit Events.HandleLinked(handle, token);
|
||||
emit RegistryEvents.HandleLinked(handle, token);
|
||||
}
|
||||
|
||||
// NOTE: Simplified interfaces for the first version - Namespace and LensHub are constants
|
||||
@@ -147,7 +147,7 @@ contract TokenHandleRegistry is VersionedInitializable {
|
||||
) internal onlyTokenOwner(token, msg.sender) onlyHandleOwner(handle, msg.sender) {
|
||||
handleToToken[_handleHash(handle)] = token;
|
||||
tokenToHandle[_tokenHash(token)] = handle;
|
||||
emit Events.HandleLinked(handle, token);
|
||||
emit RegistryEvents.HandleLinked(handle, token);
|
||||
}
|
||||
|
||||
function _unlinkHandleFromToken(
|
||||
@@ -156,7 +156,7 @@ contract TokenHandleRegistry is VersionedInitializable {
|
||||
) internal onlyHandleOrTokenOwner(handle, token, msg.sender) {
|
||||
delete handleToToken[_handleHash(handle)];
|
||||
delete tokenToHandle[_tokenHash(token)];
|
||||
emit Events.HandleUnlinked(handle, token);
|
||||
emit RegistryEvents.HandleUnlinked(handle, token);
|
||||
}
|
||||
|
||||
// Utility functions for mappings
|
||||
|
||||
@@ -8,31 +8,65 @@ import 'contracts/LensHub.sol';
|
||||
import 'contracts/FollowNFT.sol';
|
||||
import 'contracts/CollectNFT.sol';
|
||||
|
||||
import 'contracts/misc/migrations/ProfileMigration.sol';
|
||||
import {LensHandles} from 'contracts/misc/namespaces/LensHandles.sol';
|
||||
import {TokenHandleRegistry} from 'contracts/misc/namespaces/TokenHandleRegistry.sol';
|
||||
|
||||
/**
|
||||
* This script will deploy the current repository implementations, using the given environment
|
||||
* hub proxy address.
|
||||
*/
|
||||
contract DeployUpgradeScript is Script {
|
||||
function run() public {
|
||||
uint256 deployerKey = vm.envUint('DEPLOYER_KEY');
|
||||
string memory deployerMnemonic = vm.envString('MNEMONIC');
|
||||
uint256 deployerKey = vm.deriveKey(deployerMnemonic, 0);
|
||||
address deployer = vm.addr(deployerKey);
|
||||
address hubProxyAddr = vm.envAddress('HUB_PROXY_ADDRESS');
|
||||
|
||||
address owner = deployer;
|
||||
|
||||
LensHub hub = LensHub(hubProxyAddr);
|
||||
address followNFTAddress = hub.getFollowNFTImpl();
|
||||
address collectNFTAddress = hub.getCollectNFTImpl();
|
||||
|
||||
uint256 deployerNonce = vm.getNonce(deployer);
|
||||
|
||||
// Precompute needed addresss.
|
||||
address lensHandlesAddress = computeCreateAddress(deployer, deployerNonce);
|
||||
address migratorAddress = computeCreateAddress(deployer, deployerNonce + 1);
|
||||
address tokenHandleRegistryAddress = computeCreateAddress(deployer, deployerNonce + 2);
|
||||
|
||||
// Start deployments.
|
||||
vm.startBroadcast(deployerKey);
|
||||
|
||||
// Precompute needed addresss.
|
||||
address followNFTAddr = computeCreateAddress(deployer, 1);
|
||||
address collectNFTAddr = computeCreateAddress(deployer, 2);
|
||||
LensHandles lensHandles = new LensHandles(owner, address(hub), migratorAddress);
|
||||
console.log(address(lensHandles), lensHandlesAddress);
|
||||
|
||||
// Deploy implementation contracts.
|
||||
address hubImpl = address(new LensHub(followNFTAddr, collectNFTAddr));
|
||||
address followNFT = address(new FollowNFT(hubProxyAddr));
|
||||
address collectNFT = address(new CollectNFT(hubProxyAddr));
|
||||
ProfileMigration migrator = new ProfileMigration(
|
||||
owner,
|
||||
address(hub),
|
||||
lensHandlesAddress,
|
||||
tokenHandleRegistryAddress
|
||||
);
|
||||
console.log(address(migrator), migratorAddress);
|
||||
|
||||
vm.writeFile('addrs', '');
|
||||
vm.writeLine('addrs', string(abi.encodePacked('hubImpl: ', vm.toString(hubImpl))));
|
||||
vm.writeLine('addrs', string(abi.encodePacked('followNFT: ', vm.toString(followNFT))));
|
||||
vm.writeLine('addrs', string(abi.encodePacked('collectNFT: ', vm.toString(collectNFT))));
|
||||
TokenHandleRegistry tokenHandleRegistry = new TokenHandleRegistry(
|
||||
address(hub),
|
||||
lensHandlesAddress,
|
||||
migratorAddress
|
||||
);
|
||||
console.log(address(tokenHandleRegistry), tokenHandleRegistryAddress);
|
||||
|
||||
address hubImpl = address(
|
||||
new LensHub(
|
||||
followNFTAddress,
|
||||
collectNFTAddress,
|
||||
migratorAddress,
|
||||
lensHandlesAddress,
|
||||
tokenHandleRegistryAddress
|
||||
)
|
||||
);
|
||||
console.log('New hub impl:', hubImpl);
|
||||
vm.stopBroadcast();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ const config: HardhatUserConfig = {
|
||||
solidity: {
|
||||
compilers: [
|
||||
{
|
||||
version: '0.8.15',
|
||||
version: '0.8.19',
|
||||
settings: {
|
||||
optimizer: {
|
||||
enabled: true,
|
||||
|
||||
@@ -64,37 +64,8 @@ contract TestSetup is Test, ForkManagement, ArrayHelpers {
|
||||
Types.MirrorParams mockMirrorParams;
|
||||
Types.CollectParams mockCollectParams;
|
||||
|
||||
function isEnvSet(string memory key) internal returns (bool) {
|
||||
try vm.envString(key) {
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
constructor() {
|
||||
// TODO: Replace with envOr when it's released
|
||||
forkEnv = isEnvSet('TESTING_FORK') ? vm.envString('TESTING_FORK') : '';
|
||||
|
||||
if (bytes(forkEnv).length > 0) {
|
||||
fork = true;
|
||||
console.log('\n\n Testing using %s fork', forkEnv);
|
||||
loadJson();
|
||||
|
||||
network = getNetwork();
|
||||
|
||||
if (isEnvSet('FORK_BLOCK')) {
|
||||
forkBlockNumber = vm.envUint('FORK_BLOCK');
|
||||
vm.createSelectFork(network, forkBlockNumber);
|
||||
console.log('Fork Block number (FIXED BLOCK):', forkBlockNumber);
|
||||
} else {
|
||||
vm.createSelectFork(network);
|
||||
forkBlockNumber = block.number;
|
||||
console.log('Fork Block number:', forkBlockNumber);
|
||||
}
|
||||
|
||||
checkNetworkParams();
|
||||
|
||||
loadBaseAddresses(forkEnv);
|
||||
} else {
|
||||
deployBaseContracts();
|
||||
@@ -111,12 +82,6 @@ contract TestSetup is Test, ForkManagement, ArrayHelpers {
|
||||
///////////////////////////////////////// End governance actions.
|
||||
}
|
||||
|
||||
// TODO: Replace with forge-std/StdJson.sol::keyExists(...) when/if this PR is approved:
|
||||
// https://github.com/foundry-rs/forge-std/pull/226
|
||||
function keyExists(string memory key) internal returns (bool) {
|
||||
return json.parseRaw(key).length > 0;
|
||||
}
|
||||
|
||||
function loadBaseAddresses(string memory targetEnv) internal virtual {
|
||||
bytes32 PROXY_IMPLEMENTATION_STORAGE_SLOT = bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1);
|
||||
|
||||
|
||||
@@ -17,6 +17,47 @@ contract ForkManagement is Script {
|
||||
_;
|
||||
}
|
||||
|
||||
// TODO: Move somewhere else
|
||||
function isEnvSet(string memory key) internal returns (bool) {
|
||||
try vm.envString(key) {
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Move somewhere else
|
||||
// TODO: Replace with forge-std/StdJson.sol::keyExists(...) when/if this PR is approved:
|
||||
// https://github.com/foundry-rs/forge-std/pull/226
|
||||
function keyExists(string memory key) internal returns (bool) {
|
||||
return json.parseRaw(key).length > 0;
|
||||
}
|
||||
|
||||
constructor() {
|
||||
// TODO: Replace with envOr when it's released
|
||||
forkEnv = isEnvSet('TESTING_FORK') ? vm.envString('TESTING_FORK') : '';
|
||||
|
||||
if (bytes(forkEnv).length > 0) {
|
||||
fork = true;
|
||||
console.log('\n\n Testing using %s fork', forkEnv);
|
||||
loadJson();
|
||||
|
||||
network = getNetwork();
|
||||
|
||||
if (isEnvSet('FORK_BLOCK')) {
|
||||
forkBlockNumber = vm.envUint('FORK_BLOCK');
|
||||
vm.createSelectFork(network, forkBlockNumber);
|
||||
console.log('Fork Block number (FIXED BLOCK):', forkBlockNumber);
|
||||
} else {
|
||||
vm.createSelectFork(network);
|
||||
forkBlockNumber = block.number;
|
||||
console.log('Fork Block number:', forkBlockNumber);
|
||||
}
|
||||
|
||||
checkNetworkParams();
|
||||
}
|
||||
}
|
||||
|
||||
function loadJson() internal {
|
||||
string memory root = vm.projectRoot();
|
||||
string memory path = string.concat(root, '/addresses.json');
|
||||
|
||||
135
test/foundry/migrations/Migrations.t.sol
Normal file
135
test/foundry/migrations/Migrations.t.sol
Normal file
@@ -0,0 +1,135 @@
|
||||
// SPDX-License-Identifier: UNLICENSED
|
||||
pragma solidity ^0.8.13;
|
||||
|
||||
import 'forge-std/Test.sol';
|
||||
import {ForkManagement} from 'test/foundry/helpers/ForkManagement.sol';
|
||||
import {CollectNFT} from 'contracts/CollectNFT.sol';
|
||||
import {LensHub} from 'contracts/LensHub.sol';
|
||||
import {FollowNFT} from 'contracts/FollowNFT.sol';
|
||||
import {TransparentUpgradeableProxy} from 'contracts/base/upgradeability/TransparentUpgradeableProxy.sol';
|
||||
import {ModuleGlobals} from 'contracts/misc/ModuleGlobals.sol';
|
||||
import 'contracts/misc/migrations/ProfileMigration.sol';
|
||||
import {LensHandles} from 'contracts/misc/namespaces/LensHandles.sol';
|
||||
import {TokenHandleRegistry} from 'contracts/misc/namespaces/TokenHandleRegistry.sol';
|
||||
import {Types} from 'contracts/libraries/constants/Types.sol';
|
||||
|
||||
contract MigrationsTest is Test, ForkManagement {
|
||||
using stdJson for string;
|
||||
|
||||
uint256 internal constant LENS_PROTOCOL_PROFILE_ID = 1;
|
||||
|
||||
bytes32 constant PROXY_IMPLEMENTATION_STORAGE_SLOT =
|
||||
bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1);
|
||||
bytes32 constant ADMIN_SLOT = bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1);
|
||||
|
||||
address owner = address(0x087E4);
|
||||
address deployer = address(1);
|
||||
address governance;
|
||||
address treasury;
|
||||
address hubProxyAddr;
|
||||
address proxyAdmin;
|
||||
|
||||
ProfileMigration migrator;
|
||||
LensHandles lensHandles;
|
||||
TokenHandleRegistry tokenHandleRegistry;
|
||||
|
||||
CollectNFT collectNFT;
|
||||
FollowNFT followNFT;
|
||||
LensHub hubImpl;
|
||||
TransparentUpgradeableProxy hubAsProxy;
|
||||
LensHub hub;
|
||||
ModuleGlobals moduleGlobals;
|
||||
|
||||
function loadBaseAddresses(string memory targetEnv) internal virtual {
|
||||
console.log('targetEnv:', targetEnv);
|
||||
|
||||
hubProxyAddr = json.readAddress(string(abi.encodePacked('.', targetEnv, '.LensHubProxy')));
|
||||
console.log('hubProxyAddr:', hubProxyAddr);
|
||||
|
||||
hub = LensHub(hubProxyAddr);
|
||||
|
||||
console.log('Hub:', address(hub));
|
||||
|
||||
address followNFTAddr = hub.getFollowNFTImpl();
|
||||
address collectNFTAddr = hub.getCollectNFTImpl();
|
||||
|
||||
address hubImplAddr = address(uint160(uint256(vm.load(hubProxyAddr, PROXY_IMPLEMENTATION_STORAGE_SLOT))));
|
||||
console.log('Found hubImplAddr:', hubImplAddr);
|
||||
|
||||
proxyAdmin = address(uint160(uint256(vm.load(hubProxyAddr, ADMIN_SLOT))));
|
||||
|
||||
followNFT = FollowNFT(followNFTAddr);
|
||||
collectNFT = CollectNFT(collectNFTAddr);
|
||||
hubAsProxy = TransparentUpgradeableProxy(payable(address(hub)));
|
||||
moduleGlobals = ModuleGlobals(json.readAddress(string(abi.encodePacked('.', targetEnv, '.ModuleGlobals'))));
|
||||
|
||||
governance = hub.getGovernance();
|
||||
}
|
||||
|
||||
function setUp() public onlyFork {
|
||||
loadBaseAddresses(forkEnv);
|
||||
|
||||
// Precompute needed addresss.
|
||||
address lensHandlesAddress = computeCreateAddress(deployer, 0);
|
||||
address migratorAddress = computeCreateAddress(deployer, 1);
|
||||
address tokenHandleRegistryAddress = computeCreateAddress(deployer, 2);
|
||||
|
||||
vm.startPrank(deployer);
|
||||
|
||||
lensHandles = new LensHandles(owner, address(hub), migratorAddress);
|
||||
assertEq(address(lensHandles), lensHandlesAddress);
|
||||
|
||||
migrator = new ProfileMigration(owner, address(hub), lensHandlesAddress, tokenHandleRegistryAddress);
|
||||
assertEq(address(migrator), migratorAddress);
|
||||
|
||||
tokenHandleRegistry = new TokenHandleRegistry(address(hub), lensHandlesAddress, migratorAddress);
|
||||
assertEq(address(tokenHandleRegistry), tokenHandleRegistryAddress);
|
||||
|
||||
hubImpl = new LensHub(
|
||||
address(followNFT),
|
||||
address(collectNFT),
|
||||
migratorAddress,
|
||||
lensHandlesAddress,
|
||||
tokenHandleRegistryAddress
|
||||
);
|
||||
vm.stopPrank();
|
||||
|
||||
vm.prank(proxyAdmin);
|
||||
hubAsProxy.upgradeTo(address(hubImpl));
|
||||
}
|
||||
|
||||
function testMigrationsPublic() public onlyFork {
|
||||
uint256[] memory profileIds = new uint256[](10);
|
||||
for (uint256 i = 0; i < 10; i++) {
|
||||
profileIds[i] = i + 1;
|
||||
}
|
||||
hub.batchMigrateProfiles(profileIds);
|
||||
}
|
||||
|
||||
function testMigrationsByOwner() public onlyFork {
|
||||
ProfileMigrationData[] memory profileMigrationDatas = new ProfileMigrationData[](10);
|
||||
|
||||
for (uint256 i = 0; i < 10; i++) {
|
||||
uint256 profileId = i + 1;
|
||||
string memory handleWithLens = hub.getProfile(profileId).handleDeprecated;
|
||||
string memory handle = hub.getProfile(profileId).handleDeprecated;
|
||||
|
||||
if (profileId != LENS_PROTOCOL_PROFILE_ID) {
|
||||
assembly {
|
||||
let handle_length := mload(handle)
|
||||
mstore(handle, sub(handle_length, 5)) // Cut 5 chars (.lens) from the end
|
||||
}
|
||||
}
|
||||
|
||||
profileMigrationDatas[i] = ProfileMigrationData({
|
||||
profileId: profileId,
|
||||
profileDestination: hub.ownerOf(profileId),
|
||||
handle: handle,
|
||||
handleHash: keccak256(bytes(handleWithLens))
|
||||
});
|
||||
}
|
||||
|
||||
vm.prank(owner);
|
||||
migrator.batchMigrateProfiles(profileMigrationDatas);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user