// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import {Script, console2} from "forge-std/Script.sol"; import {GRUVaultIndex} from "../../../contracts/vault/GRUVaultIndex.sol"; import {VaultFactory} from "../../../contracts/vault/VaultFactory.sol"; interface IGRUVaultIndexLegacy { function allVaults(uint256 index) external view returns (address); function vaults(address vault) external view returns ( address entity, address baseToken, address depositToken, address debtToken, uint8 gruTier, bytes32 ibanHash, bytes32 policyProfileKey, uint256 recordedAt, bool active ); } /// @notice Deploy GRUVaultIndex v2 and migrate records from legacy index with policy profile backfill. contract MigrateGRUVaultIndex138 is Script { function run() external { uint256 pk = vm.envUint("PRIVATE_KEY"); address admin = vm.addr(pk); address oldIndex = vm.envAddress("OLD_GRU_VAULT_INDEX"); address factory = vm.envAddress("VAULT_FACTORY_ADDRESS"); bytes32 policyKey = vm.envBytes32("GRU_POLICY_PROFILE_KEY"); vm.startBroadcast(pk); GRUVaultIndex newIndex = new GRUVaultIndex(admin); console2.log("New GRUVaultIndex:", address(newIndex)); IGRUVaultIndexLegacy legacy = IGRUVaultIndexLegacy(oldIndex); uint256 imported; for (uint256 i = 0; i < 32; i++) { address vault; try legacy.allVaults(i) returns (address v) { vault = v; } catch { break; } if (vault == address(0)) break; ( address entity, address baseToken, address depositToken, address debtToken, uint8 gruTier, bytes32 ibanHash, bytes32 existingKey, uint256 recordedAt, bool active ) = legacy.vaults(vault); if (!active) continue; bytes32 key = existingKey == bytes32(0) ? policyKey : existingKey; newIndex.importVault( vault, entity, baseToken, depositToken, debtToken, gruTier, ibanHash, key, recordedAt ); imported++; console2.log("Imported vault", vault); } newIndex.grantFactoryRole(factory); VaultFactory(factory).setGruVaultIndex(address(newIndex)); vm.stopBroadcast(); console2.log("Migrated vault count:", imported); console2.log("Update GRU_VAULT_INDEX to", address(newIndex)); } }