Skip to content

feat: implement BLE swarm registry system#99

Open
aliXsed wants to merge 15 commits intomainfrom
aliX/swarm-manager
Open

feat: implement BLE swarm registry system#99
aliXsed wants to merge 15 commits intomainfrom
aliX/swarm-manager

Conversation

@aliXsed
Copy link
Collaborator

@aliXsed aliXsed commented Feb 6, 2026

BLE Swarm Registry System with Geographic Tiered Bonding

A complete BLE tag registry enabling decentralized device discovery using cryptographic membership proofs.

Core Contracts

  • FleetIdentity (ERC-721): UUID-based fleet ownership with geographic registration
    • Two-level registration: Country (ISO 3166-1) or Local (admin area)
    • Geometric bond tiers: BASE_BOND * 2^tier (local), *16 for country
    • Operator delegation for cold/hot wallet separation
    • O(1) setOperator via uuidTotalTierBonds tracking
  • ServiceProvider (ERC-721): Service endpoint URL ownership
  • SwarmRegistryL1: SSTORE2 filter storage for Ethereum L1
  • SwarmRegistryUniversal: Native bytes storage for ZkSync Era

Registration Model

Scenario Who Pays Amount
Fresh registration Caller (becomes owner+operator) BASE_BOND + tierBond
Owned to Registered Operator only tierBond
Multi-region Operator tierBond per region
Burn (non-last) Refund to operator tierBond
Burn (last token) Refund operator gets tierBond, owner gets BASE_BOND

Discovery

  • buildHighestBondedUuidBundle: Priority-ordered bundle (up to 20 UUIDs)
  • XOR filter membership verification for tag validation
  • Inclusion hints (localInclusionHint, countryInclusionHint) for optimal tier selection

Documentation

Complete technical specification in src/swarms/doc/:

Checklist

  • Tier 0 livelock prevention (operator-only registration with tier param)
  • O(1) setOperator via uuidTotalTierBonds storage tracking
  • BASE_BOND refund only on last burn
  • Documentation updated
  • Review tests

@aliXsed aliXsed force-pushed the aliX/swarm-manager branch from 52bb4af to 538047d Compare February 6, 2026 07:55
@aliXsed aliXsed force-pushed the aliX/swarm-manager branch from 401a465 to 483982d Compare March 2, 2026 01:39
@aliXsed aliXsed changed the title feat: implement BLE swarm registry system with dual-chain support feat: implement BLE swarm registry system with geographic tiered bonding Mar 2, 2026
@aliXsed aliXsed changed the title feat: implement BLE swarm registry system with geographic tiered bonding feat: implement BLE swarm registry system Mar 2, 2026
…red bonding

Core Contracts:
- FleetIdentity (ERC-721): UUID-based fleet ownership with geographic registration
  - Two-level registration: Country (ISO 3166-1) or Local (admin area)
  - Geometric bond tiers: BASE_BOND * 2^tier (local), *16 for country
  - Operator delegation for cold/hot wallet separation
  - O(1) setOperator via uuidTotalTierBonds tracking
- ServiceProvider (ERC-721): Service endpoint URL ownership
- SwarmRegistryL1: SSTORE2 filter storage for Ethereum L1
- SwarmRegistryUniversal: Native bytes storage for ZkSync Era

Registration Model:
- Fresh registration: caller becomes owner+operator, pays BASE_BOND + tierBond
- Owned-to-Registered: only operator can register, pays tierBond
- Multi-region: same UUID can register in multiple regions at same level
- Burn refunds: BASE_BOND to owner (on last token), tierBond to operator

Discovery:
- buildHighestBondedUuidBundle: priority-ordered bundle (up to 20 UUIDs)
- XOR filter membership verification for tag validation
- Inclusion hints for optimal tier selection

