Model Baru Keamanan Kontrak DeFi: Fokus pada Protokol Invarian

Ringkasan

Jangan hanya menulis pernyataan wajib untuk fungsi tertentu; tulis pernyataan wajib untuk protokol Anda. Pemeriksaan kepatuhan fungsi (persyaratan)-efektivitas (Efek)-interaksi (Interaksi) + invarian protokol (Iniants) atau mode FREI-PI dapat membantu kontrak Anda menjadi lebih aman, karena ini memaksa pengembang untuk fokus pada keamanan tingkat fungsi, Perhatikan juga untuk invarian pada tingkat protokol.

motivasi

Pada Maret 2023, Euler Finance diretas dan kehilangan $200 juta. Euler Finance adalah pasar pinjaman di mana pengguna dapat menyetor agunan dan meminjamnya. Ini memiliki beberapa fitur unik, sebenarnya mereka adalah pasar pinjaman yang sebanding dengan Compound Finance dan Aave.

Anda dapat membaca postmortem tentang peretasan ini di sini. Konten utamanya adalah kurangnya pemeriksaan kesehatan dalam fungsi tertentu, yang memungkinkan pengguna untuk mematahkan invarian mendasar dari pasar pinjaman.

Para Inisiat Mendasar

Inti dari sebagian besar protokol DeFi adalah kekekalan, properti status program yang diharapkan selalu benar. Dimungkinkan juga untuk memiliki banyak invarian, tetapi secara umum, invarian tersebut dibuat berdasarkan ide inti. Berikut beberapa contohnya:

  • Seperti di pasar pinjaman: pengguna tidak dapat mengambil tindakan apa pun untuk menempatkan akun apa pun dalam posisi agunan yang tidak aman atau kurang aman ("kurang aman" berarti sudah di bawah ambang batas keamanan minimum dan oleh karena itu tidak dapat ditarik lebih lanjut).
  • Dalam AMM DEX: x * y == k, x + y == k, dll.
  • Dalam staking penambangan likuiditas: pengguna hanya dapat menarik jumlah token staking yang mereka setorkan.

Apa yang salah dengan Euler Finance belum tentu mereka menambahkan fitur, tidak menulis tes, atau tidak mengikuti praktik terbaik tradisional. Mereka mengaudit pemutakhiran dan melakukan tes, tetapi masih lolos dari celah. Masalah utamanya adalah mereka melupakan invarian inti dari pasar pinjaman (seperti halnya auditor!).

*Catatan: Saya tidak mencoba memilih Euler, mereka adalah tim yang berbakat, tetapi ini adalah kasus baru-baru ini. *

Inti masalahnya

Anda mungkin berpikir "Ya, itu benar. Itu sebabnya mereka diretas; mereka lupa pernyataan wajib". Iya dan tidak.

Tetapi mengapa mereka melupakan pernyataan yang diperlukan?

periksa - validasi - interaksi tidak cukup baik

Pola umum yang direkomendasikan untuk pengembang soliditas adalah pola Interaksi-Efek-Cek. Ini sangat berguna untuk menghilangkan bug terkait reentrancy, dan seringkali meningkatkan jumlah validasi masukan yang harus dilakukan pengembang. _Tapi_, rentan terhadap masalah tidak melihat hutan untuk pepohonan.

Apa yang diajarkannya kepada pengembang adalah: "Pertama saya menulis pernyataan yang saya perlukan, lalu saya melakukan validasi, lalu mungkin saya melakukan interaksi apa pun, lalu saya aman". Masalahnya adalah, lebih sering daripada tidak, itu menjadi campuran pemeriksaan dan efek -- tidak buruk, ya? Interaksi masih final, jadi reentrancy tidak menjadi masalah. Tapi itu memaksa pengguna untuk fokus pada fungsi yang lebih spesifik dan transisi negara individu daripada konteks global yang lebih luas. Ini berarti bahwa:

Pola cek-validasi-interaksi belaka membuat pengembang melupakan invarian inti dari protokol mereka.

