MetronomeDAO vừa công bố một khoảng trống 16 triệu USD. Nguyên nhân được quy cho oracle lag. Tôi đọc xong tin này, không bất ngờ. Tôi bất ngờ vì nó vẫn còn được gọi là "nguyên nhân". Oracle lag không phải là lỗi. Nó là một trạng thái. Và trong 15 năm làm việc với các hệ thống tài chính phi tập trung, tôi chưa từng thấy một giao thức nào thực sự có fail-safe cho trạng thái này.

Hãy để tôi mổ xẻ. Vấn đề không nằm ở oracle. Vấn đề nằm ở giả định an toàn của toàn bộ tầng ứng dụng.
Khi tôi kiểm toán mã nguồn Uniswap v2 vào đầu năm 2020, một trong những điều đầu tiên tôi kiểm tra là cơ chế kiểm soát độ lệch giá (price manipulation guard). Uniswap v2 không có fail-safe cho việc oracle bị trễ trong một khoảng thời gian dài, nhưng nó có một cơ chế đặc biệt: giá được tích lũy qua mỗi khối (accumulator). Điều này làm cho việc thao túng giá chỉ trong một block trở nên tốn kém. Nhưng MetronomeDAO rõ ràng không có cơ chế nào tương tự cho quy trình của họ.
MetronomeDAO, theo công bố chính thức, không phải là một giao thức đơn giản. Đó là một hệ thống đúc và chuyển tài sản xuyên chuỗi, có các phiên đấu giá (auction). Giá đấu giá phụ thuộc vào nguồn giá bên ngoài. Đây chính là điểm yếu. Khi oracle chậm, một người dùng tinh ý sẽ thấy giá trên MetronomeDAO không khớp với giá ở nơi khác. Họ sẽ mua rẻ ở nơi này, bán đắt ở nơi khác. Số chênh lệch đó là một khoản lỗ được hiện thực hóa trên sổ sách của giao thức. 16 triệu USD bốc hơi, không phải vì một cuộc tấn công phức tạp, mà vì một khoảng cách về thời gian giữa hai nguồn dữ liệu.
Khi tôi nghiên cứu về không gian kiến trúc modular blockchain, tôi có một mô hình thử nghiệm nhỏ để kiểm tra hành vi của các hệ thống khi độ trễ tăng. Dữ liệu từ Celestia lưu dưới dạng blob, nhưng câu hỏi tôi đặt ra là: điều gì xảy ra nếu lớp sắp xếp blob bị trễ so với thị trường giao ngay? Trong mô hình sandbox của tôi, một hệ thống không có bộ kiểm soát độ trễ sẽ luôn bị hút máu. Luôn luôn. Với layer 2, tôi đã tự build một mô hình sandbox tương tự để kiểm tra hành vi của sequencer khi mạng chính bị nghẽn. Những bài học đó đều giống nhau: bạn cần một bộ giới hạn tốc độ (rate limiter) được viết bằng code, không phải bằng văn bản quản trị.
MetronomeDAO đã xác nhận một cách không chủ ý một thực tế kỹ thuật: những giao thức dựa trên giá tham chiếu bên ngoài mà không có cơ chế phát hiện và dừng khẩn cấp sẽ trở thành máy ATM cho người chơi chênh lệch giá trên chuỗi.

