Skip to content

test(failing): pin prod receipt vault authorizer consistency#116

Open
thedavidmeister wants to merge 1 commit intomainfrom
feat/issue-34-prod-authorizer-consistency
Open

test(failing): pin prod receipt vault authorizer consistency#116
thedavidmeister wants to merge 1 commit intomainfrom
feat/issue-34-prod-authorizer-consistency

Conversation

@thedavidmeister
Copy link
Copy Markdown
Contributor

@thedavidmeister thedavidmeister commented May 1, 2026

Summary

Implements the test from #34: every prod receipt vault on Base must report a non-zero authorizer AND all 13 prod token sets must share the same authorizer contract.

This PR ships a deliberately failing test as a forcing function. Two prod tokens diverge from the rest. The test landing as red is the point — it surfaces the drift to anyone who touches the prod-token suite.

Drift observed (fork against Base)

Group Tokens Authorizer
Majority (11/13) MSTR, TSLA, COIN, SPYM, SIVR, CRCL, NVDA, IAU, PPLT, AMZN, BMNR 0x35f9fA9d80aAF2B0fB27f0FF015641B3408d7456
Outlier IBHG 0x6E0F1c31Fca4Ff07cD0C3e8658b1e3a473f3393a
Outlier SGOV 0xED3A1Ab65a25dfc82F4A7B89203EEc9BCb2D4f01

None of these match the V2 constants in LibProdDeployV2 (STOX_OFFCHAIN_ASSET_RECEIPT_VAULT_AUTHORIZER_V1 = 0x667d2Ab…, STOX_OFFCHAIN_ASSET_RECEIPT_VAULT_PAYMENT_MINT_AUTHORIZER_V1 = 0x72b2a39…). The prod vaults are V1-era and use authorizers that don't appear as constants anywhere in the repo.

Three reads, one needs picking

  1. Misconfiguration — IBHG/SGOV were deployed against the wrong authorizer by mistake. Fix prod to point them at 0x35f9fA9d80…. Test stays as-is.
  2. Intentional per-token authorizer — IBHG (corporate-bond ETF) and SGOV (Treasury) have different transfer-restriction rules vs. equity tokens. Prod token test: verify authorizer is set and consistent across vaults #34's premise is wrong; relax the test to non-zero only and document the per-token expectation in LibProdTokensBase.
  3. Cohort split — IBHG/SGOV are a different deployment generation. Partition the test by cohort, assert consistency within each cohort, document which token belongs to which.

Whoever picks this up needs to (a) talk to whoever signed the IBHG/SGOV deployments to confirm intent, (b) look up the three authorizer addresses on basescan to identify what they actually are, (c) decide which read above applies and act on it.

Mechanical changes

Closes #34 only after the drift question above is resolved (do not merge while red).

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Chores

    • Updated submodule reference to latest revision.
  • Tests

    • Enhanced test validation for permission-boundary consistency across token sets, including authorizer verification and baseline comparisons.

Adds the test #34 asks for: every prod receipt vault on Base must
report a non-zero authorizer AND all 13 prod token sets must share
the same authorizer contract.

Currently fails on two tokens — fork run on Base shows drift:

- 11 of 13 vaults: authorizer 0x35f9fA9d80aAF2B0fB27f0FF015641B3408d7456
- IBHG:           authorizer 0x6E0F1c31Fca4Ff07cD0C3e8658b1e3a473f3393a
- SGOV:           authorizer 0xED3A1Ab65a25dfc82F4A7B89203EEc9BCb2D4f01

None of these match the V2 authorizer constants in `LibProdDeployV2`
(`STOX_OFFCHAIN_ASSET_RECEIPT_VAULT_AUTHORIZER_V1`,
`STOX_OFFCHAIN_ASSET_RECEIPT_VAULT_PAYMENT_MINT_AUTHORIZER_V1`) —
these are V1-era authorizers without prod constants.