Documentation:
- Complete technical specification in src/swarms/doc/
- ISO 3166-2 admin area mappings for 18 countries
@aliXsed aliXsed force-pushed the aliX/swarm-manager branch from 3bc4f36 to 540f23a Compare March 2, 2026 03:46
aliXsed added 4 commits March 3, 2026 11:14
- Modify computeSwarmId to use (fleetUuid, filterData, fingerprintSize, tagType) instead of (fleetUuid, providerId, filterData)
- This ensures swarm identity is based on immutable fleet/filter properties, not mutable provider relationship
- Remove updateSwarmFilter() function since changing filter changes swarm identity
- Update provider validation to use try/catch pattern making ProviderDoesNotExist error reachable
- Add test_checkMembership_tinyFilter_returnsFalse for m==0 edge case
- Coverage: SwarmRegistryL1 97.01%, SwarmRegistryUniversal 98.55% (123 tests passing)
- Fix Swarm ID derivation: uses keccak256(fleetUuid, filter, fpSize, tagType),
  not keccak256(fleetUuid, providerId, filter). ProviderId is mutable.
- Remove non-existent updateSwarmFilter function (filter is immutable as part of identity)
- Remove non-existent unregisterToOwned() and releaseUuid() - everything uses burn()
- Remove non-existent registerFleetLocalWithOperator - use claimUuid(uuid, operator) instead
- Fix TIER_CAPACITY: 10 members per tier (was incorrectly 4)
- Fix operator permissions: can set operator for owned UUIDs
- Fix burn flow: registered tokens burned by operator, owned-only by owner
- Fix tier management: only operator can promote/demote registered tokens
- Update struct field order in code examples to match actual contracts
@aliXsed aliXsed marked this pull request as ready for review March 2, 2026 23:43
aliXsed added 2 commits March 3, 2026 16:21
- Convert FleetIdentity, ServiceProvider, SwarmRegistryL1, SwarmRegistryUniversal to UUPS upgradeable pattern
- Implement ERC1967Proxy for transparent proxy pattern with storage isolation
- Add Ownable2Step for safer ownership transfers
- Preserve all public APIs and storage layouts

Deployment:
- Add DeploySwarmUpgradeable.s.sol for initial deployment
- Add UpgradeSwarm.s.sol helper script for contract upgrades
- Support both SwarmRegistryL1 (L1 SSTORE2) and SwarmRegistryUniversal (L2) deployments

Testing:
- Migrate all existing tests to upgradeable versions
  - 12 ServiceProvider tests
  - 216 FleetIdentity tests
  - 13 FleetIdentityFairness tests
  - 69 SwarmRegistryUniversal tests
  - 60 SwarmRegistryL1 tests
- Add test coverage: 95.74% FleetIdentity, 94.41% SwarmRegistryL1, 95.92% SwarmRegistryUniversal, 85% ServiceProvider
- Add comprehensive upgrade demo (test/upgrade-demo/) showing
- Convert FleetIdentity, ServiceProvider, SwarmRegistryL1, SwarmRegistryUniversal to UUPS upgradeable pattern
- Impleost- Implement ERC1967Proxy for transparent proxy pattern with storage isolation
- Add Ownable2Step for safer ost- Add Ownable2Step for safer ownership transfers
- Preserve all public APIs .m- Preserve all public APIs and storage layouts
t

Deployment:
- Add DeploySwarmUpgradeable.s.sn f- Add Depll - Add UpgradeSwarm.s.sol helper script for contract upgr r- Support both SwarmRegistryL1 (L1 SSTORE2) and SwarmRegistEI
Testing:
- Migrate all existing tests to upgradeable versions
  - 12 ServiceProvider Rem- Migran-  - 12 ServiceProvider tests
  - 216 FleetIdentity erviceProvider.sol, etc.)
- All  - 13 FleetIdentityFairneea  - 69 SwarmRegistryUniversal tes
@aliXsed aliXsed requested review from Douglasacost and Copilot March 6, 2026 01:14
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Implements UUPS-upgradeable versions of the BLE swarm registry system (FleetIdentity, ServiceProvider, SwarmRegistry) with supporting deployment/upgrade scripts, tests, CI coverage, and extensive technical documentation (including ISO 3166 mappings).

Changes:

  • Added UUPS-upgradeable swarm contracts (Universal + L1 variants) and deployment/upgrade scripts.
  • Added/updated Foundry tests (upgrade tests, ServiceProvider tests, FleetIdentity “fairness” analysis) and CI coverage enforcement.
  • Added comprehensive docs for registration/discovery/operations/upgradeability plus ISO 3166-2 admin-area mapping references.

Reviewed changes

