# Access Control Documentation ## Overview This document describes the access control structure for all trustless bridge contracts, including roles, permissions, and security considerations. ## Access Control Matrix ### Lockbox138 **Status**: Immutable, no admin functions | Function | Access | Notes | |----------|--------|-------| | `depositNative()` | Public | Anyone can deposit | | `depositERC20()` | Public | Anyone can deposit | | `getNonce()` | Public | View function | | `isDepositProcessed()` | Public | View function | **Security**: No admin functions, fully permissionless. ### InboxETH **Status**: Immutable, no admin functions | Function | Access | Notes | |----------|--------|-------| | `submitClaim()` | Public | Relayers submit claims with bond | | `getClaimStatus()` | Public | View function | | `getClaim()` | Public | View function | **Security**: No admin functions, fully permissionless. ### BondManager **Status**: Immutable, no admin functions | Function | Access | Notes | |----------|--------|-------| | `postBond()` | Public | Relayers post bonds | | `slashBond()` | Public | Only ChallengeManager can call (via external) | | `releaseBond()` | Public | Anyone can release after finalization | | `getRequiredBond()` | Public | View function | | `getBond()` | Public | View function | | `getTotalBonds()` | Public | View function | **Security**: No admin functions. `slashBond()` should only be called by ChallengeManager. ### ChallengeManager **Status**: Immutable, no admin functions | Function | Access | Notes | |----------|--------|-------| | `registerClaim()` | Public | Only InboxETH should call | | `challengeClaim()` | Public | Anyone can challenge | | `finalizeClaim()` | Public | Anyone can finalize after window | | `canFinalize()` | Public | View function | | `getClaim()` | Public | View function | | `getChallenge()` | Public | View function | **Security**: No admin functions. `registerClaim()` should only be called by InboxETH. ### LiquidityPoolETH **Status**: Has one admin function (needs access control) | Function | Access | Notes | |----------|--------|-------| | `authorizeRelease()` | **Public** | ⚠️ **SECURITY ISSUE**: Should have access control | | `provideLiquidity()` | Public | Anyone can provide liquidity | | `depositWETH()` | Public | Anyone can deposit WETH | | `withdrawLiquidity()` | Public | LPs can withdraw their liquidity | | `releaseToRecipient()` | Authorized only | Only authorized contracts | | `addPendingClaim()` | Authorized only | Only authorized contracts | | `removePendingClaim()` | Authorized only | Only authorized contracts | | `getAvailableLiquidity()` | Public | View function | | `getLpShare()` | Public | View function | | `getPoolStats()` | Public | View function | **Security Issue**: `authorizeRelease()` is public and has no access control. This should be: - Restricted to owner/multisig, OR - Only callable during deployment, OR - Removed if not needed **Recommendation**: Add access control to `authorizeRelease()` or make it only callable during constructor. ### SwapRouter **Status**: Immutable, no admin functions | Function | Access | Notes | |----------|--------|-------| | `swapToStablecoin()` | Public | Anyone can swap | | `_executeUniswapV3Swap()` | Internal | Internal function | | `_isValidStablecoin()` | Internal | Internal function | **Security**: No admin functions, fully permissionless. ### BridgeSwapCoordinator **Status**: Immutable, no admin functions | Function | Access | Notes | |----------|--------|-------| | `bridgeAndSwap()` | Public | Anyone can execute bridge+swap | | `canSwap()` | Public | View function | **Security**: No admin functions, fully permissionless. ## Access Control Recommendations ### 1. LiquidityPoolETH.authorizeRelease() **Current State**: Public function with no access control **Recommendation**: Add owner/multisig access control: ```solidity address public owner; modifier onlyOwner() { require(msg.sender == owner, "LiquidityPoolETH: not owner"); _; } function authorizeRelease(address releaser) external onlyOwner { require(releaser != address(0), "LiquidityPoolETH: zero address"); authorizedRelease[releaser] = true; } ``` **Alternative**: If authorization only needed during deployment, remove function and authorize in constructor. ### 2. ChallengeManager.registerClaim() **Current State**: Public function **Recommendation**: Add access control to ensure only InboxETH can call: ```solidity address public immutable inbox; modifier onlyInbox() { require(msg.sender == inbox, "ChallengeManager: not inbox"); _; } function registerClaim(...) external onlyInbox { // ... } ``` ### 3. BondManager.slashBond() **Current State**: Public function, but should only be called by ChallengeManager **Recommendation**: Add access control: ```solidity address public immutable challengeManager; modifier onlyChallengeManager() { require(msg.sender == challengeManager, "BondManager: not challenge manager"); _; } function slashBond(...) external onlyChallengeManager returns (...) { // ... } ``` ## Role-Based Access Control (Future Enhancement) Consider implementing a role-based access control system using OpenZeppelin's AccessControl: ```solidity import "@openzeppelin/contracts/access/AccessControl.sol"; contract LiquidityPoolETH is ReentrancyGuard, AccessControl { bytes32 public constant AUTHORIZER_ROLE = keccak256("AUTHORIZER_ROLE"); constructor(...) { _grantRole(DEFAULT_ADMIN_ROLE, msg.sender); } function authorizeRelease(address releaser) external onlyRole(AUTHORIZER_ROLE) { // ... } } ``` ## Multisig Integration ### Transferring Ownership 1. Deploy multisig wallet (Gnosis Safe recommended) 2. Transfer ownership of contracts with admin functions to multisig 3. Update access control roles to multisig address 4. Test multisig operations on testnet ### Multisig Operations See `docs/bridge/trustless/MULTISIG_OPERATIONS.md` for detailed procedures. ## Security Considerations ### 1. Principle of Least Privilege - Grant minimum permissions necessary - Remove unused admin functions - Use immutable contracts where possible ### 2. Access Control Review - Regularly audit access control - Review all admin functions - Document all permissions - Test access control thoroughly ### 3. Emergency Procedures - Have emergency pause mechanism - Document emergency access procedures - Test emergency procedures regularly - Maintain backup access methods ## Testing Access Control ### Test Suite Create comprehensive access control tests: ```solidity // test/bridge/trustless/AccessControl.t.sol function test_OnlyOwnerCanAuthorizeRelease() public { // Test that only owner can authorize release } function test_UnauthorizedCannotAuthorizeRelease() public { // Test that unauthorized users cannot authorize } function test_OnlyInboxCanRegisterClaim() public { // Test that only InboxETH can register claims } ``` ## Audit Checklist - [ ] Review all public functions - [ ] Verify admin functions have access control - [ ] Check for missing access control modifiers - [ ] Verify immutable contracts have no admin functions - [ ] Test all access control paths - [ ] Document all roles and permissions - [ ] Review emergency access procedures ## References - Contracts: `contracts/bridge/trustless/` - Multisig Operations: `docs/bridge/trustless/MULTISIG_OPERATIONS.md` - Security Documentation: `docs/bridge/trustless/SECURITY.md`