Also bumps `lib/rain.vats` to f52c8b4 (PR rainlanguage/rain.vats#293,
issue rainlanguage/rain.vats#292) which adds the `IAuthorizableV1`
interface used here. Without the bump there is no typed way to read
`OffchainAssetReceiptVault.authorizer()` without importing the
concrete contract.

Test landed deliberately failing as a forcing function for the team
to investigate the IBHG/SGOV drift.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 1, 2026

📝 Walkthrough

Walkthrough

The PR updates the lib/rain.vats submodule reference and adds validation tests to ensure receipt vault authorizers are set correctly and consistent across all prod token vaults, addressing potential accidental zeroing or misconfiguration.

Changes

Cohort / File(s) Summary
Submodule Update
lib/rain.vats
Bumped submodule commit reference to a new revision.
Test Enhancements
test/src/lib/LibProdTokensBase.t.sol
Added import for IAuthorizableV1 and new assertions in checkTokenSet to verify authorizer is non-zero and matches the MSTR baseline vault authorizer.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Poem

🐰 A vault's heart beats with authority's trust,
Non-zero and matching, or fail it must!
Consistency checked from east to west,
Each authorizer put to the test—
No accidental zeros on our watch! ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the primary change: adding a failing test to verify production receipt vault authorizer consistency.
Linked Issues check ✅ Passed The PR implements all requirements from issue #34: verifies authorizers are non-zero and checks consistency across production receipt vaults via a fork test.
Out of Scope Changes check ✅ Passed All changes are directly related to issue #34: submodule bump for IAuthorizableV1 and test logic to validate authorizer consistency.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/issue-34-prod-authorizer-consistency

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
Review rate limit: 0/1 reviews remaining, refill in 60 minutes.

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

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@test/src/lib/LibProdTokensBase.t.sol`:
- Around line 98-100: Add an explicit non-zero check for the per-vault
authorizer before asserting equality: call
IAuthorizableV1(receiptVault).authorizer() and assertTrue(it != address(0))
(with a message like "receiptVault authorizer is zero") prior to the existing
comparison against mstrAuthorizer; keep the existing mstrAuthorizer retrieval
(address(IAuthorizableV1(LibProdTokensBase.MSTR_RECEIPT_VAULT).authorizer()))
and the final assertEq against mstrAuthorizer unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 4282ee5f-6216-477b-a0d4-1b90f2be4ecf

📥 Commits

Reviewing files that changed from the base of the PR and between 9a247df and dbbc05f.

⛔ Files ignored due to path filters (1)
  • foundry.lock is excluded by !**/*.lock
📒 Files selected for processing (2)
  • lib/rain.vats
  • test/src/lib/LibProdTokensBase.t.sol

Comment on lines +98 to +100
address mstrAuthorizer = address(IAuthorizableV1(LibProdTokensBase.MSTR_RECEIPT_VAULT).authorizer());
assertTrue(mstrAuthorizer != address(0), "mstr authorizer is zero");
assertEq(address(IAuthorizableV1(receiptVault).authorizer()), mstrAuthorizer, "authorizer differs from mstr's");
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Make per-vault non-zero explicit for clearer drift diagnostics.

Current equality to a non-zero MSTR authorizer is functionally sufficient, but an explicit per-vault non-zero assert gives a direct failure reason for accidental zeroing (separate from mismatch).

Suggested diff
-        address mstrAuthorizer = address(IAuthorizableV1(LibProdTokensBase.MSTR_RECEIPT_VAULT).authorizer());
+        address mstrAuthorizer = IAuthorizableV1(LibProdTokensBase.MSTR_RECEIPT_VAULT).authorizer();
         assertTrue(mstrAuthorizer != address(0), "mstr authorizer is zero");
-        assertEq(address(IAuthorizableV1(receiptVault).authorizer()), mstrAuthorizer, "authorizer differs from mstr's");
+        address tokenAuthorizer = IAuthorizableV1(receiptVault).authorizer();
+        assertTrue(tokenAuthorizer != address(0), "receipt vault authorizer is zero");
+        assertEq(tokenAuthorizer, mstrAuthorizer, "authorizer differs from mstr's");
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
address mstrAuthorizer = address(IAuthorizableV1(LibProdTokensBase.MSTR_RECEIPT_VAULT).authorizer());
assertTrue(mstrAuthorizer != address(0), "mstr authorizer is zero");
assertEq(address(IAuthorizableV1(receiptVault).authorizer()), mstrAuthorizer, "authorizer differs from mstr's");
address mstrAuthorizer = IAuthorizableV1(LibProdTokensBase.MSTR_RECEIPT_VAULT).authorizer();
assertTrue(mstrAuthorizer != address(0), "mstr authorizer is zero");
address tokenAuthorizer = IAuthorizableV1(receiptVault).authorizer();
assertTrue(tokenAuthorizer != address(0), "receipt vault authorizer is zero");
assertEq(tokenAuthorizer, mstrAuthorizer, "authorizer differs from mstr's");
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/src/lib/LibProdTokensBase.t.sol` around lines 98 - 100, Add an explicit
non-zero check for the per-vault authorizer before asserting equality: call
IAuthorizableV1(receiptVault).authorizer() and assertTrue(it != address(0))
(with a message like "receiptVault authorizer is zero") prior to the existing
comparison against mstrAuthorizer; keep the existing mstrAuthorizer retrieval
(address(IAuthorizableV1(LibProdTokensBase.MSTR_RECEIPT_VAULT).authorizer()))
and the final assertEq against mstrAuthorizer unchanged.

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.

Prod token test: verify authorizer is set and consistent across vaults

2 participants