Copilot reviewed 54 out of 61 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
test/upgradeable/UpgradeableContracts.t.sol Adds upgradeability/initializer/storage-persistence tests using V2 mock implementations
test/upgrade-demo/TestUpgradeOnAnvil.s.sol Adds anvil-zksync demo script to deploy V1, create state, upgrade to V2, and verify
test/upgrade-demo/README.md Documents how to run the upgrade demo on anvil-zksync
test/contentsign/PaymentMiddleware.t.sol Removes unused console/SafeERC20 imports from tests
test/contentsign/BaseContentSign.t.sol Removes unused console import from tests
test/helpers/MockERC20.sol Adds a reusable ERC20 mock for tests (mint + configurable decimals)
test/ServiceProvider.t.sol Adds unit + fuzz tests for ServiceProviderUpgradeable
test/FleetIdentityFairness.t.sol Adds economic/fairness scenario tests around bundle selection and tier economics
src/swarms/doc/upgradeable-contracts.md Adds upgradeability architecture guide and operational runbooks
src/swarms/doc/swarm-operations.md Adds swarm registration/approval/update/deletion operational documentation
src/swarms/doc/maintenance.md Adds operator delegation + tier maintenance guidance
src/swarms/doc/lifecycle.md Adds state machine docs for UUID registration and swarm lifecycle
src/swarms/doc/iso3166-reference.md Adds ISO 3166-1/2 encoding reference and usage examples
src/swarms/doc/iso3166-2/840-United_States.md Adds USA admin-area mapping table
src/swarms/doc/iso3166-2/826-United_Kingdom.md Adds UK admin-area mapping table
src/swarms/doc/iso3166-2/756-Switzerland.md Adds Switzerland admin-area mapping table
src/swarms/doc/iso3166-2/724-Spain.md Adds Spain admin-area mapping table
src/swarms/doc/iso3166-2/710-South_Africa.md Adds South Africa admin-area mapping table
src/swarms/doc/iso3166-2/643-Russia.md Adds Russia admin-area mapping table
src/swarms/doc/iso3166-2/566-Nigeria.md Adds Nigeria admin-area mapping table
src/swarms/doc/iso3166-2/484-Mexico.md Adds Mexico admin-area mapping table
src/swarms/doc/iso3166-2/410-South_Korea.md Adds South Korea admin-area mapping table
src/swarms/doc/iso3166-2/392-Japan.md Adds Japan admin-area mapping table
src/swarms/doc/iso3166-2/380-Italy.md Adds Italy admin-area mapping table
src/swarms/doc/iso3166-2/356-India.md Adds India admin-area mapping table
src/swarms/doc/iso3166-2/276-Germany.md Adds Germany admin-area mapping table
src/swarms/doc/iso3166-2/250-France.md Adds France admin-area mapping table
src/swarms/doc/iso3166-2/156-China.md Adds China admin-area mapping table
src/swarms/doc/iso3166-2/124-Canada.md Adds Canada admin-area mapping table
src/swarms/doc/iso3166-2/076-Brazil.md Adds Brazil admin-area mapping table
src/swarms/doc/iso3166-2/036-Australia.md Adds Australia admin-area mapping table
src/swarms/doc/fleet-registration.md Adds detailed fleet/UUID registration flows + economics
src/swarms/doc/discovery.md Adds client discovery flows and membership verification guidance
src/swarms/doc/data-model.md Adds contract/interface diagrams and data model descriptions
src/swarms/doc/assistant-guide.md Adds system architecture guide intended for assistant/agent context
src/swarms/doc/README.md Adds documentation hub/index for the swarm technical specification
src/swarms/SwarmRegistryUniversalUpgradeable.sol Introduces UUPS-upgradeable universal registry storing filters in bytes
src/swarms/SwarmRegistryL1Upgradeable.sol Introduces UUPS-upgradeable L1 registry storing filters via SSTORE2
src/swarms/ServiceProviderUpgradeable.sol Introduces UUPS-upgradeable ERC721 ownership of provider URLs
src/swarms/FleetIdentityUpgradeable.sol Introduces UUPS-upgradeable FleetIdentity with tiered bonds + operator model
script/UpgradeSwarm.s.sol Adds upgrade script for deployed proxies with optional reinitializer calldata
script/DeploySwarmUpgradeable.s.sol Adds deployment script for proxies + implementations
remappings.txt Updates Foundry remappings for OZ, OZ-upgradeable, and solady
lib/solady Adds solady as a git submodule
lib/openzeppelin-contracts-upgradeable Adds OZ upgradeable contracts as a git submodule
foundry.toml Enables optimizer and adds lint config
foundry.lock Locks dependency revisions/tags for Foundry
.vscode/settings.json Updates VS Code Solidity formatter settings + adds terminal auto-approve config
.gitmodules Registers new git submodules (solady + openzeppelin-contracts-upgradeable)
.github/workflows/checks.yml Updates CI test command and adds coverage job + threshold checking
.github/copilot-instructions.md Adds repo-specific Copilot instructions for Solidity/ZkSync work
.cspell.json Updates spelling config to include new docs and terms
.agent/rules/solidity_zksync.md Adds agent rules for Solidity/ZkSync standards
Comments suppressed due to low confidence (3)