Câu hỏi đặt ra là: Tại sao một giao thức đã hoạt động trên mạng chính lại bỏ sót một lỗ hổng cơ bản như vậy? Tôi không có mã nguồn MetronomeDAO trước mặt, nhưng tôi có thể đoán rằng họ không kiểm tra hoặc không có một bộ giám sát giá chéo với các nguồn khác. Nếu họ có, một cảnh báo tự động sẽ kích hoạt ngay khi chênh lệch giá quá 5%, và giao thức sẽ tạm dừng. Không có gì trong báo cáo cho thấy họ có hệ thống như vậy.
Khi tôi phân tích các giao thức vay và cho vay, như Compound, tôi thường ghi chú rằng họ có các điều khoản về margin call. Nhưng ngay cả Compound cũng đã từng chịu một đòn tấn công tương tự vào năm 2021 liên quan đến dự đoán giá của DAI. Điều khác biệt là Compound không gọi đó là "oracle lag", họ gọi đó là thiếu kiểm tra biên độ. Thuật ngữ không quan trọng. Hậu quả là giống nhau.
Tôi muốn nói rõ: giá trên một giao thức phi tập trung không bao giờ là một con số duy nhất. Nó là một phạm vi. Nếu giao thức chỉ chấp nhận một giá từ một nguồn, nó sẽ có độ lệch trong phạm vi đó. Một độ lệch lớn hơn phí giao dịch và lớn hơn cả phần bù rủi ro sẽ là một cơ hội kinh doanh. Đó là một trạng thái cân bằng không bền vững.
Người ta có thể nói rằng vấn đề này có thể được giải quyết bằng cách chuyển sang một oracle phi tập trung tốt hơn. Tôi không đồng ý. Thậm chí một oracle phi tập trung với hàng nghìn nút cũng không thể giải quyết vấn đề độ trễ thông tin nếu chính giao thức không xác định được mức độ trễ chấp nhận được. Một oracle tốt hơn sẽ chỉ làm cho cánh cửa nhỏ hơn, không làm cho cánh cửa biến mất.
Nhưng hãy nói về một thứ mà có lẽ ít người chú ý: DAO. MetronomeDAO là một DAO. Và tôi muốn chỉ ra rằng DAO là lý do khiến vốn đã không thể được cứu. Khi một giao thức tập trung phát hiện ra oracle của mình chậm, đội ngũ vận hành chỉ cần vài phút để tạm dừng hợp đồng. Với MetronomeDAO, điều này cần phải có một đề xuất, bỏ phiếu, chờ đợi sau một thời gian khóa, rồi thực thi. Trong khoảng thời gian đó, những người thông minh nhất trên thị trường sẽ rút tiền từ nó. Tôi đã thấy điều này một nghìn lần trong thế giới tài chính truyền thống, nơi các ủy ban rủi ro hoạt động chậm hơn thị trường và trả giá bằng hàng trăm triệu đô la.
Tôi từng nói trong một bài viết của mình về mã nguồn EOS rằng khi tìm thấy ba lỗ hổng kiểm soát truy cập trong hợp đồng ICO của họ, tôi không cần phải hỏi ý kiến của một DAO xem có nên báo cáo hay không. Tôi đã gửi báo cáo và nhận phần thưởng. Đó là một quyết định nhanh chóng. MetronomeDAO không có cơ chế tương tự cho các tình huống khẩn cấp. Nó có một cấu trúc quản trị. Một cấu trúc quản trị vốn được thiết kế để chậm rãi, thận trọng, nhưng trong một cuộc khủng hoảng thanh khoản, sự chậm rãi chính là kẻ giết người.
Điều này đưa đến một điểm phản trực giác: vấn đề của MetronomeDAO không phải là oracle, mà là sự vắng mặt của một cơ chế kiểm tra an toàn (circuit breaker) nằm giữa oracle và các hoạt động kinh tế. Hợp đồng thông minh của họ tin tưởng hoàn toàn vào một nguồn dữ liệu đơn lẻ. Nếu họ có một mô-đun kiểm tra chữ ký đa nguồn và chỉ cho phép thực hiện các giao dịch khi ít nhất hai trong ba nguồn dữ liệu khớp nhau, thì khoản lỗ đã không xảy ra. Điều này không khó để lập trình, đặc biệt là nếu bạn đã làm việc trong ngành lâu năm như tôi.
Nhưng tôi muốn đi xa hơn một chút. Khi người ta nói "oracle lag", họ thường nghĩ về độ trễ về thời gian. Nhưng theo kinh nghiệm của tôi, oracle lag hiếm khi là vấn đề của công nghệ mạng. Nó thường là vấn đề của cấu hình. Một nguồn dữ liệu có thể cập nhật giá sau mỗi 30 giây, nhưng nếu biên độ điều chỉnh tối thiểu (deviation threshold) quá lớn, thì giá sẽ không được cập nhật cho đến khi thị trường biến động đủ lớn. Và khi giá bắt đầu di chuyển nhanh, nó có thể di chuyển qua biên độ đó trong vài giây, nhưng giao thức vẫn giữ giá cũ cho đến khi chu kỳ tiếp theo. Trong một thị trường biến động, cửa sổ không khớp này có thể kéo dài đến vài phút. Với một người vận hành bot chênh lệch giá, vài phút là một kỷ nguyên.
Tôi không biết liệu MetronomeDAO có sử dụng cấu hình như vậy không. Tôi chỉ đưa ra khả năng kỹ thuật. Nhưng nếu tôi đúng, thì điều này có nghĩa là giao thức không chỉ không có fail-safe, mà còn không có đúng cấu hình rủi ro cho các nguồn dữ liệu của mình. Một lỗi vận hành, không phải lỗi giao thức.
Trong bối cảnh thị trường giảm hiện tại, loại sự kiện này có thể gây ra hiệu ứng dây chuyền. Tôi không nghĩ rằng 16 triệu USD sẽ làm sụp đổ toàn bộ DeFi, nhưng nó sẽ khiến các nhà đầu tư tỉnh táo hơn. Họ sẽ bắt đầu đặt câu hỏi về các giả định an toàn của tất cả các giao thức mà họ đang sử dụng. Và điều đó là một điều tốt. Trong một thị trường giá lên, mọi người không muốn nghe về rủi ro. Trong một thị trường giá xuống, đó là tất cả những gì họ có thể nghe.
Câu hỏi duy nhất tôi muốn để lại cho các nhà phát triển đang xây dựng các ứng dụng tương tự: bạn có biết giao thức của bạn sẽ làm gì trong 10 phút khi nguồn dữ liệu giá bên ngoài của bạn bị đóng băng? Nếu câu trả lời của bạn là một đề xuất quản trị, thì bạn đã chết.