Ini masih merupakan pola yang sangat baik untuk pengembang, tetapi invarian protokol harus selalu dipastikan (serius, Anda harus tetap menggunakan CEI!).

Lakukan dengan benar: mode FREI-PI

Ambil contoh cuplikan ini dari kontrak SoloMargin dYdX (kode sumber), yang merupakan pasar peminjaman dan kontrak perdagangan leverage. Ini adalah contoh yang baik dari apa yang saya sebut pola Fungsi Persyaratan-Efek-Interaksi + Protokol Iniants, atau pola FREI-PI.

Dengan demikian, saya yakin ini adalah satu-satunya pasar pinjaman di pasar pinjaman tahap awal yang tidak memiliki kerentanan terkait pasar. Senyawa dan Aave tidak memiliki masalah langsung, tetapi garpu mereka memilikinya. Dan bZx telah diretas berkali-kali.

Periksa kode di bawah ini dan perhatikan abstraksi berikut:

  1. Periksa parameter input (_verifyInputs).
  2. Tindakan (konversi data, manipulasi status)
  3. Periksa keadaan akhir (_verifyFinalState).

Interaksi-Efek-Pemeriksaan biasa masih dilakukan. Perlu dicatat bahwa cek-validasi-interaksi dengan cek tambahan tidak setara dengan FREI-PI--keduanya mirip tetapi melayani tujuan yang berbeda secara fundamental. Oleh karena itu, pengembang harus menganggapnya berbeda: FREI-PI, sebagai abstraksi yang lebih tinggi, bertujuan untuk keamanan protokol, sedangkan CEI bertujuan untuk keamanan fungsional.

Struktur kontrak ini sangat menarik - pengguna dapat melakukan tindakan yang mereka inginkan (menyetor, meminjam, memperdagangkan, mentransfer, melikuidasi, dll.) dalam rangkaian tindakan. Ingin menyetor 3 token berbeda, menarik yang ke-4, dan melikuidasi akun? Ini satu panggilan.

Inilah kekuatan FREI-PI: pengguna dapat melakukan apa pun yang mereka inginkan dalam protokol, selama invarian dari pasar peminjaman inti bertahan di akhir panggilan: satu pengguna tidak dapat mengambil tindakan apa pun yang akan membuat akun apa pun tidak aman atau lebih Posisi agunan yang tidak aman. Untuk kontrak ini, ini dilakukan di _verifyFinalState , memeriksa agunan dari setiap akun yang terpengaruh untuk memastikan bahwa perjanjian tersebut lebih baik daripada saat transaksi dimulai.

Ada beberapa invarian tambahan yang disertakan dalam fungsi ini yang melengkapi invarian inti dan membantu dengan fungsi sampingan seperti menutup pasar, tetapi pemeriksaan intilah yang benar-benar menjaga keamanan protokol.

FREI-PI yang berpusat pada entitas

Masalah lain dengan FREI-PI adalah konsep entitas-sentris. Ambil pasar peminjaman dan asumsikan invarian inti sebagai contoh:

Secara teknis, ini bukan satu-satunya invarian, tetapi untuk entitas pengguna (ini masih invarian protokol inti, dan biasanya invarian pengguna adalah invarian protokol inti). Pasar pinjaman juga biasanya memiliki 2 entitas tambahan:

  • Oracle
  • Manajemen / Pemerintahan

Setiap kekekalan tambahan membuat protokol lebih sulit untuk dijamin, jadi semakin sedikit semakin baik. Ini sebenarnya yang dikatakan Dan Elitzer dalam artikelnya yang berjudul: Mengapa DeFi Rusak dan Cara Memperbaikinya #1 Oracle-less Protocol (petunjuk: artikel tersebut tidak benar-benar mengatakan bahwa oracle adalah masalahnya).

Peramal

Untuk oracle, ambil eksploitasi Cream Finance senilai $130 juta. Kekekalan inti entitas oracle:

Ternyata, memverifikasi oracle saat runtime dengan FREI-PI itu rumit, tetapi bisa dilakukan, dengan beberapa pemikiran ke depan. Secara umum, Chainlink adalah pilihan yang baik untuk diandalkan, memuaskan sebagian besar kekekalan. Dalam kasus manipulasi atau kejutan yang jarang terjadi, mungkin bermanfaat untuk memiliki perlindungan yang mengurangi fleksibilitas demi akurasi (seperti memeriksa bahwa nilai terakhir yang diketahui beberapa persen lebih besar dari nilai saat ini). Juga, sistem SoloMargin dYdX melakukan pekerjaan yang baik dengan oracle DAI mereka, berikut kodenya (jika Anda tidak tahu, menurut saya ini adalah sistem kontrak pintar kompleks terbaik yang pernah ditulis).

Untuk lebih lanjut tentang evaluasi oracle, dan menyoroti kemampuan tim Euler, mereka menulis artikel bagus tentang manipulasi komputasi harga oracle Uniswap V3 TWAP.

Administrasi / Pemerintahan

Membuat invarian untuk entitas terkelola adalah yang paling sulit. Ini terutama disebabkan oleh fakta bahwa sebagian besar peran mereka adalah mengubah invarian lain yang ada. Yang mengatakan, jika Anda dapat menghindari penggunaan peran administratif, Anda harus melakukannya.

Pada dasarnya, invarian inti dari entitas terkelola adalah:

Interpretasi: Admin dapat melakukan hal-hal yang seharusnya tidak merusak invarian, kecuali jika mereka mengubah hal-hal secara drastis untuk melindungi dana pengguna (misalnya: memindahkan aset ke dalam kontrak penyelamatan adalah penghapusan invarian). Admin juga harus dianggap sebagai pengguna, sehingga invarian pengguna dari pasar peminjaman inti juga harus berlaku untuk mereka (artinya mereka tidak dapat menyerang pengguna atau protokol lain). Saat ini, beberapa tindakan administrator tidak mungkin diverifikasi saat runtime melalui FREI-PI, tetapi dengan invarian yang cukup kuat di tempat lain, semoga sebagian besar masalah dapat dikurangi. Saya katakan saat ini, karena dapat dibayangkan menggunakan sistem bukti zk yang dapat memeriksa seluruh status kontrak (per pengguna, per oracle, dll.).

Sebagai contoh administrator melanggar kekekalan, ambil tindakan tata kelola Compound yang merusak pasar cETH pada Agustus 2022. Pada dasarnya, pemutakhiran ini merusak kekekalan Oracle: Oracle memberikan informasi yang akurat dan (relatif) real-time. Karena fungsionalitas yang hilang, Oracle dapat memberikan informasi yang salah. Verifikasi FREI-PI run-time, memeriksa apakah Oracle yang terpengaruh dapat memberikan informasi waktu nyata, dapat mencegah hal ini terjadi dengan pemutakhiran. Ini dapat dimasukkan ke dalam _setPriceOracle untuk memeriksa apakah semua aset menerima informasi realtime. Hal yang menyenangkan tentang FREI-PI untuk peran admin adalah bahwa peran admin relatif tidak sensitif terhadap harga (atau setidaknya seharusnya demikian), jadi lebih banyak penggunaan gas seharusnya tidak menjadi masalah besar.

Kompleksitas itu Berbahaya

Jadi sementara invarian yang paling penting adalah invarian inti dari protokol, ada juga beberapa invarian entitas-sentris yang harus dipegang oleh invarian inti. Namun, kumpulan invarian yang paling sederhana (dan terkecil) mungkin adalah yang paling aman. Sederhana itu bagus Contoh cemerlangnya adalah Uniswap…

Mengapa Uniswap tidak pernah diretas (mungkin)

AMM dapat memiliki invarian dasar paling sederhana dari semua primitif DeFi: tokenBalanceX * tokenBalanceY == k (mis. model produk konstan). Setiap fungsi di Uniswap V2 berkisar pada invarian sederhana ini:

  1. Mint : ditambahkan k
  2. Bakar: kurangi dari k
  3. Tukar: transfer x dan y, tapi tetap k.
  4. Skim: atur ulang tokenBalanceX * tokenBalanceY agar sama dengan k, dan hapus bagian yang berlebihan.

