From fd6e5da888f5726a4c715e2c1e31abb7d160b030 Mon Sep 17 00:00:00 2001 From: Alex Sedighi Date: Fri, 10 Apr 2026 14:08:26 +1200 Subject: [PATCH] feat(fleet-identity): add version() function for upgrade verification - Add virtual version() returning '1.0.0' to FleetIdentityUpgradeable - Update V2 mock to override with '2.0.0' - Add test_FleetIdentity_Version and test_FleetIdentity_VersionChangesAfterUpgrade - Fix override specifier in TestUpgradeOnAnvil V2 mock --- src/swarms/FleetIdentityUpgradeable.sol | 9 +++++++++ test/upgrade-demo/TestUpgradeOnAnvil.s.sol | 2 +- test/upgradeable/UpgradeableContracts.t.sol | 20 +++++++++++++++++--- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/swarms/FleetIdentityUpgradeable.sol b/src/swarms/FleetIdentityUpgradeable.sol index 8ec92ac0..b1036742 100644 --- a/src/swarms/FleetIdentityUpgradeable.sol +++ b/src/swarms/FleetIdentityUpgradeable.sol @@ -732,6 +732,15 @@ contract FleetIdentityUpgradeable is return (uint32(countryCode) << uint32(ADMIN_SHIFT)) | uint32(adminCode); } + // ══════════════════════════════════════════════ + // Version + // ══════════════════════════════════════════════ + + /// @notice Returns the contract version for upgrade verification. + function version() external pure virtual returns (string memory) { + return "1.0.0"; + } + // ══════════════════════════════════════════════ // UUPS Authorization // ══════════════════════════════════════════════ diff --git a/test/upgrade-demo/TestUpgradeOnAnvil.s.sol b/test/upgrade-demo/TestUpgradeOnAnvil.s.sol index 51212a01..fcf1f8fa 100644 --- a/test/upgrade-demo/TestUpgradeOnAnvil.s.sol +++ b/test/upgrade-demo/TestUpgradeOnAnvil.s.sol @@ -17,7 +17,7 @@ import {SwarmRegistryL1Upgradeable} from "../../src/swarms/SwarmRegistryL1Upgrad /// @dev Mock V2 that adds version() - inherits from V1 to preserve storage layout contract FleetIdentityUpgradeableV2 is FleetIdentityUpgradeable { - function version() external pure returns (string memory) { + function version() external pure override returns (string memory) { return "2.0.0"; } } diff --git a/test/upgradeable/UpgradeableContracts.t.sol b/test/upgradeable/UpgradeableContracts.t.sol index 9b4b23d6..14400ab9 100644 --- a/test/upgradeable/UpgradeableContracts.t.sol +++ b/test/upgradeable/UpgradeableContracts.t.sol @@ -61,8 +61,8 @@ contract FleetIdentityUpgradeableV2Mock is FleetIdentityUpgradeable { fleetMetadata[tokenId] = metadata; } - function version() external pure returns (string memory) { - return "V2"; + function version() external pure override returns (string memory) { + return "2.0.0"; } } @@ -259,6 +259,10 @@ contract UpgradeableContractsTest is Test { assertEq(fleetIdentity.symbol(), "SFID"); } + function test_FleetIdentity_Version() public view { + assertEq(fleetIdentity.version(), "1.0.0"); + } + function test_FleetIdentity_CannotReinitialize() public { vm.expectRevert(Initializable.InvalidInitialization.selector); fleetIdentity.initialize(attacker, address(bondToken), BASE_BOND, 0); @@ -289,7 +293,7 @@ contract UpgradeableContractsTest is Test { // Verify upgrade FleetIdentityUpgradeableV2Mock v2 = FleetIdentityUpgradeableV2Mock(fleetIdentityProxy); - assertEq(v2.version(), "V2"); + assertEq(v2.version(), "2.0.0"); assertGt(v2.v2InitializedAt(), 0); // Verify old state preserved @@ -301,6 +305,16 @@ contract UpgradeableContractsTest is Test { assertEq(v2.fleetMetadata(tokenId), "metadata://test"); } + function test_FleetIdentity_VersionChangesAfterUpgrade() public { + assertEq(fleetIdentity.version(), "1.0.0"); + + FleetIdentityUpgradeableV2Mock v2Impl = new FleetIdentityUpgradeableV2Mock(); + vm.prank(owner); + fleetIdentity.upgradeToAndCall(address(v2Impl), ""); + + assertEq(FleetIdentityUpgradeableV2Mock(fleetIdentityProxy).version(), "2.0.0"); + } + function test_FleetIdentity_NonOwnerCannotUpgrade() public { FleetIdentityUpgradeableV2Mock v2Impl = new FleetIdentityUpgradeableV2Mock();