Khi tôi dạy những người mới vào nghề cách audit một giao thức, tôi luôn bắt đầu bằng một bài kiểm tra: đọc hợp đồng và tìm xem có bất kỳ khái niệm "paused" và điều kiện kích hoạt nào được lập trình trong hợp đồng hay không. Nếu không có, tôi sẽ kết luận rằng đội ngũ phát triển không xem hoạt động liên tục là một yêu cầu an toàn cốt lõi. Có thể nó không quan trọng với các giao thức văn hóa nhỏ, nhưng với một giao thức quản lý tài sản, nó là thứ tối quan trọng. Và nếu không có, tôi sẽ không bao giờ gửi tiền vào đó. Tôi cũng sẽ không giới thiệu nó cho bất kỳ ai.
Giao thức của bạn có cơ chế dừng khẩn cấp không? Có một ngưỡng chênh lệch giá tối đa không? Nếu không, thì bạn có lỗ hổng cấu trúc tương tự. Uniswap v2 không có fail-safe cho nhiều thứ, nhưng Uniswap v2 không quản lý các khoản vay dựa trên giá. Nó không có khái niệm tài sản được đảm bảo. Nó trao đổi trực tiếp và ngay lập tức. Nếu bạn đang xây dựng một sản phẩm có khái niệm "nợ" hoặc "phải đảm bảo", bạn cần một mô-đun kích hoạt hoạt động nhanh hơn bất kỳ bot nào trên thị trường.
Sai lầm của MetronomeDAO có thể là một cơ hội để các nhà phát triển khác học hỏi. Bởi vì nó không phải là một cuộc tấn công tinh vi. Nó không phải là một chữ ký bị giả mạo. Nó không phải là một thuật toán mã hóa bị phá vỡ. Nó là một lỗ hổng cấp độ ứng dụng đơn giản: tin tưởng một nguồn dữ liệu duy nhất với số phận của 16 triệu USD. Và lý do nó xảy ra là vì những người xây dựng đã không viết ra câu hỏi: "Điều gì xảy ra nếu oracle ngừng cập nhật?". Một câu hỏi có thể đã được trả lời bằng một dòng mã để tạm dừng tất cả hoạt động cho đến khi quản trị viên xác nhận thủ công.
Ở một tầng sâu hơn, tôi muốn nói rằng vấn đề này không nên tồn tại ở một giao thức đã có tên tuổi. Nhưng nó đã tồn tại. Đó là bằng chứng cho thấy ngành công nghiệp này vẫn còn trẻ và đầy cạm bẫy.
Tôi không tin vào các cơ chế bảo hiểm phi tập trung trong vài năm qua vì phần lớn chúng không được kiểm tra trong tình huống khủng hoảng thực tế. Nhưng tôi tin vào các cấu trúc hợp đồng thông minh: nếu bạn không có một cách rõ ràng trong mã để ứng phó với một nguồn dữ liệu ngừng hoạt động, thì bạn không có chiến lược rủi ro. Bạn chỉ có niềm tin.