Skip to content

m8b-dev/hlyx-audit

Repository files navigation

HLYX Hyperlane Bridge Security Audit

📅 Audit Date: January 9, 2025

🚨 Critical Security Finding

This repository contains a security audit of the HLYX Hyperlane Bridge contracts deployed on Ethereum mainnet.

CRITICAL: As of January 9, 2025, the bridge was controlled by EOAs (Externally Owned Accounts) instead of multisigs, creating severe centralization risks.

⚠️ IMPORTANT: The ownership and control structure may have changed since this audit. Always verify current state on-chain before making decisions.

📁 Repository Contents

📋 Main Documentation

  • AUDIT_REPORT.md - Complete security audit report by M8B.dev
  • CRITICAL_FINDING_PROOF.md - Detailed proof of the critical EOA control issue
  • HOW_TO_VERIFY_PROXY.md - Instructions for verifying proxy configuration

📄 Source Code

  • contracts/HypERC20Pausable.sol - Main pausable token contract
  • contracts/PausableController.sol - Abstract pause controller

🔧 Configuration

  • .solhint.json - Solidity linting configuration
  • hardhat.config.ts - Hardhat configuration
  • package.json - Dependencies and scripts
  • remappings.txt - Solidity import mappings

🔍 Verification Scripts

  • verify_critical_finding.js - Script to verify EOA control on mainnet
  • verify_pause_controller.js - Script to check pause controller status
  • scripts/run-security-audit.sh - Complete security audit runner
  • scripts/run-mythril-proper.sh - Mythril analysis script
  • scripts/mythril-with-deps.sh - Dependency-aware Mythril runner

📊 Audit Results

  • audit-results/ - All tool outputs and findings
    • mythril-success.txt/json - Mythril analysis results
    • slither-pausable.txt - Slither analysis results
    • solhint-complete.txt - Solhint linting results

🔴 Key Findings

Critical Operational Issues

  1. Single EOA Controls Everything: 0x8ea82F2DC6dAc2078eF0da432a66Ee43BB7193F9

    • Controls ProxyAdmin (can upgrade to steal funds)
    • Controls Token ownership (can change pause controller)
    • No multisig, no timelock
  2. Pause Controller is also EOA: 0xaa997F2B5C6cf291dc14ab1723f041f4FFC235A3

    • Not a multisig
    • Single key controls emergency pause

Automated Tool Results

  • Mythril: No vulnerabilities (contract code secure)
  • Solhint: 0 errors, good code quality
  • ⚠️ Slither: Found 1 structural issue (events outside contract scope)

🚀 Quick Start

  1. Clone the repository:
git clone <repo-url>
cd hlyx
  1. Install dependencies:
npm install
  1. Set up environment variables:
cp .env.example .env
# Edit .env and add your Infura/Alchemy key
  1. Run verification scripts:
# Replace YOUR_INFURA_KEY in the scripts first
node verify_critical_finding.js
node verify_pause_controller.js

🔍 How to Verify Findings Yourself

📅 Note: These instructions show how to verify the current on-chain state. The findings below were accurate as of January 9, 2025, but may have changed.

Method 1: Using Etherscan (No coding required)

  1. Verify ProxyAdmin Owner:

  2. Verify Token Owner:

  3. Check if addresses are EOAs or Contracts:

    • Search each address on Etherscan
    • If "Contract" tab is missing = EOA
    • If "Contract" tab exists = Smart Contract

Method 2: Using the Verification Scripts

  1. Setup:
# Clone this repo
git clone <repo-url>
cd hlyx
npm install
  1. Configure Infura Key:
# Edit the scripts and replace YOUR_INFURA_KEY with an actual key
# You can get a free key at: https://infura.io/
nano verify_critical_finding.js
# Replace: YOUR_INFURA_KEY with your actual key
  1. Run Verification:
node verify_critical_finding.js

Expected output will show:

  • ProxyAdmin Owner is EOA ❌
  • Token Owner is same EOA ❌
  • Pause Controller is EOA ❌

Method 3: Using Cast (Foundry)

# Install Foundry first: https://getfoundry.sh/

# Check ProxyAdmin owner
cast call 0x32fDda6b6Cfe7571c25e3eADeFC9F4faD60C912B "owner()" --rpc-url https://eth.llamarpc.com

# Check Token owner
cast call 0xC210B2cB65ed3484892167F5e05F7ab496Ab0598 "owner()" --rpc-url https://eth.llamarpc.com

# Check pausableController
cast call 0xC210B2cB65ed3484892167F5e05F7ab496Ab0598 "pausableController()" --rpc-url https://eth.llamarpc.com

# Check if address is EOA (returns 0x if EOA)
cast code 0x8ea82F2DC6dAc2078eF0da432a66Ee43BB7193F9 --rpc-url https://eth.llamarpc.com

Method 4: Using Web3.js in Browser Console

Open browser console and run:

// Using public RPC
const web3 = new Web3('https://eth.llamarpc.com');

// Check if address is EOA
const code = await web3.eth.getCode('0x8ea82F2DC6dAc2078eF0da432a66Ee43BB7193F9');
console.log(code === '0x' ? 'EOA' : 'Contract'); // Will print: EOA

📊 Contract Addresses

  • Proxy (Token): 0xC210B2cB65ed3484892167F5e05F7ab496Ab0598
  • ProxyAdmin: 0x32fDda6b6Cfe7571c25e3eADeFC9F4faD60C912B
  • Implementation: 0x28A32d8Ae251578421eD370cDC34faf01414ab22

⚠️ Recommendations

IMMEDIATE ACTION REQUIRED:

  1. Deploy a multisig (minimum 3/5 signers)
  2. Transfer ProxyAdmin ownership to multisig
  3. Transfer Token ownership to multisig
  4. Set pausableController to multisig
  5. Implement timelock for upgrades

📝 License

MIT

👥 Auditor

M8B.dev Security Team


⚠️ DISCLAIMER: This audit identified critical security issues that require immediate attention. The bridge should be considered HIGH RISK until these issues are resolved.

About

Audit of HLYX implementation (Hyperlane LYX)

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published