Skip to content

chore(erc20-bridge): protect admin actions#1151

Merged
MicBun merged 3 commits intomainfrom
feat/protect-admin-actions
Sep 10, 2025
Merged

chore(erc20-bridge): protect admin actions#1151
MicBun merged 3 commits intomainfrom
feat/protect-admin-actions

Conversation

@williamrusdyputra
Copy link
Contributor

@williamrusdyputra williamrusdyputra commented Sep 10, 2025

Related Problem

resolves: https://github.com/trufnetwork/truf-network/issues/1186

How Has This Been Tested?

without the role

Screenshot 2025-09-11 at 01 28 50

Using erc20_bridge_writer role wallet

Screenshot 2025-09-11 at 01 29 07

Summary by CodeRabbit

  • New Features
    • Introduced role-based access control for admin token operations (lock, unlock, issue) on both mainnet and testnet. Only users with the designated writer role can execute these actions; others receive a clear permission error.
    • Read-only wallet balance lookups remain unchanged, ensuring no impact to users checking balances.

@williamrusdyputra williamrusdyputra self-assigned this Sep 10, 2025
@coderabbitai
Copy link

coderabbitai bot commented Sep 10, 2025

Walkthrough

Adds runtime access-control checks to six ERC20 bridge admin actions (lock/unlock/issue on sepolia and mainnet), gating execution on membership in system:erc20_bridge_writer. Wallet balance helpers remain unchanged. No action signatures changed.

Changes

Cohort / File(s) Summary
ERC20 bridge admin actions (permission checks added)
internal/migrations/erc20-bridge/001-actions.sql
For sepolia/mainnet admin actions: normalize caller, verify membership via are_members_of('system','erc20_bridge_writer', ARRAY[$lower_caller]); on failure raise ERROR; on success call existing lock_admin/unlock/issue functions with original args.
Wallet balance helpers (unchanged)
internal/migrations/erc20-bridge/001-actions.sql
No changes to sepolia_wallet_balance and mainnet_wallet_balance.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant C as Caller (@caller)
  participant A as Admin Action (SQL)
  participant AC as Access Control
  participant B as Bridge Function

  C->>A: Invoke admin action (lock/unlock/issue)
  A->>AC: are_members_of('system','erc20_bridge_writer', LOWER(@caller))
  alt has permission
    A->>B: Call lock_admin / unlock / issue (args)
    B-->>A: Result
    A-->>C: Success
  else lacks permission
    A-->>C: ERROR: caller lacks role system:erc20_bridge_writer
  end

  note over A,AC: Permission check occurs before any bridge operation
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Suggested reviewers

  • MicBun

Pre-merge checks (5 passed)

✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The current title “chore(erc20-bridge): protect admin actions” succinctly and accurately captures the primary change in the pull request by highlighting the addition of protection to admin actions within the ERC-20 bridge logic. It is concise, clear, and directly related to the main code modifications.
Linked Issues Check ✅ Passed The pull request fully addresses issue #1186 by introducing runtime permission checks for all six admin functions, leveraging the system:erc20_bridge_writer role, and including error handling for unauthorized callers as specified in the linked issue’s objective to protect admin actions.
Out of Scope Changes Check ✅ Passed All changes in this pull request are strictly confined to adding permission checks for ERC-20 bridge admin actions and no unrelated files or functionality were modified, ensuring that no out-of-scope code has been introduced.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.

Poem

A twitch of whiskers, roles in line,
I hop through guards before I sign.
Lock, unlock, issue—checked with care,
No burrow trespassers anywhere.
With keys well-kept and carrots bright,
This bridge now bounces safe at night. 🥕✨

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
  pre_merge_checks:
    custom_checks:
      - name: "Undocumented Breaking Changes"
        mode: "warning"
        instructions: |
          Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.

✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/protect-admin-actions

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 and usage tips.

