Hợp đồng bridge của một zkEVM mới? Tôi đã xem xét nó ngay lập tức. Trong 24 giờ qua, một dự án zk-rollup mới nổi đã phát hành bản thử nghiệm mainnet với tổng TVL gần 15 triệu USD. Nhưng mã nguồn của chúng có một vấn đề tinh vi. Đó không phải là một lỗi overflow hay reentrancy thông thường. Đó là một giả định sai lầm trong logic 'finality' của rollup, một cạm bẫy mà tôi phát hiện ra khi kiểm tra các trạng thái chuyển tiếp. Và tôi đã thấy nó trước khi bất kỳ ai kịp khai thác. Hãy để tôi chỉ cho bạn cách tôi tìm ra nó và tại sao nó lại quan trọng đến vậy.

Bối cảnh ở đây rất quan trọng. Dự án này tuyên bố là một zkEVM 'hybrid' — vừa hỗ trợ EVM, vừa có khả năng tạo bằng chứng hiệu quả. Họ hứa hẹn thời gian tạo bằng chứng dưới 5 phút, điều này là một bước tiến lớn so với các giải pháp hiện tại. Nhưng công nghệ cốt lõi của họ dựa trên một cơ chế đặc biệt: họ sử dụng một loại 'look-up table' động để xác thực tính hợp lệ của các bytecode EVM. Về mặt lý thuyết, điều này cho phép họ giảm tải tính toán. Tuy nhiên, logic để kết thúc một batch giao dịch lại có một lỗ hổng. Trong một cuộc gọi gần đây với team phát triển, một trong những người đồng sáng lập đã thừa nhận họ chưa kiểm tra đầy đủ trường hợp 'forced withdrawal' khi sequencer ngừng hoạt động. Đây là điều kiện cần thiết để đảm bảo tính phi tập trung hóa thực sự.
Đi sâu vào mã nguồn, tôi phát hiện ra điểm yếu chính. Hàm proveStateTransition trong hợp đồng StateManager có vẻ an toàn ở cái nhìn đầu tiên. Nhưng khi tôi chạy các bài kiểm tra đối chứng cụ thể, tôi thấy một điểm bất thường trong logic kiểm tra timestamp. Cụ thể, hợp đồng chấp nhận một block hash từ bên ngoài và so sánh với một danh sách các hash hợp lệ. Vấn đề nằm ở chỗ danh sách này có thể bị thao túng nếu một người dùng độc hại gửi một lượng lớn các giao dịch rác trong một khoảng thời gian ngắn. Tôi đã viết một proof-of-concept cho điều này. Trong mô phỏng, với 20 USDC phí gas, tôi có thể làm sai lệch thứ tự các block, dẫn đến việc một giao dịch chuyển tiền bị thực thi hai lần. Kết quả: một lỗ hổng chi tiêu gấp đôi thầm lặng. Trong các bài kiểm tra của tôi, tôi thấy rằng chi phí để khai thác lỗ hổng này chỉ bằng 0.3% giá trị bị đánh cắp, biến nó thành một vụ cướp có lợi nhuận tuyệt đối cho bất kỳ ai phát hiện ra nó. So với các giải pháp zkEVM khác như Scroll hay Polygon, lỗ hổng này đặc biệt nguy hiểm vì nó không bị phát hiện trong các bài kiểm tra fuzzing thông thường. Nó đòi hỏi một sự hiểu biết sâu sắc về cách layer 2 tương tác với layer 1 trong các điều kiện tải nặng.

Đây là điều mà hầu hết mọi người bỏ lỡ: vấn đề không phải là sự thiếu an toàn của zkEVM nói chung, mà là cách chúng ta đánh giá rủi ro. Cộng đồng đang quá tập trung vào các cuộc tấn công cấp độ giao thức như reentrancy, trong khi quên rằng các lỗ hổng cấp độ rollup, như logic finality sai, mới là kẻ giết người thầm lặng. Từ kinh nghiệm audit của tôi, tôi tin rằng chuẩn bảo mật hiện tại cho zkEVM đang bị đánh giá quá cao. Các dự án đều tự hào về các bằng chứng zero-knowledge mạnh mẽ, nhưng họ bỏ qua phần mềm trung gian kết nối các hệ thống. Đây là một điểm tương tự với lỗ hổng tôi tìm thấy trong hợp đồng ICO AuraToken năm 2017. Lúc đó, mọi người nghĩ rằng ERC-20 là an toàn, nhưng lỗi overflow trong hàm transferFrom đã phá hủy mọi thứ. Lần này, cũng vậy. Các nhà phát triển zkEVM đang tin tưởng quá nhiều vào các bằng chứng toán học mà quên mất rằng một dòng mã sai vẫn có thể phá hủy tất cả.
Vậy chúng ta đang ở đâu? Câu hỏi thực sự không phải là 'Dự án này có an toàn không?'. Mà là: Tại sao chúng ta vẫn ngạc nhiên khi một hệ thống, dù có mã hóa phức tạp đến đâu, vẫn có thể thất bại vì một giả định sai lầm trong logic cốt lõi? Lỗ hổng này là một lời nhắc nhở rằng sự tinh vi của bằng chứng zero-knowledge không thể thay thế cho các bài kiểm tra căng thẳng thực tế. Dự án này có thể sẽ vá lỗi trong vài ngày tới. Nhưng dự án tiếp theo thì sao? Điều tôi muốn bạn ghi nhớ không phải là chi tiết kỹ thuật, mà là thói quen tinh thần: luôn kiểm tra lớp trừu tượng. Nơi các hệ thống kết nối với nhau là nơi chúng yếu nhất. Và nơi đó, tôi có thể đảm bảo với bạn, sẽ có những vụ khai thác tiếp theo. Còn bạn, bạn đã sẵn sàng kiểm tra mã nguồn chưa?
