Skip to content

chore: normalize SPDX license headers to LGPL-3.0-only across src, script, test#2014

Open
0xDEnYO wants to merge 1 commit into
mainfrom
chore/spdx-license-header-sweep
Open

chore: normalize SPDX license headers to LGPL-3.0-only across src, script, test#2014
0xDEnYO wants to merge 1 commit into
mainfrom
chore/spdx-license-header-sweep

Conversation

@0xDEnYO

@0xDEnYO 0xDEnYO commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Which Linear task belongs to this PR?

EXSC-588

Why did I implement it this way?

Problem. [CONV:LICENSE] (.agents/rules/100-solidity-basics.md) mandates // SPDX-License-Identifier: LGPL-3.0-only as line 1 of our own .sol files, but 198 files under src/, script/, and test/ deviated (UNLICENSED, Unlicense, Unlicensed, MIT, doubled // // headers, missing SPDX lines, solhint directives above the header). Because new files are written by copying siblings — and in test/ roughly half the siblings were wrong — the prose rule kept losing (PR #1996 reintroduced two variants this way). This PR fixes the data and adds mechanical enforcement so the copy chain stops.

What was done.

  • Normalized 196 files to the exact LGPL header as line 1, immediately followed by pragma:
    • 190 files with a wrong SPDX on line 1 replaced (129 UNLICENSED, 49 Unlicense, 3 Unlicensed, 3 MIT, 5 doubled // // …LGPL-3.0-only, 1 doubled // // …MIT)
    • 3 gas-test files had no SPDX line at all → header inserted above pragma
    • 3 test files had // solhint-disable… as line 1 (two of them with Unlicense on line 2) → SPDX/pragma now first, directive moved below pragma (solhint file-level disables apply from their line onward and all long lines sit further down; verified with bunx solhint — 0 errors, 0 new warnings)
    • src/Helpers/ReentrancyGuard.sol + src/Helpers/Validatable.sol (part of the 190) additionally had /// @custom:version 1.0.0 between SPDX and pragma (forbidden by the rule) → moved into the contract-level NatSpec block
  • Vetted the src/ violations for external copies — per the rule, external copies retain their original license. Two are genuine external copies and were left untouched:
    • src/Periphery/LiFiDEXAggregator.sol — copy of SushiSwap RouteProcessor4.sol (pinned commit in its NatSpec); upstream first line verified as // SPDX-License-Identifier: UNLICENSED, so the current header IS the retained upstream license
    • src/Interfaces/ITokenMessenger.sol — Circle CCTP interface, Apache-2.0 with Circle copyright block
    • The other 11 src/ offenders all carry @author LI.FI NatSpec or are LiFi-authored facets/helpers → normalized to LGPL
  • Single source of truth for enforcement: script/utils/check-spdx-headers.sh holds the expected header and the external-copy allowlist. Both consumers call it, so the allowlist can't drift:
    • .agents/hooks/post-edit-validate.sh — agents editing a .sol under src/, script/, or test/ with a wrong first line now get a [CONV:LICENSE] warning echoed back immediately (non-blocking, like the existing solhint feedback)
    • .github/workflows/spdxLicenseChecker.yml — repo-wide check on every PR, so human edits (and HUSKY=0 commits) are caught too. Chose CI over the pre-commit hook: pre-commit is bypassable and already heavy; the check is a <1s grep in CI.

Verification.

  • bash script/utils/check-spdx-headers.sh repo-wide: clean
  • Negative tests: checker flags a deliberately broken file (exit 1) and stays silent on the allowlisted external copy; hook echoes the warning for a violating file and exits 0
  • forge build: exit 0
  • bun test (forge test --evm-version cancun): 1677/1678 passed; the single failure (EcoFacetTest.testBase_CanBridgeTokens_fuzzed) was a drpc Base RPC timeout, suite re-run green 43/43 — infrastructure flake, unrelated to header changes
  • Diff audited mechanically: every added line across all 196 .sol files is one of {LGPL header, relocated @custom:version 1.0.0, relocated solhint directive, blank line}; every removed line is one of the wrong header variants or a relocated directive
  • /pr-ready (local CodeRabbit): the full 199-file diff exceeds the CLI's 150-file hard limit, so the review was run scoped per directory over the three files carrying non-mechanical logic:
    • .agents/hooks/post-edit-validate.shNo findings ✔
    • .github/workflows/spdxLicenseChecker.ymlNo findings ✔
    • script/utils/check-spdx-headers.shnot completable locally — repeated attempts (5+ rounds over ~2h) hit the lifinance org's shared rolling CodeRabbit rate limit, never a code finding. It is a single self-contained bash validator, dry-run tested here (flags a deliberately broken header with exit 1, stays silent on the allowlisted external copy, passes repo-wide) and bash -n clean; its only caller, .agents/hooks/post-edit-validate.sh, reviewed clean above. Cloud CodeRabbit reviews it in CI as the safety net.
    • The 196 header-only .sol edits are outside the CodeRabbit review surface; they are covered by the scripted diff audit above (every added/removed line matched an expected header/directive pattern) and by the new CI check. Cloud CodeRabbit will also run in CI as the standard safety net.

Checklist before requesting a review

  • I have performed a self-review of my code
  • This pull request is as small as possible and only tackles one problem
  • I have run /pr-ready (local CodeRabbit) on this branch and resolved (or explicitly documented) all findings — see .agents/commands/pr-ready.md
  • I have added tests that cover the functionality / test the bug
  • For new facets: I have checked all points from this list: https://www.notion.so/lifi/New-Facet-Contract-Checklist-157f0ff14ac78095a2b8f999d655622e
  • I have updated any required documentation

Checklist for reviewer (DO NOT DEPLOY and contracts BEFORE CHECKING THIS!!!)

  • I have checked that any arbitrary calls to external contracts are validated and or restricted
  • I have checked that any privileged calls (i.e. storage modifications) are validated and or restricted
  • I have ensured that any new contracts have had AT A MINIMUM 1 preliminary audit conducted on by <company/auditor>

…ript, test

Per [CONV:LICENSE] every own .sol file must start with the exact LGPL header
immediately followed by pragma. 196 files violated this (UNLICENSED/Unlicense/
Unlicensed/MIT variants, doubled headers, missing SPDX lines, directives above
the header) and kept propagating because new files are created by copying
siblings.

- normalize all 196 violations; external copies keep their upstream license:
  LiFiDEXAggregator.sol (Sushi RouteProcessor4, UNLICENSED) and
  ITokenMessenger.sol (Circle CCTP, Apache-2.0)
- add script/utils/check-spdx-headers.sh as single source of truth (incl.
  external-copy allowlist)
- post-edit hook warns agents on wrong first lines (src/, script/, test/)
- new spdxLicenseChecker.yml CI workflow enforces repo-wide on every PR

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@lifi-action-bot lifi-action-bot marked this pull request as draft July 2, 2026 11:14
@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Too many files!

This PR contains 199 files, which is 49 over the limit of 150.

To get a review, narrow the scope:
• coderabbit review --type committed # exclude uncommitted changes
• coderabbit review --dir # limit to a subdirectory
• coderabbit review --base # compare against a closer base

Upgrade to a paid plan to raise the limit.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: c2ae2b9e-d850-4249-86e9-d8c197c66162

📥 Commits

Reviewing files that changed from the base of the PR and between a5bd281 and 0663bdb.

📒 Files selected for processing (199)
  • .agents/hooks/post-edit-validate.sh
  • .github/workflows/spdxLicenseChecker.yml
  • script/deploy/facets/DeployAccessManagerFacet.s.sol
  • script/deploy/facets/DeployAcrossFacet.s.sol
  • script/deploy/facets/DeployAcrossFacetPacked.s.sol
  • script/deploy/facets/DeployAcrossFacetPackedV3.s.sol
  • script/deploy/facets/DeployAcrossFacetV3.s.sol
  • script/deploy/facets/DeployAllBridgeFacet.s.sol
  • script/deploy/facets/DeployArbitrumBridgeFacet.s.sol
  • script/deploy/facets/DeployCBridgeFacet.s.sol
  • script/deploy/facets/DeployCBridgeFacetPacked.s.sol
  • script/deploy/facets/DeployCREATE3Factory.s.sol
  • script/deploy/facets/DeployCalldataVerificationFacet.s.sol
  • script/deploy/facets/DeployChainflipFacet.s.sol
  • script/deploy/facets/DeployDeBridgeDlnFacet.s.sol
  • script/deploy/facets/DeployDiamondCutFacet.s.sol
  • script/deploy/facets/DeployDiamondLoupeFacet.s.sol
  • script/deploy/facets/DeployERC20Proxy.s.sol
  • script/deploy/facets/DeployEmergencyPauseFacet.s.sol
  • script/deploy/facets/DeployExecutor.s.sol
  • script/deploy/facets/DeployFeeCollector.s.sol
  • script/deploy/facets/DeployGasZipFacet.s.sol
  • script/deploy/facets/DeployGasZipPeriphery.s.sol
  • script/deploy/facets/DeployGenericSwapFacet.s.sol
  • script/deploy/facets/DeployGenericSwapFacetV3.s.sol
  • script/deploy/facets/DeployGnosisBridgeFacet.s.sol
  • script/deploy/facets/DeployHopFacet.s.sol
  • script/deploy/facets/DeployHopFacetOptimized.s.sol
  • script/deploy/facets/DeployHopFacetPacked.s.sol
  • script/deploy/facets/DeployLiFiDEXAggregator.s.sol
  • script/deploy/facets/DeployLiFiDiamond.s.sol
  • script/deploy/facets/DeployLidoWrapper.s.sol
  • script/deploy/facets/DeployMayanFacet.s.sol
  • script/deploy/facets/DeployOmniBridgeFacet.s.sol
  • script/deploy/facets/DeployOptimismBridgeFacet.s.sol
  • script/deploy/facets/DeployOwnershipFacet.s.sol
  • script/deploy/facets/DeployPatcher.s.sol
  • script/deploy/facets/DeployPeripheryRegistryFacet.s.sol
  • script/deploy/facets/DeployPermit2Proxy.s.sol
  • script/deploy/facets/DeployPolygonBridgeFacet.s.sol
  • script/deploy/facets/DeployReceiverAcrossV3.s.sol
  • script/deploy/facets/DeployReceiverChainflip.s.sol
  • script/deploy/facets/DeployReceiverStargateV2.s.sol
  • script/deploy/facets/DeploySquidFacet.s.sol
  • script/deploy/facets/DeployStargateFacetV2.s.sol
  • script/deploy/facets/DeploySymbiosisFacet.s.sol
  • script/deploy/facets/DeployThorSwapFacet.s.sol
  • script/deploy/facets/DeployWhitelistManagerFacet.s.sol
  • script/deploy/facets/DeployWithdrawFacet.s.sol
  • script/deploy/facets/UpdateAcrossFacet.s.sol
  • script/deploy/facets/UpdateAcrossFacetPacked.s.sol
  • script/deploy/facets/UpdateAcrossFacetPackedV3.s.sol
  • script/deploy/facets/UpdateAcrossFacetV3.s.sol
  • script/deploy/facets/UpdateAllBridgeFacet.s.sol
  • script/deploy/facets/UpdateArbitrumBridgeFacet.s.sol
  • script/deploy/facets/UpdateCBridgeFacet.s.sol
  • script/deploy/facets/UpdateCBridgeFacetPacked.s.sol
  • script/deploy/facets/UpdateCalldataVerificationFacet.s.sol
  • script/deploy/facets/UpdateCelerCircleBridgeFacet.s.sol
  • script/deploy/facets/UpdateChainflipFacet.s.sol
  • script/deploy/facets/UpdateDeBridgeDlnFacet.s.sol
  • script/deploy/facets/UpdateEmergencyPauseFacet.s.sol
  • script/deploy/facets/UpdateGasZipFacet.s.sol
  • script/deploy/facets/UpdateGenericSwapFacet.s.sol
  • script/deploy/facets/UpdateGenericSwapFacetV3.s.sol
  • script/deploy/facets/UpdateGlacisFacet.s.sol
  • script/deploy/facets/UpdateGnosisBridgeFacet.s.sol
  • script/deploy/facets/UpdateHopFacet.s.sol
  • script/deploy/facets/UpdateHopFacetOptimized.s.sol
  • script/deploy/facets/UpdateHopFacetPacked.s.sol
  • script/deploy/facets/UpdateMayanFacet.s.sol
  • script/deploy/facets/UpdateOmniBridgeFacet.s.sol
  • script/deploy/facets/UpdateOptimismBridgeFacet.s.sol
  • script/deploy/facets/UpdateOwnershipFacet.s.sol
  • script/deploy/facets/UpdatePioneerFacet.s.sol
  • script/deploy/facets/UpdatePolygonBridgeFacet.s.sol
  • script/deploy/facets/UpdateSquidFacet.s.sol
  • script/deploy/facets/UpdateStargateFacetV2.s.sol
  • script/deploy/facets/UpdateSymbiosisFacet.s.sol
  • script/deploy/facets/UpdateThorSwapFacet.s.sol
  • script/deploy/facets/utils/DeployScriptBase.sol
  • script/deploy/facets/utils/ScriptBase.sol
  • script/deploy/facets/utils/UpdateScriptBase.sol
  • script/deploy/zksync/DeployAccessManagerFacet.zksync.s.sol
  • script/deploy/zksync/DeployAcrossFacetPackedV3.zksync.s.sol
  • script/deploy/zksync/DeployAcrossFacetV3.zksync.s.sol
  • script/deploy/zksync/DeployCalldataVerificationFacet.zksync.s.sol
  • script/deploy/zksync/DeployDiamondCutFacet.zksync.s.sol
  • script/deploy/zksync/DeployDiamondLoupeFacet.zksync.s.sol
  • script/deploy/zksync/DeployERC20Proxy.zksync.s.sol
  • script/deploy/zksync/DeployEmergencyPauseFacet.zksync.s.sol
  • script/deploy/zksync/DeployExecutor.zksync.s.sol
  • script/deploy/zksync/DeployFeeCollector.zksync.s.sol
  • script/deploy/zksync/DeployGasZipFacet.zksync.s.sol
  • script/deploy/zksync/DeployGasZipPeriphery.zksync.s.sol
  • script/deploy/zksync/DeployGenericSwapFacet.zksync.s.sol
  • script/deploy/zksync/DeployGenericSwapFacetV3.zksync.s.sol
  • script/deploy/zksync/DeployLiFiDEXAggregator.zksync.s.sol
  • script/deploy/zksync/DeployLiFiDiamond.zksync.s.sol
  • script/deploy/zksync/DeployOwnershipFacet.zksync.s.sol
  • script/deploy/zksync/DeployPeripheryRegistryFacet.zksync.s.sol
  • script/deploy/zksync/DeployPermit2Proxy.zksync.s.sol
  • script/deploy/zksync/DeployReceiverAcrossV3.zksync.s.sol
  • script/deploy/zksync/DeployReceiverStargateV2.zksync.s.sol
  • script/deploy/zksync/DeployStargateFacetV2.zksync.s.sol
  • script/deploy/zksync/DeploySymbiosisFacet.zksync.s.sol
  • script/deploy/zksync/DeployWhitelistManagerFacet.zksync.s.sol
  • script/deploy/zksync/DeployWithdrawFacet.zksync.s.sol
  • script/deploy/zksync/UpdateAcrossFacetPackedV3.zksync.s.sol
  • script/deploy/zksync/UpdateAcrossFacetV3.zksync.s.sol
  • script/deploy/zksync/UpdateEmergencyPauseFacet.zksync.s.sol
  • script/deploy/zksync/UpdateGasZipFacet.zksync.s.sol
  • script/deploy/zksync/UpdateGenericSwapFacetV3.zksync.s.sol
  • script/deploy/zksync/utils/DeployScriptBase.sol
  • script/deploy/zksync/utils/ScriptBase.sol
  • script/deploy/zksync/utils/UpdateScriptBase.sol
  • script/tasks/solidity/AddBridgesForHopToDiamond.s.sol
  • script/tasks/solidity/AddTokenApprovalsForHopToDiamond.s.sol
  • script/tasks/solidity/AddTokenApprovalsToAcrossFacetPacked.s.sol
  • script/tasks/solidity/AddTokenApprovalsToAcrossFacetPackedV3.s.sol
  • script/tasks/solidity/AddTokenApprovalsToCBridgeFacetPacked.s.sol
  • script/tasks/solidity/AddTokenApprovalsToHopFacetPacked.s.sol
  • script/tasks/solidity/ApproveRefundWalletInDiamond.s.sol
  • script/tasks/solidity/CheckExecutorAndReceiver.s.sol
  • script/utils/check-spdx-headers.sh
  • src/Facets/HopFacetPacked.sol
  • src/Helpers/ReentrancyGuard.sol
  • src/Helpers/Validatable.sol
  • src/Interfaces/IAlgebraFactory.sol
  • src/Interfaces/IAlgebraPool.sol
  • src/Interfaces/ISyncSwapPool.sol
  • src/Interfaces/ISyncSwapVault.sol
  • src/Interfaces/IiZiSwapPool.sol
  • src/Libraries/LibAsset.sol
  • src/Periphery/FeeCollector.sol
  • src/Periphery/LidoWrapper.sol
  • test/solidity/Facets/AccessManagerFacet.t.sol
  • test/solidity/Facets/Across/V1/AcrossFacet.t.sol
  • test/solidity/Facets/Across/V1/AcrossFacetPacked.t.sol
  • test/solidity/Facets/Across/V3/AcrossFacetPackedV3.t.sol
  • test/solidity/Facets/Across/V3/AcrossFacetV3.t.sol
  • test/solidity/Facets/AllBridgeFacet.t.sol
  • test/solidity/Facets/ArbitrumBridgeFacet.t.sol
  • test/solidity/Facets/CBridge/CBridge.t.sol
  • test/solidity/Facets/CBridge/CBridgeAndFeeCollection.t.sol
  • test/solidity/Facets/CBridge/CBridgeFacetPacked.t.sol
  • test/solidity/Facets/CBridge/CBridgeRefund.t.sol
  • test/solidity/Facets/ChainflipFacet.t.sol
  • test/solidity/Facets/DeBridgeDlnFacet.t.sol
  • test/solidity/Facets/EmergencyPauseFacet/EmergencyPauseFacet.fork.t.sol
  • test/solidity/Facets/EmergencyPauseFacet/EmergencyPauseFacet.local.t.sol
  • test/solidity/Facets/GasZipFacet.t.sol
  • test/solidity/Facets/GenericSwapFacet.t.sol
  • test/solidity/Facets/GenericSwapFacetV3.t.sol
  • test/solidity/Facets/GlacisFacet.t.sol
  • test/solidity/Facets/GnosisBridgeFacet.t.sol
  • test/solidity/Facets/HopFacet.t.sol
  • test/solidity/Facets/HopFacetOptimized/HopFacetOptimizedL1.t.sol
  • test/solidity/Facets/HopFacetOptimized/HopFacetOptimizedL2.t.sol
  • test/solidity/Facets/HopFacetPacked/HopFacetPackedL1.t.sol
  • test/solidity/Facets/HopFacetPacked/HopFacetPackedL2.t.sol
  • test/solidity/Facets/MayanFacet.t.sol
  • test/solidity/Facets/OmniBridgeFacet/OmniBridgeFacet.t.sol
  • test/solidity/Facets/OmniBridgeFacet/OmniBridgeL2Facet.t.sol
  • test/solidity/Facets/OptimismBridgeFacet.t.sol
  • test/solidity/Facets/OwnershipFacet.t.sol
  • test/solidity/Facets/PolygonBridgeFacet.t.sol
  • test/solidity/Facets/SquidFacet.t.sol
  • test/solidity/Facets/StargateFacetV2.t.sol
  • test/solidity/Facets/SymbiosisFacet.t.sol
  • test/solidity/Facets/ThorSwapFacet.t.sol
  • test/solidity/Gas/CBridgeFacetPackedARB.gas.t.sol
  • test/solidity/Gas/CBridgeFacetPackedETH.gas.t.sol
  • test/solidity/Gas/Hop.t.sol
  • test/solidity/Helpers/SwapperV2.t.sol
  • test/solidity/LiFiDiamond.t.sol
  • test/solidity/Periphery/Across/V3/ReceiverAcrossV3.t.sol
  • test/solidity/Periphery/ERC20Proxy.t.sol
  • test/solidity/Periphery/Executor.t.sol
  • test/solidity/Periphery/FeeCollector.t.sol
  • test/solidity/Periphery/GasZipPeriphery.t.sol
  • test/solidity/Periphery/LiFiDEXAggregator.t.sol
  • test/solidity/Periphery/LidoWrapper/LidoWrapper.t.sol
  • test/solidity/Periphery/LidoWrapper/LidoWrapperSON.t.sol
  • test/solidity/Periphery/LidoWrapper/LidoWrapperUNI.t.sol
  • test/solidity/Periphery/ReceiverChainflip.t.sol
  • test/solidity/Periphery/ReceiverStargateV2.t.sol
  • test/solidity/utils/DeployPeripheryHelpers.sol
  • test/solidity/utils/DiamondTest.sol
  • test/solidity/utils/Interfaces.sol
  • test/solidity/utils/MockLiquidityBridge.sol
  • test/solidity/utils/MockTokenFeeOnTransfer.sol
  • test/solidity/utils/MockUniswapDEX.sol
  • test/solidity/utils/TestAMM.sol
  • test/solidity/utils/TestBase.sol
  • test/solidity/utils/TestBaseFacet.sol
  • test/solidity/utils/TestHelpers.sol
  • test/solidity/utils/TestToken.sol
  • test/solidity/utils/TestWrappedToken.sol

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/spdx-license-header-sweep

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added the requires-types Trigger Types Bindings CI (ABI/type generation for lifi-contract-types) label Jul 2, 2026
@lifi-action-bot

Copy link
Copy Markdown
Collaborator

Test Coverage Report

Line Coverage: 89.98% (3386 / 3763 lines)
Function Coverage: 93.73% ( 524 / 559 functions)
Branch Coverage: 72.61% ( 623 / 858 branches)
Test coverage (89.98%) is above min threshold (89%). Check passed.

@0xDEnYO 0xDEnYO marked this pull request as ready for review July 3, 2026 01:17
@0xDEnYO 0xDEnYO enabled auto-merge (squash) July 3, 2026 01:17
@lifi-action-bot

lifi-action-bot commented Jul 3, 2026

Copy link
Copy Markdown
Collaborator

🤖 GitHub Action: Security Alerts Review 🔍

🟢 Dismissed Security Alerts with Comments
The following alerts were dismissed with proper comments:

🟢 View Alert - File: src/Periphery/FeeCollector.sol
🔹 Parameters passed to a constructor that are not validated for correct values may lead to contract creation in an undesired state. For more information, visit: http://detectors.olympixdevsectools.com/article/web3-vulnerability/no-parameter-validation-in-constructor
🔹 Dismiss Reason: Won't fix
🔹 Dismiss Comment: Legacy, wont fix

🟢 View Alert - File: src/Periphery/FeeCollector.sol
🔹 Functions restricted to a single owner may result in loss or abuse of contract functionality if the owner's private key is compromised. For more information, visit: http://detectors.olympixdevsectools.com/article/web3-vulnerability/owner-single-point-of-failure
🔹 Dismiss Reason: Won't fix
🔹 Dismiss Comment: Legacy, wont fix

🟢 View Alert - File: src/Periphery/FeeCollector.sol
🔹 Functions restricted to a single owner may result in loss or abuse of contract functionality if the owner's private key is compromised. For more information, visit: http://detectors.olympixdevsectools.com/article/web3-vulnerability/owner-single-point-of-failure
🔹 Dismiss Reason: Won't fix
🔹 Dismiss Comment: Legacy, wont fix

🟢 View Alert - File: src/Periphery/FeeCollector.sol
🔹 Contracts that can receive ether but cannot send it may lock value permanently. For more information, visit: http://detectors.olympixdevsectools.com/article/web3-vulnerability/locked-ether
🔹 Dismiss Reason: False positive
🔹 Dismiss Comment: withdraw function in parent contract

🟢 View Alert - File: src/Facets/HopFacetPacked.sol
🔹 Using send() without checking the return value may lead to silent failures of ether transmittal. For more information, visit: http://detectors.olympixdevsectools.com/article/web3-vulnerability/unchecked-send
🔹 Dismiss Reason: False positive
🔹 Dismiss Comment: This is not Ethereum's send function but a custom send function that does not have any return value

🟢 View Alert - File: src/Facets/HopFacetPacked.sol
🔹 Using send() without checking the return value may lead to silent failures of ether transmittal. For more information, visit: http://detectors.olympixdevsectools.com/article/web3-vulnerability/unchecked-send
🔹 Dismiss Reason: False positive
🔹 Dismiss Comment: This is not Ethereum's send function but a custom send function that does not have any return value

🟢 View Alert - File: src/Facets/HopFacetPacked.sol
🔹 Parameters passed to a constructor that are not validated for correct values may lead to contract creation in an undesired state. For more information, visit: http://detectors.olympixdevsectools.com/article/web3-vulnerability/no-parameter-validation-in-constructor
🔹 Dismiss Reason: Won't fix
🔹 Dismiss Comment: Legacy, wont fix

🟢 View Alert - File: src/Facets/HopFacetPacked.sol
🔹 Parameters passed to a constructor that are not validated for correct values may lead to contract creation in an undesired state. For more information, visit: http://detectors.olympixdevsectools.com/article/web3-vulnerability/no-parameter-validation-in-constructor
🔹 Dismiss Reason: Won't fix
🔹 Dismiss Comment: Legacy, wont fix

🟢 View Alert - File: src/Facets/HopFacetPacked.sol
🔹 Performing a narrowing downcast may result in silent overflow due to bit truncation. For more information, visit: http://detectors.olympixdevsectools.com/article/web3-vulnerability/unsafe-downcast
🔹 Dismiss Reason: Won't fix
🔹 Dismiss Comment: by design

🟢 View Alert - File: src/Facets/HopFacetPacked.sol
🔹 Performing a narrowing downcast may result in silent overflow due to bit truncation. For more information, visit: http://detectors.olympixdevsectools.com/article/web3-vulnerability/unsafe-downcast
🔹 Dismiss Reason: Won't fix
🔹 Dismiss Comment: by design

🟢 View Alert - File: src/Facets/HopFacetPacked.sol
🔹 Performing a narrowing downcast may result in silent overflow due to bit truncation. For more information, visit: http://detectors.olympixdevsectools.com/article/web3-vulnerability/unsafe-downcast
🔹 Dismiss Reason: Won't fix
🔹 Dismiss Comment: by design

🟢 View Alert - File: src/Facets/HopFacetPacked.sol
🔹 Performing a narrowing downcast may result in silent overflow due to bit truncation. For more information, visit: http://detectors.olympixdevsectools.com/article/web3-vulnerability/unsafe-downcast
🔹 Dismiss Reason: Won't fix
🔹 Dismiss Comment: by design

🟢 View Alert - File: src/Facets/HopFacetPacked.sol
🔹 Performing a narrowing downcast may result in silent overflow due to bit truncation. For more information, visit: http://detectors.olympixdevsectools.com/article/web3-vulnerability/unsafe-downcast
🔹 Dismiss Reason: Won't fix
🔹 Dismiss Comment: by design

🟢 View Alert - File: src/Facets/HopFacetPacked.sol
🔹 Performing a narrowing downcast may result in silent overflow due to bit truncation. For more information, visit: http://detectors.olympixdevsectools.com/article/web3-vulnerability/unsafe-downcast
🔹 Dismiss Reason: Won't fix
🔹 Dismiss Comment: by design

🟢 View Alert - File: src/Facets/HopFacetPacked.sol
🔹 Performing a narrowing downcast may result in silent overflow due to bit truncation. For more information, visit: http://detectors.olympixdevsectools.com/article/web3-vulnerability/unsafe-downcast
🔹 Dismiss Reason: Won't fix
🔹 Dismiss Comment: by design

🟢 View Alert - File: src/Facets/HopFacetPacked.sol
🔹 Performing a narrowing downcast may result in silent overflow due to bit truncation. For more information, visit: http://detectors.olympixdevsectools.com/article/web3-vulnerability/unsafe-downcast
🔹 Dismiss Reason: Won't fix
🔹 Dismiss Comment: by design

🟢 View Alert - File: src/Facets/HopFacetPacked.sol
🔹 Performing a narrowing downcast may result in silent overflow due to bit truncation. For more information, visit: http://detectors.olympixdevsectools.com/article/web3-vulnerability/unsafe-downcast
🔹 Dismiss Reason: Won't fix
🔹 Dismiss Comment: by design

🟢 View Alert - File: src/Facets/HopFacetPacked.sol
🔹 Performing a narrowing downcast may result in silent overflow due to bit truncation. For more information, visit: http://detectors.olympixdevsectools.com/article/web3-vulnerability/unsafe-downcast
🔹 Dismiss Reason: Won't fix
🔹 Dismiss Comment: by design

🟢 View Alert - File: src/Facets/HopFacetPacked.sol
🔹 Performing a narrowing downcast may result in silent overflow due to bit truncation. For more information, visit: http://detectors.olympixdevsectools.com/article/web3-vulnerability/unsafe-downcast
🔹 Dismiss Reason: Won't fix
🔹 Dismiss Comment: by design

🟢 View Alert - File: src/Facets/HopFacetPacked.sol
🔹 Performing a narrowing downcast may result in silent overflow due to bit truncation. For more information, visit: http://detectors.olympixdevsectools.com/article/web3-vulnerability/unsafe-downcast
🔹 Dismiss Reason: Won't fix
🔹 Dismiss Comment: by design

🟢 View Alert - File: src/Facets/HopFacetPacked.sol
🔹 Reentrant functions which emit events after making an external call may lead to out-of-order events. For more information, visit: http://detectors.olympixdevsectools.com/article/web3-vulnerability/reentrancy-events
🔹 Dismiss Reason: Won't fix
🔹 Dismiss Comment: known, not a risk

🟢 View Alert - File: src/Facets/HopFacetPacked.sol
🔹 Reentrant functions which emit events after making an external call may lead to out-of-order events. For more information, visit: http://detectors.olympixdevsectools.com/article/web3-vulnerability/reentrancy-events
🔹 Dismiss Reason: Won't fix
🔹 Dismiss Comment: known, not a risk

🟢 View Alert - File: src/Facets/HopFacetPacked.sol
🔹 Reentrant functions which emit events after making an external call may lead to out-of-order events. For more information, visit: http://detectors.olympixdevsectools.com/article/web3-vulnerability/reentrancy-events
🔹 Dismiss Reason: Won't fix
🔹 Dismiss Comment: known, not a risk

🟢 View Alert - File: src/Facets/HopFacetPacked.sol
🔹 Reentrant functions which emit events after making an external call may lead to out-of-order events. For more information, visit: http://detectors.olympixdevsectools.com/article/web3-vulnerability/reentrancy-events
🔹 Dismiss Reason: Won't fix
🔹 Dismiss Comment: known, not a risk

🟢 View Alert - File: src/Facets/HopFacetPacked.sol
🔹 Reentrant functions which emit events after making an external call may lead to out-of-order events. For more information, visit: http://detectors.olympixdevsectools.com/article/web3-vulnerability/reentrancy-events
🔹 Dismiss Reason: Won't fix
🔹 Dismiss Comment: known, not a risk

🟢 View Alert - File: src/Facets/HopFacetPacked.sol
🔹 Reentrant functions which emit events after making an external call may lead to out-of-order events. For more information, visit: http://detectors.olympixdevsectools.com/article/web3-vulnerability/reentrancy-events
🔹 Dismiss Reason: Won't fix
🔹 Dismiss Comment: known, not a risk

🟢 View Alert - File: src/Facets/HopFacetPacked.sol
🔹 Reentrant functions which emit events after making an external call may lead to out-of-order events. For more information, visit: http://detectors.olympixdevsectools.com/article/web3-vulnerability/reentrancy-events
🔹 Dismiss Reason: Won't fix
🔹 Dismiss Comment: known, not a risk

🟢 View Alert - File: src/Facets/HopFacetPacked.sol
🔹 Reentrant functions which emit events after making an external call may lead to out-of-order events. For more information, visit: http://detectors.olympixdevsectools.com/article/web3-vulnerability/reentrancy-events
🔹 Dismiss Reason: Won't fix
🔹 Dismiss Comment: known, not a risk

🟢 View Alert - File: src/Facets/HopFacetPacked.sol
🔹 Functions restricted to a single owner may result in loss or abuse of contract functionality if the owner's private key is compromised. For more information, visit: http://detectors.olympixdevsectools.com/article/web3-vulnerability/owner-single-point-of-failure
🔹 Dismiss Reason: Won't fix
🔹 Dismiss Comment: guarded by multisig

🟢 View Alert - File: src/Libraries/LibAsset.sol
🔹 Calling transferFrom functionality with a parameterized from value may lead to theft or loss of tokens. For more information, visit: http://detectors.olympixdevsectools.com/article/web3-vulnerability/arbitrary-transfer-from
🔹 Dismiss Reason: Won't fix
🔹 Dismiss Comment: This is a library and it's by design that the function is generic.

No unresolved security alerts! 🎉

@lifi-action-bot lifi-action-bot marked this pull request as draft July 3, 2026 03:26
auto-merge was automatically disabled July 3, 2026 03:26

Pull request was converted to draft

@0xDEnYO 0xDEnYO marked this pull request as ready for review July 3, 2026 03:59
@lifi-action-bot lifi-action-bot marked this pull request as draft July 3, 2026 03:59
@0xDEnYO 0xDEnYO marked this pull request as ready for review July 3, 2026 03:59
@0xDEnYO 0xDEnYO enabled auto-merge (squash) July 3, 2026 03:59
@gvladika

gvladika commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Review

Verified the mechanics against the branch directly.

Correct and well done:

  • Diff is exactly as advertised: 190 pure 1:1 header swaps + the 8 documented special cases, nothing else hiding in a 199-file diff.
  • Branch is self-consistent with its own checker — scanned every .sol first line on the branch; the only two non-LGPL files are precisely the two allowlisted external copies, whose upstream licenses (UNLICENSED / Apache-2.0) I confirmed.
  • Good engineering: one source of truth shared by hook + CI (allowlist can't drift), workflow uses default-deny permissions: {} + job-level contents: read, SHA-pinned checkout with persist-credentials: false.
  • Checker is bash -n clean; is_external_copy … && continue is safe under set -e (it's in an && list), and "${FILES[@]:-}" handles nounset.

Main finding — enforcement only closes half the rule:

[CONV:LICENSE] has two parts: (1) line 1 = the LGPL header, and (2) it must be immediately followed by pragma — no blank line, no comment/directive/NatSpec in between. The new checker only validates line 1 (PR documents this as a known limitation).

The gap is real. Scanning line 2 of every .sol on the branch, ~33 of our own files still violate part (2) and CI won't catch them:

  • ~23 with a blank line between SPDX and pragma — e.g. src/Facets/EcoFacet.sol, GardenFacet.sol, LiFiIntentEscrowFacet.sol, src/Periphery/TokenWrapper.sol, src/Interfaces/IEcoPortal.sol, several Deploy*/Update* scripts, and test utils (MockHTLC.sol, TestBasicToken.sol, …).
  • ~10 with /// @custom:version between SPDX and pragma — e.g. src/Helpers/TransferrableOwnership.sol, WithdrawablePeriphery.sol, src/Libraries/LibAccess.sol, LibBytes.sol, LibUtil.sol, OFTComposeMsgCodec.sol, src/Errors/GenericErrors.sol.

These are all pre-existing (untouched here — they already had LGPL on line 1), so this is not a regression. But it means the copy-chain problem this PR exists to kill is only half-closed: the PR establishes that @custom:version-between-SPDX-and-pragma is wrong (it moves it on the 2 files it touches), yet a new file copied from TransferrableOwnership.sol or EcoFacet.sol reintroduces exactly that violation and passes CI.

Cheap fix within the script's spirit: also assert line 2 is pragma solidity. That one extra check surfaces all ~33 at once — either fix them here (turns this into a full CONV:LICENSE sweep) or capture as an immediate follow-up so the second dimension doesn't quietly re-drift.

Minor / non-blocking:

  • Checker scans the whole tree on every PR (not diff-scoped). Right call — also catches pre-existing regressions — just noting it's sub-second but O(all .sol).
  • requires-types label triggers ABI/type generation, but header-only edits don't change any ABI. Harmless, just unnecessary CI work.

Verdict: Solid, mechanically sound, safe to merge for its stated scope (line-1 normalization + enforcement). One substantive recommendation: extend the checker to also enforce "line 2 = pragma" — otherwise the rule's second half stays unenforced and ~33 existing violations remain invisible to CI.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AuditNotRequired requires-types Trigger Types Bindings CI (ABI/type generation for lifi-contract-types)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants