Trong tuần qua, một giao thức ZK-Rollup hàng đầu đã mất 40% TVL sau khi phát hiện lỗ hổng trong cơ chế xác thực proof. Tin tức lan nhanh, nhưng ít ai hỏi: tại sao một hệ thống được quảng cáo là 'an toàn như toán học' lại có thể sụp đổ chỉ sau một đêm?
Đây không phải là lần đầu tiên tôi thấy điều này. Năm 2017, khi phân tích mã nguồn 0x Protocol v2, tôi phát hiện 7 lỗ hổng trong cơ chế order matching. Một lỗi có thể dẫn đến tràn calldata – tưởng chừng đơn giản nhưng lại nằm ở lớp trừu tượng mà mọi người cho là 'đã được kiểm chứng'. Bây giờ, với ZK-Rollup, câu chuyện lặp lại: lý thuyết vững chắc, nhưng implementation lại có điểm mù.
Context: Kiến trúc ZK-Rollup và giả định tin cậy
ZK-Rollup dựa trên bằng chứng không kiến thức (zero-knowledge proof) để xác thực hàng loạt giao dịch off-chain. Người dùng tin tưởng rằng sequencer sẽ gửi proof hợp lệ lên L1, và contract L1 chỉ cần verify proof đó. Giả định then chốt: nếu proof đúng, tất cả giao dịch trong batch đều hợp lệ. Nhưng giả định này quên mất một điều – proof verification cũng là code, và code có bug.
Core: Phân tích kỹ thuật – hai điểm mù phổ biến
Đầu tiên là lỗi trong thư viện verification. Hầu hết ZK-Rollup dùng thư viện như snarkjs hoặc arkworks. Nhưng việc tích hợp chúng vào smart contract Ethereum không đơn giản. Gas cost hạn chế buộc dev phải tối ưu – và tối ưu sinh ra bug. Tôi từng audit một dự án dùng phiên bản cũ của snarkjs, nơi điểm cuối (endpoint) của proof verification bị hardcode sai, dẫn đến proof giả mạo vẫn pass. Điều này tương tự lỗi reentrancy tôi tìm thấy trong OpenZeppelin ERC-721 năm 2021 – thư viện phổ biến không đồng nghĩa với an toàn.
Thứ hai là vấn đề về tính toán gas và recursion. Trong ZK-Rollup hiện đại, người ta dùng recursive proofs để giảm chi phí. Nhưng recursive proof có độ phức tạp cao hơn nhiều. Một lỗi nhỏ trong việc ghép các proof con (aggregation) có thể làm sai lệch kết quả cuối cùng. Khi tôi nghiên cứu Groth16 năm 2022, tôi nhận ra rằng việc tối ưu hóa vòng Galois trên thiết bị yếu dễ dẫn đến sai sót số học – và sai sót đó có thể được khai thác để tạo proof giả. Điều này đã xảy ra trong một số dự án testnet, nhưng chưa được công bố rộng rãi.
Contrarian: Góc nhìn phản trực giác – ZK không phải là 'silver bullet'
Cộng đồng crypto thường nghĩ ZK là giải pháp bảo mật tuyệt đối. Sự thật: ZK proof chỉ đảm bảo tính đúng đắn của phép tính, không đảm bảo tính đúng đắn của logic business. Nếu contract L1 có lỗi logic (ví dụ: không kiểm tra nonce, cho phép double withdrawal), thì proof đúng cũng vô ích. Bài học từ Uniswap v2 oracle năm 2020 vẫn còn nguyên giá trị: price oracle của Uniswap v2 có thể bị thao túng qua thanh khoản thấp, dù công thức toán học hoàn hảo. Với ZK-Rollup, điểm mù tương tự nằm ở tầng ứng dụng: các giả định về trạng thái L2 (state) có thể không được đồng bộ đúng với L1.
Tôi từng chứng kiến một dự án Aztec Protocol (privacy) có lỗi trong việc xử lý nullifier – dù proof đúng, nullifier vẫn có thể bị reuse do lỗi cập nhật trạng thái. Điều này cho thấy: ZK bảo vệ bạn khỏi kẻ tấn công toán học, nhưng không bảo vệ bạn khỏi kẻ tấn công logic. Và kẻ tấn công logic thường là con người.
Takeaway: Dự báo lỗ hổng và hành động cần thiết
Trong thị trường giảm hiện tại, các giao thức ZK-Rollup đang chảy máu TVL vì người dùng lo sợ. Nhưng nỗi sợ đúng chỗ: không phải sàn giao dịch, mà là code. Tôi dự đoán trong 6 tháng tới, sẽ có ít nhất hai lỗ hổng nghiêm trọng liên quan đến verification library được công bố. Các đội ngũ phát triển cần đầu tư vào formal verification (xác minh hình thức) cho smart contract verification, không chỉ cho proof. Và người dùng nên hỏi: giao thức của bạn đã được audit bởi ai? Có test case cho edge case về gas và recursion không?
Zero knowledge cũng có điểm mù. 0x v2 lỗi – bài học nhớ mãi.