| H-01 Slither + Aderyn | SaucerSwap LP admin reentrancy ordering createLPPosition / increaseLPPosition update storage after external SaucerSwap calls. Slither reentrancy-eth; Aderyn H-2. Why acceptedThese functions are onlyOwner and nonReentrant. The external caller is the configured SaucerSwap NFT manager — a trusted protocol contract, not arbitrary users. There is no practical reentrancy attack path for depositors; reordering to strict checks-effects-interactions would be a style improvement, not a security fix. SaucerSwapLiquidityStrategy.sol | ● high | SaucerSwapLiquidityStrategy.sol | Accepted |
| H-02 Aderyn | Payable contracts lock native HBAR LynxVault, LynxHTSBridge, and SaucerSwapLiquidityStrategy accept native value without a generic withdraw() sweep. Aderyn H-1. Why acceptedThe vault and bridge must receive HBAR for depositHbar and depositHbarAndWrap. The LP strategy holds HBAR for SaucerSwap V2 NFT mint/increase fees. User funds are not trapped — the missing sweep only affects residual operational dust, which governance can recover later if needed. LynxVault.sol · LynxHTSBridge.sol · SaucerSwapLiquidityStrategy.sol | ● high | LynxVault.sol · LynxHTSBridge.sol · SaucerSwapLiquidityStrategy.sol | Accepted |
| H-03 Slither | Arbitrary-send-eth on staking wrap Slither arbitrary-send-eth: LynxKeeperRouter sends native HBAR to configured WHBAR helper during staking harvest wrap. Why acceptedThe recipient is a governance-configured WHBAR helper contract, not an arbitrary user address. This is required for the staking harvest unwrap/wrap path. Access is keeper-only on the harvest functions. LynxKeeperRouter.sol | ● high | LynxKeeperRouter.sol | Accepted |
| H-04 Aderyn | FullMath caret operator (Aderyn H-2) Aderyn flags Uniswap V3 FullMath.sol for incorrect use of the caret operator. Why false positiveFalse positive. FullMath is the standard Uniswap V3 library; the flagged operator is bitwise XOR in fixed-point math, not Solidity exponentiation. Included in scope for LP mark-to-market helpers only. libraries/FullMath.sol | ● high | libraries/FullMath.sol | False positive |
| H-05 Aderyn | Weak randomness on schedule probing Aderyn H-5 flags prevrandao / pseudo-random slot probing in LynxKeeperRouter schedule discovery. Why acceptedAccepted. _findAvailableSecond uses bounded prevrandao jitter to discover HIP-1215 schedule slots. Failure is non-reverting with ScheduleFailed events; health CI monitors mirror logs. LynxKeeperRouter.sol | ● high | LynxKeeperRouter.sol | Accepted |
| R-01 Slither | Harvest return values unused (Slither) Slither unused-return on harvestLp / harvestStaking manager return values before fix. Why resolvedResolved by emitting HarvestCompleted events that include the manager return values. Closes the unused-return finding; +2 Low reentrancy-events on the same paths are accepted (observability events post-call). LynxKeeperRouter.sol — harvestLp / harvestStaking | ● medium | LynxKeeperRouter.sol — harvestLp / harvestStaking | Resolved |
| R-02 Aderyn | LpAllocatorSet event missing (Aderyn L-7) Aderyn flagged setLpAllocator state change without an event. Why resolvedResolved by adding LpAllocatorSet event on setLpAllocator. Improves ops observability and closes the Aderyn L-7 theme. LynxKeeperRouter.setLpAllocator() | ● low | LynxKeeperRouter.setLpAllocator() | Resolved |
| R-03 Slither + Aderyn | Silent LP deploy no-ops (manual review) Misconfigured swap pools or zero-liquidity increases could complete without effect, leaving ops blind. Why resolvedResolved by LynxLpAllocator fail-fast reverts: SwapProducedZero when swap output is zero, LiquidityIncreaseZero when liquidity increase is zero on the active deploy path. LynxLpAllocator.sol | ● medium | LynxLpAllocator.sol | Resolved |
| R-04 Aderyn | Unsafe uint128 cast on lpDrainDust (Aderyn H-4) Aderyn flagged an unsafe downcast on lpDrainDustThreshold in LynxKeeperRouter. Why resolvedResolved by typing DEFAULT_LP_DRAIN_DUST as uint128 at declaration. Closes the H-4 unsafe-cast theme from the prior snapshot. LynxKeeperRouter.sol | ● low | LynxKeeperRouter.sol | Resolved |
| R-05 Slither | Uninitialized-local / cache-array-length (Slither) Slither flagged uninitialized locals in reconcileInactiveLp and uncached array length in deployLpIdle. Why resolvedResolved with explicit local initializers in LynxKeeperRouter.reconcileInactiveLp and cached targets.length in LynxLpAllocator.deployLpIdle. LynxKeeperRouter.sol · LynxLpAllocator.sol | ● low | LynxKeeperRouter.sol · LynxLpAllocator.sol | Resolved |
| M-01 Slither | HTS return values ignored at call sites Slither unused-return on HtsOps.mint, transfer, associate, approve. Why false positiveHtsOps checks HederaResponseCodes.SUCCESS internally and reverts with HTSCallFailed on failure. Callers do not need to re-check the int64 return value — the library already enforces success or revert. libraries/HtsOps.sol | ● medium | libraries/HtsOps.sol | False positive |
| M-02 Slither | Cost-basis NAV uses block.timestamp block.timestamp used in lockedProfit(), totalAssets(), setProfitUnlockPeriod. Why acceptedProfit streaming (Yearn-style linear unlock) deliberately uses timestamps so depositors cannot sandwich harvests. On Hedera, consensus timestamps have narrow skew (~10–15s), which is negligible for hour/day unlock periods set by governance. LynxVault.sol | ● medium | LynxVault.sol | Accepted |
| M-03 Aderyn | StrategyManager pull/harvest interaction order State updates after withdraw() / harvest() external calls. Why acceptedThe manager must observe strategy return values before adjusting principal or reporting PnL — reversing the order would break accounting. Access is keeper-only with nonReentrant; push was reordered to CEI, but pull/harvest order is intentional. StrategyManager.sol | ● medium | StrategyManager.sol | Accepted |
| M-04 Aderyn | Centralized governance Owner/keeper can change fees, strategies, caps, pause inflows, and move capital. Why acceptedThis is the protocol trust model, not a code bug. Mitigations include Ownable2Step (two-step ownership transfer), optional guardian for fast pause, exit/redemption paths that stay open when inflows are paused, MAX_EXIT_FEE_BPS ceiling, and per-strategy caps. Production governance is expected to be a multisig. Core contracts | ● medium | Core contracts | Accepted |
| M-05 Slither + Aderyn | registerStrategy ManagerMismatch validation order Aderyn H-3 / Slither: registerStrategy performs external view reads before writing strategy state. Why acceptedAccepted. Leading calls validate strategyManager matches the vault before registration — a hardening guard against miswired strategies. No user funds at risk; only governance can register. StrategyManager.sol — registerStrategy | ● medium | StrategyManager.sol — registerStrategy | Accepted |
| M-06 Slither | bookLossToExposure reentrancy-benign Slither reentrancy-benign on StrategyManager.bookLossToExposure after external strategy calls. Why acceptedAccepted. Same pattern as bookLoss — keeper-only, nonReentrant manager path. Books NAV loss when principal exceeds on-chain exposureValue(); required for exposure-cap hardening. StrategyManager.sol — bookLossToExposure | ● medium | StrategyManager.sol — bookLossToExposure | Accepted |
| L-01 Slither | configure() allows zero addresses SaucerSwapLiquidityStrategy.configure allows zero addresses for SaucerSwap dependencies. Why acceptedZero means “not configured yet.” All mutating LP functions revert with NotConfigured() until the admin sets real SaucerSwap router and NFT manager addresses. This is an intentional two-phase setup pattern. SaucerSwapLiquidityStrategy.configure() | ● low | SaucerSwapLiquidityStrategy.configure() | Accepted |
| L-02 Slither | setGuardian(address(0)) allowed Guardian can be set to the zero address. Why acceptedClearing the guardian is intentional — it disables guardian-only pause so only the owner can pause. Documented in NatSpec. Useful when rotating or removing the guardian role without transferring ownership. LynxVault.sol · LynxHTSBridge.sol | ● low | LynxVault.sol · LynxHTSBridge.sol | Accepted |
| L-03 Aderyn | Unsafe ERC20 on HTS paths HtsOps.transfer / approve flagged as unsafe ERC20 by Aderyn. Why false positiveThese are Hedera HTS precompile calls at 0x167, not standard ERC20 transfer/approve with boolean return values. Aderyn’s ERC20 checker does not apply to HTS semantics. libraries/HtsOps.sol | ● low | libraries/HtsOps.sol | False positive |
| L-04 Aderyn | Cancun / PUSH0 bytecode Bytecode may include PUSH0 (Cancun opcode). Why acceptedevmVersion: cancun is pinned in Hardhat and Foundry profiles to match Hedera mainnet (Besu EVM, release 0.50.0+). PUSH0 is expected and required for Cancun-targeted deployments. All production contracts | ● low | All production contracts | Accepted |
| L-05 Slither | LynxVault asset() unimplemented Slither claims ILynxVault.asset() is not implemented. Why false positiveasset() is implemented via override resolving both ERC4626 and ILynxVault in LynxVault.sol. Slither’s inheritance analysis missed the dual-interface override. LynxVault.sol | ● low | LynxVault.sol | False positive |
| L-06 Aderyn | Large numeric literal BASIS = 10_000 Aderyn L-2 flags the BASIS constant as a large numeric literal. Why ignored10_000 is the standard basis-points denominator (100.00%). Named constant improves readability; no security impact. Core contracts | ● low | Core contracts | Ignored |
| L-07 Aderyn | nonReentrant not first modifier Aderyn L-3: nonReentrant is not the first modifier on some LP admin functions. Why ignoredModifier ordering on owner-only admin functions has no demonstrated security impact. nonReentrant is still applied; reordering would be cosmetic. SaucerSwapLiquidityStrategy.sol | ● low | SaucerSwapLiquidityStrategy.sol | Ignored |
| L-08 Aderyn | Unspecific pragma ^0.8.20 Aderyn L-8: broad ^0.8.20 pragma on production contracts. Why ignoredCI compiles all contracts with solc 0.8.28. The broad pragma allows compatibility; the pinned compiler version in CI is what matters for deployment. Production contracts | ● low | Production contracts | Ignored |
| L-09 Slither | Reentrancy-benign on StrategyManager Slither reentrancy-benign on manager push/pull/harvest paths. Why ignoredPaths are access-controlled (keeper or owner only). push was hardened with checks-effects-interactions (principal booked before external calls). No user-facing reentrancy surface. StrategyManager.sol | ● low | StrategyManager.sol | Ignored |
| L-10 Slither | Reentrancy-events on harvest paths Slither reentrancy-events on harvestLp / harvestStaking after HarvestCompleted event emission. Why acceptedEvents are emitted after external harvest calls for observability. No state corruption — harvest functions are access-controlled and the events document manager return values intentionally. LynxKeeperRouter.sol | ● low | LynxKeeperRouter.sol | Accepted |
| L-11 Slither | block.timestamp on deployLpIdle deadline Slither timestamp on LynxLpAllocator.deployLpIdle deadline calculation. Why acceptedDeadline uses block.timestamp + buffer — standard swap deadline pattern. Hedera consensus timestamp skew is negligible for LP deploy timeouts. LynxLpAllocator.deployLpIdle() | ● low | LynxLpAllocator.deployLpIdle() | Accepted |
| L-12 Slither + Aderyn | setSplitRouter(address(0)) allowed Slither missing-zero-check / Aderyn L-12 on StrategyManager.setSplitRouter. Why acceptedAccepted by design. address(0) disables split-router alignment checks — same intentional pattern as setGuardian(0) for clearing optional wiring. StrategyManager.setSplitRouter() | ● low | StrategyManager.setSplitRouter() | Accepted |
| L-13 Aderyn | setPositionPool without event (Aderyn L-11) SaucerSwapLiquidityStrategy.setPositionPool updates state without emitting an event. Why acceptedAccepted. Retroactive ops wiring for existing LP positions; optional event can be added in a future version. No depositor-facing exploit path. SaucerSwapLiquidityStrategy.setPositionPool() | ● low | SaucerSwapLiquidityStrategy.setPositionPool() | Accepted |
| I-01 Slither | Solc version warning on HtsOps Broad ^0.8.0 pragma triggered Slither’s historical solc bug list. Why resolvedPragma updated to ^0.8.28 aligned with the rest of the stack. CI compiles with solc 0.8.28 — the warning is resolved in the current codebase. libraries/HtsOps.sol | ● info | libraries/HtsOps.sol | Resolved |