Skip to content

Conversation

- Fix root test:coverage to use build:self:coverage for proper coverage artifacts
- Add build:coverage chain in issuance package for coverage-specific compilation
- Inline coverage script execution in test:coverage:self
- Remove scripts/coverage file (logic moved inline)

The original issue was that pnpm test:coverage reported incomplete coverage
after contract changes, requiring manual pnpm clean. This was caused by
coverage tests using regular build artifacts instead of coverage-specific
artifacts. The fix ensures coverage builds use the correct configuration
and generate proper artifacts automatically.
@RembrandtK RembrandtK self-assigned this Oct 8, 2025
@RembrandtK RembrandtK requested a review from Copilot October 8, 2025 21:31
Copy link
Contributor

@Copilot 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

This pull request introduces an Issuance Allocator system for The Graph protocol, providing a centralized mechanism for distributing token issuance to various protocol components. The PR includes comprehensive testing infrastructure, performance optimizations, and support for both allocator-minting and self-minting allocation models.

  • Implements the core IssuanceAllocator contract with pause/resume functionality and proportional token distribution
  • Adds supporting contracts including DirectAllocation targets and comprehensive test infrastructure
  • Introduces optimized test utilities and fixtures to reduce test execution time and code duplication

Reviewed Changes

Copilot reviewed 35 out of 36 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
packages/issuance/contracts/allocate/IssuanceAllocator.sol Core contract implementing proportional token issuance allocation with pause/resume functionality
packages/issuance/contracts/allocate/DirectAllocation.sol Simple target contract that receives and redistributes allocated tokens
packages/issuance/test/utils/testPatterns.ts Comprehensive test utilities and patterns to reduce duplication across test files
packages/issuance/test/utils/optimizedFixtures.ts Performance-optimized test fixtures for faster test execution
packages/issuance/test/tests/helpers/fixtures.ts Updated test fixtures with support for new issuance system contracts
packages/interfaces/contracts/issuance/allocate/ Interface definitions for issuance allocation system

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Copy link

openzeppelin-code bot commented Oct 8, 2025

[Preview] Issuance Allocator

Generated at commit: 7b0634bda699824d08146b798ca45f7563e058c7

🚨 Report Summary

Severity Level Results
Contracts Critical
High
Medium
Low
Note
Total
3
5
0
15
38
61
Dependencies Critical
High
Medium
Low
Note
Total
0
0
0
0
0
0

For more details view the full report in OpenZeppelin Code Inspector

Copy link

codecov bot commented Oct 8, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 85.96%. Comparing base (f2dca10) to head (7b0634b).

Additional details and impacted files
@@                       Coverage Diff                        @@
##           rewards-eligibility-oracle-2    #1236      +/-   ##
================================================================
+ Coverage                         83.69%   85.96%   +2.27%     
================================================================
  Files                                51       46       -5     
  Lines                              2183     2352     +169     
  Branches                            643      696      +53     
================================================================
+ Hits                               1827     2022     +195     
+ Misses                              356      330      -26     
Flag Coverage Δ
unittests 85.96% <100.00%> (+2.27%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

- Fix syntax errors in RewardsManager.sol (missing closing braces)
- Add missing IRewardsIssuer import
- Complete MockIssuanceAllocator implementation with all required methods
- Update interface declarations and parameter names for consistency
- Fix interface support tests for IRewardsManager

All IssuanceAllocator integration tests now passing (9/9)
Contract compilation successful with proper ERC165 interface support
- Add InterfaceIdExtractor contract for extracting ERC165 interface IDs
- Add Python script to generate TypeScript interface ID constants
- Update tests to use auto-generated interface IDs instead of manual calculation
- Add interface ID consistency verification test
- Integrate interface ID generation into build process

This follows the same pattern as the issuance package and ensures
interface IDs are always consistent with Solidity's calculations.
- Move InterfaceIdExtractor contract to interfaces package
- Move interface ID generation script to interfaces package
- Integrate interface ID generation into interfaces package build process
- Update contracts package to use interface IDs from interfaces package
- Remove local interface ID generation from contracts package
- Place generated interface IDs in src/types/interfaceIds.ts following package conventions

This centralizes interface ID generation in the interfaces package where it belongs,
making it available for all packages to use and eliminating duplication.
Lint Fixes:
- Restore missing NatSpec documentation for IRewardsIssuer interface
- Remove TODO comment from MockIssuanceAllocator
- Add solhint-disable for named-parameters-mapping rule (not supported in Solidity 0.7.6)

Interface ID Centralization:
- Add IIssuanceAllocator and IRewardsEligibilityOracle to interfaces package InterfaceIdExtractor
- Update interfaces package generation script to include all interface IDs
- Remove duplicate interface ID generation from issuance package:
  * Delete InterfaceIdExtractor.sol
  * Delete generateInterfaceIds.py script
  * Delete local interfaceIds.ts helper
  * Remove generate:interfaces script from package.json
- Update issuance package to import interface IDs from @graphprotocol/interfaces
- Simplify interface compliance tests (remove redundant consistency checks)

All lint checks now pass (0 warnings) and all tests pass (161/161).
Interface IDs are now centrally managed in the interfaces package for consistency.
- Convert require() statements to ES6 imports where possible
- Improve type safety in test utility functions
- Export previously unused functions in issuanceCalculations.ts
- Standardize import organization across test files
- Fix mixed import styles in test files
- Organize imports properly in commonTestUtils.ts

All tests pass (161/161) and linting is clean.
- Add README.md with package documentation including setup, build,
  test, and lint commands
- Remove LICENSE from package.json files array (consistent with
  majority of packages; root LICENSE covers monorepo)
- Add Contracts section with links to detailed documentation
- Reference IssuanceAllocator.md and RewardsEligibilityOracle.md
- Include brief descriptions of each contract's purpose
- Replace generateInterfaceIds.py with generateInterfaceIds.js to eliminate Python dependency
- Add automatic interface discovery via contract introspection - no more manual maintenance
- Move generated file to src/interfaceIds.ts for git version control
- Add timestamp checking to only regenerate when source files change
- Improve generated file with clear autogen warning and DRY const reuse
- Maintain succinct output: one line when generated, silent when up-to-date
- All tests continue to pass with new implementation
Split the monolithic IIssuanceAllocator interface into three focused
sub-interfaces following the Interface Segregation Principle:

- IIssuanceAllocationDistribution: Minimal interface for targets
  (RewardsManager only needs this)
- IIssuanceAllocationAdministration: Governor-only operations
- IIssuanceAllocationStatus: Read-only status queries

This reduces coupling and allows consumers to check only for the
specific interfaces they require via ERC-165. The combined interface
has been removed to enforce this pattern.

Changes:
- Add IIssuanceAllocatorTypes.sol for shared type definitions
- Add three new sub-interfaces
- Remove combined IIssuanceAllocator.sol
- Update IssuanceAllocator and MockIssuanceAllocator to implement
  all three sub-interfaces
- Update RewardsManager to check for IIssuanceAllocationDistribution
- Update InterfaceIdExtractor to expose three interface IDs
- Update all tests to check for correct sub-interfaces
Split the monolithic IRewardsEligibilityOracle interface into four focused
sub-interfaces following the Interface Segregation Principle:

- IRewardsEligibility: Minimal interface for consumers
  (RewardsManager only needs this)
- IRewardsEligibilityAdministration: OPERATOR_ROLE operations
- IRewardsEligibilityReporting: ORACLE_ROLE operations
- IRewardsEligibilityStatus: Read-only status queries

This reduces coupling and allows consumers to check only for the
specific interfaces they require via ERC-165. The combined interface
has been removed to enforce this pattern.

Changes:
- Add IRewardsEligibilityTypes.sol for shared event definitions
- Add four new sub-interfaces
- Remove combined IRewardsEligibilityOracle.sol
- Update RewardsEligibilityOracle to implement all four sub-interfaces
- Update RewardsManager to check for IRewardsEligibility
- Update MockRewardsEligibilityOracle to implement all four sub-interfaces
- Update InterfaceIdExtractor to expose four interface IDs
- Update all tests to check for correct sub-interfaces
- Update documentation
Add override keyword to functions in IssuanceAllocator and
RewardsEligibilityOracle that implement interface methods:

IssuanceAllocator:
- notifyTarget
- distributePendingIssuance (both overloads)

RewardsEligibilityOracle:
- setEligibilityPeriod
- setOracleUpdateTimeout
- setEligibilityValidation
- renewIndexerEligibility
- getEligibilityRenewalTime
- getEligibilityPeriod
- getOracleUpdateTimeout
- getLastOracleUpdateTime
- getEligibilityValidation

These functions all have @inheritdoc comments referencing their
interfaces but were missing the override keyword.
Add three new interfaces to provide complete ERC-165 coverage for
all public functionality in issuance package contracts:

- IPausableControl: pause/unpause/paused functions
  (for BaseUpgradeable and descendants)
- IIssuanceAllocationData: getTargetData function
  (for IssuanceAllocator)
- ISendTokens: sendTokens function
  (for DirectAllocation)

This enables external contracts to check for specific capabilities
via ERC-165, improves API clarity, and follows the pattern of
interface segregation already established.

Changes:
- Add IPausableControl, ISendTokens, IIssuanceAllocationData interfaces
- Update BaseUpgradeable to implement IPausableControl with ERC-165 support
- Update IssuanceAllocator to implement IIssuanceAllocationData
- Update DirectAllocation to implement ISendTokens
- Update InterfaceIdExtractor to expose three new interface IDs
- Add override keywords and @inheritdoc tags to implementations

Note: OpenZeppelin v5 AccessControlUpgradeable already implements and
exposes IAccessControl via ERC-165, so no additional work needed there.
Enhanced the verify-solhint-disables.js script with comprehensive
improvements and added a full test suite:

Script improvements:
- Properly handle multiline solhint-disable comments by collecting
  all consecutive disable lines instead of breaking after first
- Distinguish between pre-TODO disables (permanent architectural
  decisions) and TODO section disables (temporary fixes)
- Remove unnecessary rules from anywhere (pre-TODO or TODO sections)
- Add new rules only to TODO sections, preserving pre-TODO disables
- Find and use correct .solhint.json config file regardless of CWD
- Support running from any directory (monorepo root, package dir)
- Accept specific files/directories as arguments
- Handle blank lines correctly when removing disable comments
- Add comprehensive JSDoc documentation

Test suite (verify-solhint-disables.test.js):
- 16 extraction tests covering various file structures
- 5 fix function tests covering manipulation scenarios
- Tests for pre-TODO only, TODO only, and combined disables
- Tests for multiline and comma-separated rules
- Tests for adding/removing disable comments
- All 21 tests passing

This fixes issues where the script was:
- Only detecting the first solhint-disable line
- Using incorrect solhint config (default instead of project's)
- Not properly cleaning up unnecessary pre-TODO disables
- Leaving extra blank lines when removing disable comments
Removed the unnecessary 'gas-small-strings' rule from the
solhint-disable comment in MockIssuanceAllocator.sol as it is
not triggered by any actual linting issues in the file.

Also moved the disable comment before the pragma directive for
consistency with project style.

This change was automatically generated by the enhanced
verify-solhint-disables.js script with --fix flag.
Copy link

socket-security bot commented Oct 14, 2025

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Updated@​openzeppelin/​contracts@​3.4.1 ⏵ 3.4.210071 +469596 +4100
Added@​typescript-eslint/​parser@​8.46.11001007197100
Added@​typescript-eslint/​eslint-plugin@​8.46.1991008097100

View full report

RembrandtK and others added 2 commits October 14, 2025 10:54
Switch from non-upgradeable ERC165 to ERC165Upgradeable to properly
support interface detection in upgradeable contracts.

Key changes:
- Use ERC165Upgradeable instead of ERC165
- Call __ERC165_init_unchained() in initialize() for fresh deployments
- Add completeUpgrade() function for post-upgrade initialization
- Register all interfaces (IERC165, IIssuanceTarget, IRewardsManager) via
  _registerInterfaces() helper
- Remove supportsInterface() override - now handled by ERC165Upgradeable

Benefits:
- Eliminates 10 lines of boilerplate override code
- Proper initialization pattern for upgradeable contracts
- Interfaces stored in contract state vs hardcoded in logic
- More maintainable - adding interfaces just requires registration
- Follows OpenZeppelin best practices

For upgrades: Governor must call completeUpgrade() after deploying new
implementation to register interface support.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Replace ERC165Upgradeable inheritance with direct IERC165 implementation
to eliminate storage overhead, initialization dependencies, and upgrade
ceremony requirements.

Changes:
- Remove ERC165Upgradeable import and inheritance
- Inherit directly from IERC165 interface
- Remove __ERC165_init_unchained() call from initialize()
- Remove completeUpgrade() and _registerInterfaces() functions
- Implement supportsInterface() with explicit interface checks

Benefits:
- Zero storage overhead (no _supportedInterfaces mapping)
- Zero initialization dependencies
- Zero upgrade ceremony (no need to call completeUpgrade)
- Simpler, more maintainable code
- Same functionality as OpenZeppelin v5 pattern

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
RembrandtK and others added 15 commits October 14, 2025 12:03
- Update @openzeppelin/contracts from 3.4.1 to 3.4.2 in all packages
- Verified 98 contracts across 4 packages show no functional differences
- Only metadata hashes changed as expected

Package updates:
- packages/contracts/package.json
- packages/interfaces/package.json
- packages/token-distribution/package.json
- packages/contracts/task/package.json
- packages/contracts/test/package.json

Script improvements:
- Add compare-repo-contract-bytecode-excluding-metadata.py for reliable repo comparisons
- Remove obsolete bytecode-diff-no-metadata.sh script

Verification completed:
- contracts: 55 contracts ✅ functionally identical
- token-distribution: 20 contracts ✅ functionally identical
- horizon: 33 contracts ✅ functionally identical
- subgraph-service: 12 contracts ✅ functionally identical
- Convert TODO check from bash to Python and remove from pre-commit
- Update coverage path for contracts package
- Centralize coverage detection with type-safe helper
- Fix horizon minimum delegation requirement in slash test
- Add incremental build logic to avoid unnecessary rebuilding
- Upgrade OpenZeppelin contracts from v3.4.1 to v3.4.2
- Update ethereumjs-util dependency in lock file
- Replace @graphql-mesh/utils with local gql implementation
- Add test:coverage script to packages/contracts
Replace Python-based TODO checker with a Node.js implementation to
eliminate Python as a build dependency.

Changes:
- Add scripts/check-todos.mjs (ES module, no dependencies)
- Remove scripts/check_todos.py
- Update package.json to use Node.js version

The new script:
- Uses native Node.js APIs (no external dependencies)
- Maintains identical functionality to Python version
- Works with git-changed files by default
- Supports checking specific files when provided as arguments
Replace Python-based bytecode comparison tool with Node.js implementation
to eliminate Python as a dependency.

Changes:
- Add scripts/compare-repo-contract-bytecode-excluding-metadata.mjs
- Remove scripts/compare-repo-contract-bytecode-excluding-metadata.py

The new script:
- Uses native Node.js APIs (no external dependencies)
- Maintains identical functionality to Python version
- Compares contract artifacts between two repo directories
- Strips metadata hashes to focus on functional differences
- Useful for verifying dependency upgrades don't affect bytecode

This completes the removal of Python from the repository's build and
developer tooling.
…dules

Convert verify-solhint-disables scripts from CommonJS (.js) to ES modules
(.mjs) for consistency with other scripts in the repository.

Changes:
- Rename verify-solhint-disables.js → verify-solhint-disables.mjs
- Rename verify-solhint-disables.test.js → verify-solhint-disables.test.mjs
- Convert require() → import statements
- Convert module.exports → export statements
- Add __filename/__dirname shims for ES modules
- Update entry point detection for ES modules

All tests pass (21/21). Functionality remains identical.

This completes the modernization of all scripts to use ES modules,
providing a consistent codebase using modern JavaScript standards.
Standardize package.json files across the monorepo for consistency:

- Update author to "Edge & Node" across all packages
- Reorder fields to follow consistent pattern (version, publishConfig,
  description, author, license, then exports/main/scripts)
- Move scripts section before dependencies where applicable
- Add .solhint.json config files to horizon and subgraph-service packages
- Update lint:sol scripts to use local .solhint.json (instead of root config)
- Add missing descriptions to horizon and subgraph-service packages
- Add publishConfig to issuance package
Move skipped issuance-related tests into dedicated test files:
- rewards-issuance-allocator.test.ts: Tests for issuance allocator integration
- rewards-eligibility-oracle.test.ts: Tests for rewards eligibility oracle
- rewards-interface-support.test.ts: Tests for ERC165 interface support

Changes:
- Extract 10 skipped tests for issuance allocator functionality
- Extract 8 skipped tests for rewards eligibility oracle
- Extract 7 skipped tests for interface support (IIssuanceTarget, IRewardsManager, IERC165)
- Remove commented-out setIssuanceAllocator call from rewards.test.ts
- Add proper reset logic to issuance allocator tests
- Clean up unused imports and variables in all test files

These tests are currently skipped as they depend on issuance package
functionality not yet merged into this branch.
Merged rewardsManager.setIssuanceAllocator.test.ts into
rewards-issuance-allocator.test.ts to eliminate duplication while
preserving all test coverage.

The combined file organizes 14 tests into logical groups:
- setIssuanceAllocator: ERC-165 validation, access control, state mgmt
- getRewardsIssuancePerBlock: behavior with/without allocator
- setIssuancePerBlock: interaction with allocator
- beforeIssuanceAllocationChange: lifecycle hook

Eliminated duplicate tests:
- Setting to zero address
- IssuanceAllocatorSet event emission
- Governor-only access control
- Setting same allocator twice (no-op)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
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.

1 participant