Rahasia keamanan Uniswap V2: intinya adalah kekekalan sederhana, dan semua fungsi mendukungnya. Satu-satunya entitas lain yang dapat diperdebatkan adalah tata kelola, yang dapat menghidupkan sakelar biaya, yang tidak menyentuh kekekalan inti, hanya distribusi kepemilikan saldo token. Kesederhanaan dalam pernyataan keamanan mereka adalah mengapa Uniswap tidak pernah diretas. Kesederhanaan sebenarnya bukan penghinaan bagi pengembang yang sangat baik dari kontrak pintar Uniswap, sebaliknya, dibutuhkan insinyur yang hebat untuk menemukan kesederhanaan.

Masalah gas

Twitter saya sudah penuh dengan jeritan horor dan rasa sakit karena optimisasi bahwa pemeriksaan ini tidak perlu dan tidak efisien. Dua hal tentang pertanyaan ini:

  1. Apakah Anda tahu apa lagi yang tidak efisien? Harus mengirim pesan ke ~~Laurence~~ peretas Korea Utara melalui etherscan, mentransfer uang menggunakan ETH, dan mengancam bahwa FBI akan campur tangan.
  2. Anda mungkin sudah memuat semua data yang Anda butuhkan dari penyimpanan, jadi di akhir panggilan, cukup tambahkan sedikit cek wajib ke hot data. Apakah Anda ingin perjanjian Anda dikenakan biaya yang dapat diabaikan, atau membiarkannya mati?

Jika biayanya mahal, pikirkan ulang variabel inti, dan coba sederhanakan.

Apa artinya ini bagi saya?

Sebagai pengembang, penting untuk mendefinisikan dan mengekspresikan invarian inti di awal proses pengembangan. Sebagai saran konkret: fungsi pertama untuk menulis sendiri adalah _verifyAfter, untuk memverifikasi invarian Anda setelah setiap panggilan ke kontrak Anda. Masukkan ke dalam kontrak Anda, dan terapkan di sana. Lengkapi invarian ini (dan invarian entitas-sentris lainnya) dengan pengujian invarian yang lebih luas yang diperiksa sebelum penerapan (Panduan pengecoran).

Penyimpanan sementara membuka beberapa pengoptimalan dan peningkatan menarik yang akan dicoba oleh Nascent -- Saya sarankan Anda mempertimbangkan bagaimana penyimpanan sementara dapat digunakan sebagai alat untuk keamanan yang lebih baik di seluruh konteks panggilan.

Dalam artikel ini, tidak banyak waktu yang dihabiskan untuk pengenalan model FREI-PI untuk input validasi, tetapi juga sangat penting. Menentukan batasan input adalah tugas yang menantang untuk menghindari luapan dan situasi serupa. Pertimbangkan untuk memeriksa dan mengikuti perkembangan alat kami: pirometer (saat ini dalam versi beta, tolong beri kami bintang). Itu dapat menelusuri dan membantu menemukan tempat di mana Anda mungkin tidak melakukan validasi masukan.

Kesimpulannya

Di atas akronim yang menarik (FREI-PI) atau nama skema, bagian yang sangat penting adalah:

Temukan kesederhanaan dalam kekekalan inti protokol Anda. Dan bekerja keras untuk memastikan itu tidak pernah hancur (atau tertangkap sebelum itu).

Lihat Asli
This page may contain third-party content, which is provided for information purposes only (not representations/warranties) and should not be considered as an endorsement of its views by Gate, nor as financial or professional advice. See Disclaimer for details.
  • Hadiah
  • Komentar
  • Bagikan
Komentar
0/400
Tidak ada komentar
  • Sematkan
Perdagangkan Kripto Di Mana Saja Kapan Saja
qrCode
Pindai untuk mengunduh aplikasi Gate
Komunitas
Bahasa Indonesia
  • 简体中文
  • English
  • Tiếng Việt
  • 繁體中文
  • Español
  • Русский
  • Français (Afrique)
  • Português (Portugal)
  • Bahasa Indonesia
  • 日本語
  • بالعربية
  • Українська
  • Português (Brasil)