Khi tôi mở file mã nguồn của NostraNet – một ZK-rollup mới huy động 100 triệu USD trong thị trường tăng – điều đầu tiên tôi thấy không phải là bằng chứng không kiến thức, mà là một mâu thuẫn. Hợp đồng ProxyAdmin của họ chỉ ghi nhận 3 địa chỉ trong mảng _owners, trong khi tài liệu trắng tuyên bố “ít nhất 6 bên độc lập quản trị”. Tôi lập tức đặt câu hỏi: liệu đây có phải là lỗi trong quá trình deploy, hay là một thiết kế cố ý?
Đây không phải lần đầu tôi gặp tình huống như vậy. Năm 2017, tôi phát hiện lỗ hổng reentrancy trong hợp đồng ICO EtherGrow – một dự án huy động 12.000 ETH. Lúc đó tôi mới 24 tuổi, vừa nhận bằng Tiến sĩ Mật mã. Tôi báo cáo lên GitHub, kêu gọi cộng đồng qua Telegram, và giúp 2.500 nhà đầu tư thoát khỏi thảm họa. Từ đó, tôi học được rằng mã nguồn không bao giờ nói dối – nhưng con người thì có thể. Với NostraNet, tôi quyết định dành một tuần để kiểm tra toàn bộ stack của họ, từ mô-đun PlonkVerifier đến cơ chế cầu nối.
— Root: Cảm xúc khi tôi tìm ra sự thật này là sự báo động lẫn lộn với thất vọng. Bởi vì tôi biết, trong thị trường tăng giá, rất ít người dùng chịu dừng lại để đọc một dòng code. Họ chỉ nhìn vào TVL tăng 300% sau 3 tuần và những lời hứa “tốc độ giao dịch 100.000 TPS”. Nhưng tôi, với vai trò là một người bảo vệ cộng đồng, buộc phải cảnh báo.
Hãy cùng tôi đi sâu vào code. NostraNet là một ZK-rollup sử dụng mô hình settlement trên Ethereum, tương tự Optimism nhưng thay thế cơ chế fraud proof bằng zk-SNARKs. Họ tuyên bố đã được ba công ty audit hàng đầu kiểm tra, và không có lỗ hổng nghiêm trọng. Điều đó đúng trên lý thuyết. Nhưng vấn đề không nằm ở mạch logic của zk-proof, mà nằm ở lớp quản trị – nơi quyết định ai có thể nâng cấp hợp đồng, ai có thể rút ETH từ cầu nối.
Trong hợp đồng NostraGovernor.sol, tôi tìm thấy hàm upgradeTo(address newImplementation) chỉ được bảo vệ bởi modifier onlyOwner. Và onlyOwner kiểm tra msg.sender có nằm trong mảng owners với kích thước 3. Ba địa chỉ này lần lượt là: một ví multisig 2/3 do team dự án kiểm soát, một ví của quỹ đầu tư chính, và một ví lạ không có dấu hiệu hoạt động on-chain trước đó. Khi tôi truy vết giao dịch deploy, tôi thấy rằng cả ba địa chỉ đều được thêm bởi cùng một EOA (Externally Owned Account) – tức là một người dùng duy nhất đã khởi tạo toàn bộ hệ thống quản trị. Đây là diver thực sự: không phải mã nguồn sai, mà là quy trình thiết lập tập trung.
Tôi gọi đây là “điểm mù của audit truyền thống”. Các công ty audit thường kiểm tra tính đúng đắn của logic, nhưng hiếm khi đặt câu hỏi: “ai thực sự có quyền thay đổi logic đó?”. Với NostraNet, nếu một trong ba chủ sở hữu bị thỏa hiệp (hoặc thậm chí là ba người cùng hành động), họ có thể nâng cấp hợp đồng lên bất kỳ phiên bản nào – kể cả phiên bản cho phép rút toàn bộ token trong cầu nối. Cộng đồng sẽ không thể ngăn chặn vì multisig là 2/3 – chỉ cần hai chữ ký là đủ.
— Khi tôi đào sâu vào code, tôi thấy một 'diver' thực sự: không phải lỗi syntax, mà là lỗ hổng trong uy tín con người.
Một số người có thể nói: “Nhưng dự án nào chẳng có multisig? Đó là chuẩn mực”. Đúng, nhưng vấn đề là NostraNet công khai tuyên bố “6 bên độc lập” trong khi thực tế chỉ có 3. Họ cố tình hoặc vô tình gây hiểu lầm. Nếu họ muốn phi tập trung thực sự, họ có thể dùng một DAO với đề xuất on-chain và thời gian khóa. Thay vào đó, họ chọn giải pháp nhanh, tiết kiệm gas, nhưng hy sinh tính bảo mật.
Hơn nữa, tôi phát hiện trong hợp đồng cầu nối NostraBridge.sol, có một hàm emergencyPause() chỉ có thể gọi bởi owner. Hàm này có thể tạm dừng toàn bộ hoạt động rút tiền trong vòng 7 ngày. Không có cơ chế kiểm tra nào từ cộng đồng. Nếu team muốn “khoá” thanh khoản để mua thêm thời gian, họ hoàn toàn có thể. Điều này đặc biệt nguy hiểm trong bối cảnh thị trường tăng, khi các dự án dễ dùng biện pháp khẩn cấp để tránh sự hoảng loạn tạm thời – nhưng cũng có thể lạm dụng để thực hiện hành vi xấu.
Tôi không khẳng định NostraNet là lừa đảo. Tôi chỉ chỉ ra rằng cấu trúc quản trị của họ có rủi ro tập trung cao hơn nhiều so với những gì họ quảng cáo. Với tư cách một Smart Contract Architect, tôi đã xây dựng thư viện SoliditySafeLibs vào năm 2020, và tôi biết giá của việc chạy theo phản hồi cộng đồng. Khi đó tôi bỏ qua tối ưu gas để thêm tính năng, dẫn đến chi phí giao dịch cao hơn 15%. NostraNet cũng đang chạy theo tốc độ và TVL, nhưng quên mất rằng sự tin tưởng là tài sản quý nhất của người dùng.
— Root: Cảm xúc của tôi bây giờ là sự xót xa, bởi tôi đã chứng kiến quá nhiều dự án tương tự sụp đổ trong bear market trước. Nhưng trong bull market, FOMO khiến mọi người mù quáng.
Trong workshop “Smart Contract Safety for All” tôi tổ chức năm 2022, tôi đã phân tích 15 vụ hack nổi tiếng. Điểm chung: hầu hết đều bắt nguồn từ quyền nâng cấp không được kiểm soát. Wormhole mất 320 triệu USD vì multisig bị tấn công. Ronin mất 600 triệu USD vì 5/9 validator bị kiểm soát. NostraNet với 2/3 multisig còn dễ bị tổn thương hơn. Nếu hacker chiếm được hai private key, trò chơi kết thúc.
Vậy giải pháp là gì? Tôi đề xuất yêu cầu tối thiểu: số lượng multisig tối thiểu là 5, ngưỡng ký tối thiểu là 4/5. Thời gian khóa nâng cấp tối thiểu 48 giờ để cộng đồng có thể phản ứng. Và quan trọng nhất, danh tính các chủ sở hữu phải được công khai – không thể là ví ẩn danh. Nếu NostraNet thực sự muốn xây dựng niềm tin, hãy chứng minh bằng code, không chỉ bằng whitepaper.
— Đây là 'diver' cuối cùng: những người dùng thông thái sẽ kiểm tra mã nguồn, nhưng ngay cả họ cũng có thể bỏ qua chi tiết này.
Thị trường tăng giá không phải lý do để hạ thấp tiêu chuẩn bảo mật. Tôi đã kiểm tra 47 dự án DeFi cho thư viện của mình, và tôi biết rằng sự cẩu thả trong quản trị luôn dẫn đến hậu quả. Hãy coi bài viết này như một lời nhắc: trước khi FOMO, hãy dành 10 phút kiểm tra xem contract có thể nâng cấp không, ai có quyền nâng cấp, và liệu bạn có tin tưởng họ không.
Còn NostraNet? Tôi hy vọng họ sẽ sửa đổi và minh bạch hơn. Nếu không, tôi sẽ tiếp tục theo dõi và cập nhật. Bởi vì trong thế giới on-chain, mã lệnh không bao giờ nói dối.