@williamrusdyputra williamrusdyputra changed the title Feat/protect admin actions chore: protect admin actions Sep 10, 2025
@williamrusdyputra williamrusdyputra changed the title chore: protect admin actions chore(erc20-bridge): protect admin actions Sep 10, 2025
@trufnetwork trufnetwork deleted a comment from williamrusdyputra Sep 10, 2025
@williamrusdyputra williamrusdyputra marked this pull request as ready for review September 10, 2025 18:31
@holdex
Copy link

holdex bot commented Sep 10, 2025

Time Submission Status

Member Status Time Action Last Update
williamrusdyputra ✅ Submitted 2h Update time Sep 10, 2025, 10:48 PM
MicBun ✅ Submitted 20min Update time Sep 10, 2025, 10:54 PM

Copy link

@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

♻️ Duplicate comments (5)
internal/migrations/erc20-bridge/001-actions.sql (5)

35-47: Same access-control notes as above.

See earlier comments on amount validation, deduping the role check, and auditing.


53-65: Same access-control notes as above.

Replicate amount validation, helper-based role check, and auditing.


77-89: Same access-control notes as above (mainnet lock).

Apply the same improvements here.


95-107: Same access-control notes as above (mainnet unlock).

Apply the same improvements here.


113-125: Same access-control notes as above (mainnet issue).

Apply the same improvements here.

🧹 Nitpick comments (3)
internal/migrations/erc20-bridge/001-actions.sql (3)

17-29: Deduplicate the role check into a reusable helper to reduce repetition and drift.

All six actions repeat the same loop. Extract to a small PRIVATE VIEW action (or function) and call it, keeping the single source of truth for the role name and logic.

For example, add near the top of this file:

-- Helper: returns TRUE iff the caller is an erc20_bridge_writer
CREATE OR REPLACE ACTION _has_erc20_bridge_writer_role($w TEXT) PRIVATE VIEW RETURNS (ok BOOL) {
  $w := LOWER($w);
  for $row in are_members_of('system', 'erc20_bridge_writer', ARRAY[$w]) {
    if $row.is_member { return true; }
  }
  return false;
};

Then replace in each admin action:

-  $lower_caller TEXT := LOWER(@caller);
-  $has_permission BOOL := false;
-  for $row in are_members_of('system', 'erc20_bridge_writer', ARRAY[$lower_caller]) {
-      if $row.wallet = $lower_caller AND $row.is_member {
-          $has_permission := true;
-          break;
-      }
-  }
-  if NOT $has_permission {
+  if NOT _has_erc20_bridge_writer_role(@caller) {
       ERROR('Caller does not have the required system:erc20_bridge_writer role to <op>.');
   }

Replace with lock/unlock/issue accordingly.

Also applies to: 35-47, 53-65, 77-89, 95-107, 113-125


31-31: Prefer passing a pre-cast variable instead of repeating the cast at call sites.

Minor readability and avoids double parse/cast costs once you introduce $amt.

Also applies to: 49-49, 67-67, 91-91, 109-109, 127-127


17-29: Include caller and params in error/audit for traceability.

Optional: emit an audit event/row on both success and authorization failure (operation, caller, to/wallet, amount). Greatly helps incident response.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 60b02d0 and a0b6d97.

📒 Files selected for processing (1)
  • internal/migrations/erc20-bridge/001-actions.sql (2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: acceptance-test
  • GitHub Check: lint
🔇 Additional comments (2)
internal/migrations/erc20-bridge/001-actions.sql (2)

17-29: Access control check looks correct and aligns with the PR objective.

Lowercasing the caller and verifying membership in system:erc20_bridge_writer before invoking the bridge op is sound.


16-32: No exposure of underlying bridge functions: Verified via ripgrep that there are no PUBLIC ACTION definitions for sepolia_bridge.lock_admin/unlock/issue or mainnet_bridge.lock_admin/unlock/issue anywhere in the repository.

Copy link
Member

@MicBun MicBun left a comment

Choose a reason for hiding this comment

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

lgtm

@MicBun MicBun merged commit b4e0995 into main Sep 10, 2025
12 of 13 checks passed
@MicBun MicBun deleted the feat/protect-admin-actions branch September 10, 2025 22:48
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.

2 participants