test/upgradeable/UpgradeableContracts.t.sol:1

  • The comment implies the V1 __gap was reduced, but in an inherited V2 mock the original V1 gap still exists in the layout and the new variables are appended after it (the extra __gap_v2 does not “reduce” the inherited gap). To avoid misleading readers about upgrade-safe storage layout, either adjust the comment to reflect the actual layout or structure the mock V2 in a way that truly consumes the V1 gap.
    test/FleetIdentityFairness.t.sol:1
  • The test name references an “8x” multiplier, but the assertions in the body verify a 16× multiplier (COUNTRY_BOND_MULTIPLIER() == 16 and countryBond == localBond * 16). Renaming the test to reflect 16× will make the intent clearer and avoid confusion when reading failures.
    src/swarms/doc/upgradeable-contracts.md:1
  • This shell example is likely to fail as written because the inline # comment comes after a line-continuation backslash, and 0x \ includes trailing characters. Consider rewriting the snippet so the 0x argument is clean (e.g., 0x on its own line without a trailing backslash+comment), and move the explanatory comment to a separate line.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +91 to +98
# Check if coverage is below 95%
THRESHOLD=95
if awk "BEGIN {exit !($COVERAGE < $THRESHOLD)}"; then
echo "Error: Line coverage ($COVERAGE%) is below the required threshold ($THRESHOLD%)"
exit 1
fi

echo "Coverage check passed: $COVERAGE% >= $THRESHOLD%"
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The coverage-threshold condition is inverted: as written, it will fail when coverage is >= threshold and pass when coverage is below threshold. Flip the awk predicate/exit code so the job exits non-zero only when COVERAGE < THRESHOLD (or compare COVERAGE >= THRESHOLD for the passing case).

Suggested change
# Check if coverage is below 95%
THRESHOLD=95
if awk "BEGIN {exit !($COVERAGE < $THRESHOLD)}"; then
echo "Error: Line coverage ($COVERAGE%) is below the required threshold ($THRESHOLD%)"
exit 1
fi
echo "Coverage check passed: $COVERAGE% >= $THRESHOLD%"
# Check if coverage meets or exceeds 95%
THRESHOLD=95
if awk "BEGIN {exit ($COVERAGE >= $THRESHOLD ? 0 : 1)}"; then
echo "Coverage check passed: $COVERAGE% >= $THRESHOLD%"
else
echo "Error: Line coverage ($COVERAGE%) is below the required threshold ($THRESHOLD%)"
exit 1
fi

Copilot uses AI. Check for mistakes.
Comment on lines +525 to +526
if (countryCode == 0) revert InvalidCountryCode();
if (adminCode == 0) revert AdminAreaRequired();
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

buildHighestBondedUuidBundle validates countryCode == 0 and adminCode == 0 but does not enforce the documented bounds (countryCode <= 999, adminCode <= 255). This makes the view behave inconsistently with the registration methods and can produce meaningless region keys for out-of-range inputs; add the same upper-bound checks used elsewhere in the contract.

Suggested change
if (countryCode == 0) revert InvalidCountryCode();
if (adminCode == 0) revert AdminAreaRequired();
if (countryCode == 0 || countryCode > MAX_COUNTRY_CODE) revert InvalidCountryCode();
if (adminCode == 0 || adminCode > 255) revert AdminAreaRequired();

Copilot uses AI. Check for mistakes.
Comment on lines +16 to +18
},
"chat.tools.terminal.autoApprove": {
"forge": true
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Enabling repo-wide terminal auto-approval for forge can cause unsafe command execution for contributors using compatible chat tooling (it changes behavior outside the Solidity code). Consider removing this from the repository settings (or moving it to personal/user settings) so running terminal commands always requires explicit user confirmation.

Suggested change
},
"chat.tools.terminal.autoApprove": {
"forge": true

Copilot uses AI. Check for mistakes.
pragma solidity ^0.8.24;

import {Script, console} from "forge-std/Script.sol";
import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This import is not referenced anywhere in the script. Removing it reduces clutter and avoids implying that the script depends on UUPS internals beyond calling upgradeToAndCall on the proxy contract types.

Suggested change
import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";

Copilot uses AI. Check for mistakes.
Comment on lines +99 to +102
} else {
console.log("Calling upgradeTo...");
proxyContract.upgradeToAndCall(impl, "");
}
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The log message says upgradeTo... but the code calls upgradeToAndCall (with empty calldata). Either call upgradeTo(impl) in the no-reinit branch, or update the log message to match the actual function being invoked to prevent operator confusion during upgrades.

Copilot uses AI. Check for mistakes.

All contracts are **permissionless** — access control is enforced through NFT ownership rather than admin roles. `FleetIdentity` additionally requires an ERC-20 bond (e.g. NODL) to register a fleet, acting as an anti-spam / anti-abuse mechanism.

Both NFT contracts support **burning**. For `FleetIdentity`, owned-only tokens can be burned by the owner (refunds BASE*BOND), while registered tokens can only be burned by the operator (refunds tier bond). Burning a `ServiceProvider` token requires owner rights. Burning either NFT makes any swarms referencing that token \_orphaned*.
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct the bond constant formatting: BASE*BOND should be BASE_BOND.

Suggested change
Both NFT contracts support **burning**. For `FleetIdentity`, owned-only tokens can be burned by the owner (refunds BASE*BOND), while registered tokens can only be burned by the operator (refunds tier bond). Burning a `ServiceProvider` token requires owner rights. Burning either NFT makes any swarms referencing that token \_orphaned*.
Both NFT contracts support **burning**. For `FleetIdentity`, owned-only tokens can be burned by the owner (refunds BASE_BOND), while registered tokens can only be burned by the operator (refunds tier bond). Burning a `ServiceProvider` token requires owner rights. Burning either NFT makes any swarms referencing that token \_orphaned*.

Copilot uses AI. Check for mistakes.
aliXsed added 4 commits March 6, 2026 16:16
- Reorder params: (owner, bondToken, baseBond, countryMultiplier)
- bondToken required; baseBond=0 uses DEFAULT_BASE_BOND (1e18)
- countryMultiplier=0 uses DEFAULT_COUNTRY_BOND_MULTIPLIER (16)
- Simplify countryBondMultiplier() getter (no more fallback logic)
- Update all test files with new signature
- Coverage: 96.77% line, 95.58% branch
…rint

- Replace uint8 fingerprintSize with FingerprintSize enum (BITS_8, BITS_16)
- Optimize _readFingerprint: direct byte access without loops/divisions
- Simplify checkMembership m calculation with ternary operator
- Remove InvalidFingerprintSize error (enum enforces valid values)
- Update tests for both SwarmRegistryL1 and SwarmRegistryUniversal
- Add missing technical terms to cspell dictionary
…ests

- Add getFilterData() function to SwarmRegistryL1Upgradeable for parity with Universal
- Install lcov in CI workflow before running coverage report action (fixes genhtml missing error)
- Add coverage tests for 8-bit fingerprint path and upgrade authorization
- Fix test string identifiers for spellcheck compliance
@github-actions
Copy link

github-actions bot commented Mar 6, 2026

LCOV of commit 5e59643 during checks #602

Summary coverage rate:
  lines......: 32.0% (714 of 2231 lines)
  functions..: 28.9% (104 of 360 functions)
  branches...: 34.5% (118 of 342 branches)

