feat: implement BLE swarm registry system#99
Conversation
52bb4af to
538047d
Compare
401a465 to
483982d
Compare
…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
3bc4f36 to
540f23a
Compare
- 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
- 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
There was a problem hiding this comment.
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
__gapwas 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_v2does 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() == 16andcountryBond == 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, and0x \includes trailing characters. Consider rewriting the snippet so the0xargument is clean (e.g.,0xon 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.
- 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
LCOV of commit
|
- 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
There was a problem hiding this comment.
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
SwarmRegistryUniversalUpgradeableemitsSwarmRegisteredwith an extrafilterSizeargument, which changes the event signature/topic0 and makes this interface event incorrect for Universal deployments. Consider standardizing the event signature across implementations (e.g., adduint32 filterSizeto 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_v2does not “reduce” the parent contract’s__gap; the parent__gapremains 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__gapsize 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.
- Add ops/deploy_swarm_contracts_zksync.sh: Automated ZkSync Era deployment using Forge * Temporarily moves L1-incompatible contracts (SSTORE2/EXTCODECOPY) * Builds with zksolc compiler via --zksync flag * Supports dry-run and actual deployment modes * Tests deployment by calling view functions on proxies - Add ops/deploy_swarm_contracts_l1.sh: Automated L1 deployment using Forge * Deploys SwarmRegistryL1 with SSTORE2 support * Verifies contracts on Etherscan - Split Forge deployment scripts * script/DeploySwarmUpgradeable.s.sol: L1 only, deploys SwarmRegistryL1 * script/DeploySwarmUpgradeableZkSync.s.sol: ZkSync only, deploys SwarmRegistryUniversal - Update foundry.toml with zksolc profile - Add hardhat-deploy/DeploySwarmUpgradeable.ts for reference (uses Hardhat) - Update hardhat.config.ts with ZkSync optimization settings
…ackgrounded, reconstructable)
- Merge 8 doc files into spec/swarm-specification.md (zero info loss) - Add build.sh pipeline: Mermaid→PNG + md-to-pdf for styled A4 output - Add Specification-PDF CI job: builds PDF on PRs to main, uploads artifact - Replace README.md with slim index linking spec, ops guide, and iso data - Delete redundant files: assistant-guide, data-model, discovery, fleet-registration, iso3166-reference, lifecycle, maintenance, swarm-operations
Use npx puppeteer browsers install chrome instead of manually installing system packages (libasound2 renamed to libasound2t64 on Ubuntu 24.04).
Pass --no-sandbox via mmdc puppeteer config and md-to-pdf --launch-options when CI=true (GitHub Actions Ubuntu 24.04 has AppArmor restrictions on unprivileged user namespaces).
Root cause: Yarn v1 rewrites git+https:// to git+ssh:// in yarn.lock's resolved field, causing CI to fail. Added postinstall script to auto-normalize SSH URLs back to HTTPS. Removed unnecessary git config workaround from CI workflow. Changes: - Add postinstall script to normalize git+ssh:// → git+https:// - Remove Force git HTTPS steps from checks.yml (handled by postinstall now) - Fix yarn.lock to use HTTPS for matter-labs dependencies
BLE Swarm Registry System with Geographic Tiered Bonding
A complete BLE tag registry enabling decentralized device discovery using cryptographic membership proofs.
Core Contracts
BASE_BOND * 2^tier(local),*16for countrysetOperatorviauuidTotalTierBondstrackingRegistration Model
BASE_BOND + tierBondtierBondtierBondper regiontierBondtierBond, owner getsBASE_BONDDiscovery
buildHighestBondedUuidBundle: Priority-ordered bundle (up to 20 UUIDs)localInclusionHint,countryInclusionHint) for optimal tier selectionDocumentation
Complete technical specification in
src/swarms/doc/:Checklist