Skip to content

SIG-744: remove unused RiskGate functions#74

Merged
worjs merged 1 commit into
mainfrom
chore/SIG-744-remove-unused-riskgate-functions
May 9, 2026
Merged

SIG-744: remove unused RiskGate functions#74
worjs merged 1 commit into
mainfrom
chore/SIG-744-remove-unused-riskgate-functions

Conversation

@worjs
Copy link
Copy Markdown
Contributor

@worjs worjs commented May 9, 2026

Context

SIG-744. RiskModule.gateOpenPosition and gateIncreasePosition were no-op view functions that silenced their parameters with a // Exposure cap enforcement pending implementation comment. IRiskModule.gateRequestWithdraw had no implementation at all. SignalsCore still issued a _riskGate(...) delegatecall into the two trade-time gates from openPosition, openPositionFor, and increasePosition on every trade.

Per-trade alpha enforcement was removed in commit 0908712 ("remove per-trade alpha enforcement, keep market-creation-only"). The placeholder gates added afterward for a future exposure-cap feature were never implemented and now confuse the audit narrative ("why call empty functions on every trade?") while burning ~700 gas per call on Citrea.

Decisions

Deletion-first across interface, implementation, call sites, and tests in a single change so no layer keeps a stale gate surface. No replacement abstraction added: gateCreateMarket is the only real risk gate, and SignalsCore._riskGate already supports it.

Surviving valid-path tests in RiskGateCallOrder.t.sol (test_openPosition_succeeds_with_valid_params, test_increasePosition_updates_quantity) kept as-is; the two removed tests (test_openPosition_gate_no_revert, test_increasePosition_gate_no_revert) only asserted that no-op hooks did not revert. No new regression test added because the directive removes dead behavior rather than introducing a new path.

Impact

SignalsCore external ABI surface is unchanged. Only internal bytecode (regenerated abis/SignalsCore.json and abis/SignalsCoreHarness.json) and the internal IRiskModule delegatecall surface differ. No subgraph events touched, no SDK calculation helpers touched.

The IRiskModule interface is internal to v1-contract (used only by SignalsCore for abi.encodeCall against the RiskModule delegate). No downstream repo (v1-subgraph, v1-sdk, v1-server) consumes those three signatures.

Risk Areas

  • contracts/core/SignalsCore.sol openPosition / openPositionFor / increasePosition: trade entrypoint behavior with the pre-delegate _riskGate call removed. Reviewer should confirm no other side effect (e.g. reentrancy ordering, event emission expectations) depended on the gate executing before _delegate(tradeModule, ...).
  • .gas-snapshot churn is broad because yarn snapshot regenerated the full file under current Foundry output; the load-bearing deltas are the trade entrypoints losing the delegatecall and the two removed RiskGateCallOrder tests.
  • IRiskModule ABI shape change: any off-chain caller that hand-encoded gateOpenPosition / gateIncreasePosition / gateRequestWithdraw selectors against the deployed RiskModule address would now hit a non-existent function. Repo grep confirms zero in-tree callers; out-of-tree callers are unexpected because RiskModule is a delegatecall target rather than a directly invoked contract.

Copy link
Copy Markdown

@signals-reviewer signals-reviewer Bot left a comment

Choose a reason for hiding this comment

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

Summary

Removes the trade-time _riskGate(...) delegatecalls from openPosition, openPositionFor, and increasePosition in SignalsCore, drops the corresponding no-op gateOpenPosition / gateIncreasePosition implementations and the never-implemented gateRequestWithdraw declaration from RiskModule / IRiskModule, and prunes the two RiskGateCallOrder tests that asserted only that the no-op gates did not revert. The surviving gateCreateMarket enforcement path is untouched. ABI/JSON regeneration and .gas-snapshot refresh are bundled in.

Cross-PR Context

Sibling PRs (SIG-744)

  • v1-whitepaper PR#13 (OPEN): SIG-744: align whitepaper with v1 RiskModule enforcement surface
  • v1-docs PR#23 (OPEN): SIG-744: remove trade gate hook narrative from risk docs
  • Impact map check: no v1-subgraph / v1-sdk / v1-server PRs needed. IRiskModule is not referenced in any downstream repo (verified via grep across v1-subgraph, v1-sdk, v1-server, signals-app, v1-admin); the impact map at v1-skills/references/impact-map.md lists no risk-module dependency.

Issues

No issues found.

Verifications performed

  • Confirmed zero in-tree callers of the removed selectors via grep -r 'gateOpenPosition|gateIncreasePosition|gateRequestWithdraw' (only the four files in this diff matched).
  • Confirmed RiskModule carries the onlyDelegated modifier (contracts/modules/RiskModule.sol:36-39), so any external direct call against the deployed RiskModule address reverts with NotDelegated() regardless of which selectors exist. The interface shrinkage cannot break an off-chain integration.
  • Confirmed the removed gate bodies (marketId; trader; quantity; etc.) had no require / revert / state mutation, so removing both the call sites and the implementations is behavior-preserving for openPosition / openPositionFor / increasePosition. The view qualifier rules out lost events or storage writes.
  • Confirmed _riskGate still exists in SignalsCore.sol:773 and is still wired to gateCreateMarket at line 451, so the surviving market-creation enforcement path is unaffected.
  • Confirmed nonReentrant ordering is unchanged: the reentrancy critical section now wraps only the _delegate(tradeModule, ...) call, which is a tightening, not a loosening, of the invariant.
  • Confirmed gateRequestWithdraw was indeed never implemented in RiskModule (interface-only, never a concrete function), so its removal from the interface is a pure cleanup with no caller to break.
  • SignalsCore external function ABI surface in abis/SignalsCore.json is preserved; only the bytecode field changed, consistent with removing the three pre-delegate calls.

Suggestions

Gas snapshot churn is broader than the directive

The .gas-snapshot diff removes 434 entries and adds 311. The bulk of the disappearance is testFuzz_* and invariant_* lines (e.g. ClmsrInvariantTest:invariant_*, LazyMulSegmentTreeFuzzTest:*, FixedPointMathFuzz:*, FeeWaterfallLibFuzzTest:*). This is consistent with package.json's snapshot script (forge snapshot --no-match-test 'testFuzz|invariant_'), which excludes those by design, while the previous on-disk snapshot (last refreshed in PR #63) predates the exclusion. So the churn is harmless, but two follow-ups would make future SIG-744-style refactors easier to read:

  • Consider a one-shot housekeeping commit on main that regenerates .gas-snapshot standalone, so future PRs only show the load-bearing deltas.
  • The ApprovedOperatorTest:* entries appear added because that suite shipped after the last snapshot refresh (PR #69, test/foundry/integration/trade/ApprovedOperator.t.sol). Same housekeeping commit would absorb that drift too.

Status: Accepted. The PR description explicitly flags the broad churn and identifies the load-bearing deltas. No code change required for this PR.

Test file naming

test/foundry/integration/core/RiskGateCallOrder.t.sol retains the name and the contract RiskGateCallOrderTest but, post-PR, only covers the createMarket gate plus generic open/increase valid paths. The header comment was updated, but a future rename to something like RiskCreateMarketGate.t.sol (or moving the open/increase valid-path tests into an existing trade-suite) would more honestly reflect the file's scope.

Status: Accepted. Purely cosmetic, out of scope for a deletion-only directive.

Verdict

APPROVE: zero unresolved items. Directive cleanly executed across interface, implementation, call sites, and tests with no surviving stale gate surface. Sibling narrative PRs in v1-whitepaper and v1-docs cover the documentation side. Both suggestions above are accepted as out-of-scope cosmetic follow-ups that would not justify blocking this change.

@worjs worjs merged commit 9a25c0c into main May 9, 2026
16 checks passed
@worjs worjs deleted the chore/SIG-744-remove-unused-riskgate-functions branch May 9, 2026 14:52
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