Skip to content

fix(config): require multiRewardDistributor for EVM comptroller chains#307

Closed
bprofiro wants to merge 1 commit into
brenda/moo-413-add-multirewarddistributor-to-ethereum-sdk-config-before-mipfrom
brenda/sdk-require-multirewarddistributor-evm-config-type
Closed

fix(config): require multiRewardDistributor for EVM comptroller chains#307
bprofiro wants to merge 1 commit into
brenda/moo-413-add-multirewarddistributor-to-ethereum-sdk-config-before-mipfrom
brenda/sdk-require-multirewarddistributor-evm-config-type

Conversation

@bprofiro

Copy link
Copy Markdown
Collaborator

Summary

Closes the root cause behind MOO-413 / #306: the contracts config typed multiRewardDistributor? as optional, so an EVM comptroller chain could omit it with no compile error — which is exactly how Ethereum shipped without it and silently broke the frontend reward-claim flow (it falls back to the Moonbeam 0x…0808 precompile path, which reverts).

⚠️ Stacked on #306 (base = brenda/moo-413-…). This change requires Ethereum's MRD to already be present, so it must merge after #306. Retarget to main once #306 lands.

Change

createContractsConfig now intersects a conditional constraint onto its input:

type RequireMultiRewardDistributor<contracts> = contracts extends { comptroller: Address }
  ? contracts extends { governor: Address }
    ? unknown                              // Moonbeam/Moonriver: WELL precompile model, no MRD
    : { multiRewardDistributor: Address }  // EVM comptroller chain: MRD required
  : unknown;                               // no comptroller: not a lending env

Discriminator: comptroller present + governor absent ⟹ EVM comptroller chain ⟹ MRD required. Verified against all 8 definitions: Base/Optimism/Ethereum (require, and have it); Moonbeam/Moonriver (have governor → exempt); arbitrum/avalanche/polygon (no comptroller → exempt).

Verification

  • pnpm typecheck passes for all 8 current definitions.
  • Proof it catches the regression: removing MRD from ethereum/contracts.ts now produces error TS2741: Property 'multiRewardDistributor' is missing.
  • Moonbeam/Moonriver and the non-comptroller chains still compile.
  • Full suite: 552 pass (34 files). Quality gate: PASS.

Tests added

  • src/environments/contracts-invariants.test.ts — runtime backstop iterating publicEnvironments: asserts every EVM comptroller env (comptroller, no governor) has a valid multiRewardDistributor.address. Covers envs built outside the factory and any as-cast bypass. Registered in the vitest include list.

Reviewer notes (triaged)

  • A type-design review flagged a possible governor: undefined bypass (🟡). Verified not reproducible under this repo's exactOptionalPropertyTypes: truegovernor: undefined is itself a compile error (TS2375), so it can't take the exempt branch. No code change made (guarding an impossible case would add noise).
  • The governor-presence discriminator is a structural proxy for "Moonbeam-family home chain." Sound for all current/foreseeable chains; if a future chain breaks the heuristic, an explicit kind tag would be the more durable design. Noted as a future option, not done now (disproportionate to this fix).

Semver

Marked minor (breaking) per the repo's breaking-change hook: direct callers of the exported createContractsConfig that omit MRD on an EVM comptroller config will no longer compile. Internal definitions are all updated/valid.

Close the root cause behind MOO-413: the contracts config made
`multiRewardDistributor?` optional, so an EVM comptroller chain could omit it
with no compile error — which is how Ethereum shipped without it, silently
breaking the frontend reward-claim flow (it falls back to the Moonbeam 0x..0808
precompile path and reverts).

createContractsConfig now intersects a conditional constraint: a config that has
a `comptroller` but no `governor` (Base/Optimism/Ethereum) must define
`multiRewardDistributor`, or it fails to compile. Moonbeam/Moonriver carry a
`governor` and use the WELL precompile reward model, so they remain exempt;
chains without a comptroller (arbitrum/avalanche/polygon) are unaffected.

Adds a runtime invariant test over publicEnvironments as the universal backstop
(covers envs built outside the factory and any `as`-cast bypass).
@bprofiro

Copy link
Copy Markdown
Collaborator Author

Closing — not needed. The fix lives entirely in #306 (adds Ethereum's multiRewardDistributor, with an env test locking it). Making the config type require MRD is a breaking change to createContractsConfig that isn't necessary to solve MOO-413.

@bprofiro bprofiro closed this Jun 15, 2026
@bprofiro bprofiro deleted the brenda/sdk-require-multirewarddistributor-evm-config-type branch June 15, 2026 17:20
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