Files changed coverage rate:
                                                  |Lines       |Functions  |Branches    
  Filename                                        |Rate     Num|Rate    Num|Rate     Num
  ======================================================================================
  script/DeploySwarmUpgradeable.s.sol             | 0.0%     49| 0.0%     1| 0.0%      2
  script/UpgradeSwarm.s.sol                       | 0.0%     66| 0.0%     5| 0.0%     16
  src/swarms/FleetIdentityUpgradeable.sol         |96.5%    433|95.2%    62|80.6%     72
  src/swarms/ServiceProviderUpgradeable.sol       |85.0%     20|80.0%     5| 100%      2
  src/swarms/SwarmRegistryL1Upgradeable.sol       |95.0%    140| 100%    17|96.7%     30
  src/swarms/SwarmRegistryUniversalUpgradeable.sol|96.4%    138| 100%    17|96.7%     30
  test/FleetIdentity.t.sol                        |70.0%     10|80.0%     5|    -      0
  test/FleetIdentityFairness.t.sol                | 100%      2| 100%     1|    -      0
  test/SwarmRegistryL1.t.sol                      | 100%      2| 100%     1|    -      0
  test/SwarmRegistryUniversal.t.sol               | 100%      2| 100%     1|    -      0
  test/__helpers__/MockERC20.sol                  | 0.0%      6| 0.0%     3|    -      0
  test/contentsign/BaseContentSign.t.sol          | 0.0%      4| 0.0%     2|    -      0
  test/contentsign/PaymentMiddleware.t.sol        | 0.0%      6| 0.0%     3|    -      0
  test/upgrade-demo/TestUpgradeOnAnvil.s.sol      | 0.0%    139| 0.0%     6| 0.0%     24
  test/upgradeable/UpgradeableContracts.t.sol     | 0.0%     20| 0.0%     9| 0.0%      2

aliXsed added 4 commits March 6, 2026 18:04
- SwarmRegistryL1Upgradeable uses SSTORE2 which relies on EXTCODECOPY
- EXTCODECOPY is not supported on ZkSync Era, causing tx drops
- Updated test to use regular anvil instead of anvil-zksync
- Added Phase 1B to verify V1 initializers run correctly
- Updated README with correct instructions and warnings
- Create src/swarms/interfaces/ directory with:
  - SwarmTypes.sol: shared enums (RegistrationLevel, SwarmStatus, TagType,
    FingerprintSize) for use by contracts and external integrators
  - IFleetIdentity.sol: public interface for FleetIdentityUpgradeable
  - IServiceProvider.sol: public interface for ServiceProviderUpgradeable
  - ISwarmRegistry.sol: common interface for SwarmRegistry variants

- Update contracts to import shared enums from SwarmTypes.sol instead of
  defining them inline, reducing duplication

- Update tests to use imported enums from SwarmTypes.sol

This follows the recommended UUPS pattern of defining public interfaces
separately to make the expected API surface explicit across upgrades.
The zgosalvez/github-actions-report-lcov action was checking 95% coverage
against the entire project (32%). The custom shell script step below
correctly filters and checks coverage for src/swarms/* files only.
- Add Interface Files section to data-model.md
- Add interfaces/ link to README documentation table
- Reference SwarmTypes.sol location in assistant-guide.md
@aliXsed aliXsed requested a review from Copilot March 6, 2026 06:07
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 58 out of 65 changed files in this pull request and generated 5 comments.

Comments suppressed due to low confidence (3)

src/swarms/interfaces/ISwarmRegistry.sol:1

  • SwarmRegistryUniversalUpgradeable emits SwarmRegistered with an extra filterSize argument, which changes the event signature/topic0 and makes this interface event incorrect for Universal deployments. Consider standardizing the event signature across implementations (e.g., add uint32 filterSize to the interface and also emit it from the L1 implementation, or emit a second “extended” event name in Universal while keeping the canonical 4-arg event for compatibility).
    test/upgradeable/UpgradeableContracts.t.sol:1
  • In an inherited V2 implementation, adding __gap_v2 does not “reduce” the parent contract’s __gap; the parent __gap remains part of the layout and the new variables are appended after it. To avoid teaching a misleading upgrade pattern, either (a) remove/reword the “reduce gap” comments, or (b) demonstrate the real gap-consumption approach by updating the original contract’s __gap size in a V2 copy rather than adding a second gap in the child.
    test/FleetIdentityFairness.t.sol:1
  • The test name says “8xMultiplier” but the assertions validate a 16× multiplier. Rename the test to reflect the actual invariant being checked (e.g., test_economicAdvantage_16xMultiplier) to keep intent clear.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

console.log(" Implementation:", fleetIdentityImpl);

bytes memory fleetIdentityInitData =
abi.encodeWithSelector(FleetIdentityUpgradeable.initialize.selector, bondToken, baseBond, owner);
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The initializer calldata for FleetIdentityUpgradeable.initialize appears to use a different parameter order/arity than the tests in this PR (which call initialize(owner, bondToken, baseBond, ...)). As written, this is likely to revert at runtime or fail to compile if the signature doesn’t match; update the deploy script to use abi.encodeCall(FleetIdentityUpgradeable.initialize, (...)) with the exact initializer argument order used by the contract/tests.

Suggested change
abi.encodeWithSelector(FleetIdentityUpgradeable.initialize.selector, bondToken, baseBond, owner);
abi.encodeCall(FleetIdentityUpgradeable.initialize, (owner, bondToken, baseBond));

Copilot uses AI. Check for mistakes.
Comment on lines +69 to +79
if (keccak256(bytes(contractType)) == keccak256("ServiceProvider")) {
newImpl = _upgradeServiceProvider(proxyAddress, reinitData);
} else if (keccak256(bytes(contractType)) == keccak256("FleetIdentity")) {
newImpl = _upgradeFleetIdentity(proxyAddress, reinitData);
} else if (keccak256(bytes(contractType)) == keccak256("SwarmRegistryUniversal")) {
newImpl = _upgradeSwarmRegistryUniversal(proxyAddress, reinitData);
} else if (keccak256(bytes(contractType)) == keccak256("SwarmRegistryL1")) {
newImpl = _upgradeSwarmRegistryL1(proxyAddress, reinitData);
} else {
revert("Invalid CONTRACT_TYPE. Use: ServiceProvider, FleetIdentity, SwarmRegistryUniversal, SwarmRegistryL1");
}
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

keccak256("...") is not valid because keccak256 expects bytes (not a string literal). Use keccak256(bytes("ServiceProvider")) (and likewise for the other constants), or compare strings via keccak256(bytes(contractType)) == keccak256(bytes(CONSTANT)) where CONSTANT is a string.

Copilot uses AI. Check for mistakes.
}
if (filter.length > MAX_FILTER_SIZE) {
revert FilterTooLarge();
}
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

registerSwarm does not validate fpSize values beyond the enum type, but Solidity enums can still carry invalid underlying values supplied by callers. Since checkMembership branches on fpSize and otherwise defaults to the 16-bit path, an invalid fpSize can cause inconsistent/misleading membership behavior. Add an explicit check that fpSize is either FingerprintSize.BITS_8 or FingerprintSize.BITS_16 (and optionally enforce filter.length parity for BITS_16 if that’s a requirement of your encoding).

Suggested change
}
}
if (fpSize != FingerprintSize.BITS_8 && fpSize != FingerprintSize.BITS_16) {
revert("Invalid fingerprint size");
}

Copilot uses AI. Check for mistakes.
@@ -0,0 +1,142 @@
# Lifecycle & State Machines
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The markdown code fences use quadruple backticks (````) around a mermaid block, which will likely render incorrectly (and the opening fence at line 107 appears unmatched/unnecessary). Use consistent triple-backtick fences and ensure each opening fence has a matching closing fence so the document renders reliably.

Copilot uses AI. Check for mistakes.
Comment on lines +136 to +138
| :------ | :------------------------ | :------------------------------ | ------------------------------- |
| Owned | `BASE_BOND` | Owner |
| Local | `BASE_BOND × 2^tier` | Operator (owner paid BASE_BOND) | Operator (owner paid BASE_BOND) |
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This table’s header/separator rows define 3 columns but the separator row defines 4, and the “Local” row repeats the “Who Pays” cell (4 columns). Fix the markdown table to a consistent column count so it renders correctly and doesn’t confuse the “Who Pays” semantics.

Suggested change
| :------ | :------------------------ | :------------------------------ | ------------------------------- |
| Owned | `BASE_BOND` | Owner |
| Local | `BASE_BOND × 2^tier` | Operator (owner paid BASE_BOND) | Operator (owner paid BASE_BOND) |
| :------ | :------------------------ | :------------------------------ |
| Owned | `BASE_BOND` | Owner |
| Local | `BASE_BOND × 2^tier` | Operator (owner paid BASE_BOND) |

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants