Daftar Kerentanan Umum
Kerentanan kontrak pintar dapat menyebabkan konsekuensi bencana dan seringkali tidak dapat diubah setelah diterapkan. Eksploitasi kelemahan ini merupakan tantangan besar bagi keamanan blockchain, mengakibatkan miliaran dolar aset dicuri dan merusak kepercayaan pengguna. Oleh karena itu, mencapai keamanan kontrak pintar yang kuat sangatlah penting. Hal ini membutuhkan lebih dari sekadar menerapkan kode ke blockchain. Hal ini menuntut praktik pengkodean aman yang ketat, pengujian menyeluruh, dan seringkali, audit kontrak pintar independen untuk mengidentifikasi masalah sebelum dapat dieksploitasi. Memahami kesalahan umum – mulai dari serangan reentrancy seperti peretasan DAO yang terkenal hingga kesalahan logika yang halus dan kerentanan Ethereum seperti integer overflow – adalah langkah kritis pertama menuju mitigasi risiko. Halaman ini memberikan gambaran umum penting tentang kerentanan kontrak pintar yang sering terjadi untuk meningkatkan kesadaran dan mendorong pengembangan yang lebih aman dalam ekosistem terdesentralisasi.
- Reentrancy
- Unexpected Ether
- DoS
- Overflow
- tx.origin Authentication
- Access Control
- Weak Randomness
- Hash Collision
- Precision Loss
- msg.value in loop
- ecrecover
- Replay
- Inheritance Order
- MEV
Reentrancy adalah salah satu kerentanan kontrak pintar (smart contract) paling awal dan paling merusak, bertanggung jawab atas eksploitasi historis yang signifikan seperti peretasan The DAO, yang menyebabkan hard fork Ethereum. Ini tetap menjadi ancaman kritis dengan konsekuensi yang berpotensi mengerikan, mampu menguras semua dana dari kontrak.
Kerentanan ini berasal dari anti-pola pengkodean yang umum, sering kali terbawa dari kebiasaan Web2: melakukan interaksi eksternal (seperti mentransfer Ether atau memanggil kontrak lain) sebelum memperbarui status internal kontrak (misalnya, saldo pengguna). Ketika sebuah kontrak mengirim Ether atau memanggil kontrak eksternal, ia mentransfer kontrol eksekusi untuk sementara. Penyerang yang mengendalikan kontrak penerima dapat mengeksploitasi ini dengan segera memanggil kembali ke kontrak asli, seringkali melalui fungsi receive atau fallback yang dipicu oleh transfer Ether, atau melalui kait (hooks) standar token.
Karena status kontrak asli (misalnya, saldo penyerang) belum diperbarui, panggilan re-entrant lolos pemeriksaan awal, memungkinkan penyerang mengulangi tindakan (seperti menarik dana) berkali-kali dalam transaksi yang sama. Loop rekursif ini berlanjut hingga dana terkuras habis atau batas gas tercapai.
Meskipun serangan klasik melibatkan fungsi tunggal, variasi yang lebih kompleks ada, seperti reentrancy lintas-fungsi (mengeksploitasi status bersama antar fungsi) dan reentrancy hanya-baca (read-only - memanipulasi pembacaan status melalui fungsi tampilan atau view functions).
Pertahanan utama adalah pola Checks-Effects-Interactions (CEI) atau Pemeriksaan-Efek-Interaksi: lakukan semua pemeriksaan yang diperlukan, kemudian perbarui variabel status (efek), dan hanya setelah pembaruan ini, berinteraksilah dengan kontrak eksternal.
Kerentanan "Manipulasi Saldo Melalui Ether Tak Terduga" muncul karena smart contract Solidity dapat menerima Ether melalui mekanisme yang melewati fungsi `receive` dan `fallback` yang telah ditentukan. Metode utama untuk injeksi Ether "tak terduga" ini adalah opcode `selfdestruct`, yang secara paksa mentransfer saldo kontrak yang sedang dihancurkan ke alamat yang ditunjuk, dan transaksi coinbase (hadiah blok).
Masalah intinya adalah bahwa transfer paksa ini secara langsung meningkatkan saldo Ether kontrak (`address(this).balance`) tanpa memicu logika terprogram kontrak untuk menangani dana masuk. Hal ini merusak asumsi atau invarian umum, yang seringkali implisit: bahwa saldo aktual kontrak secara akurat mencerminkan jumlah dana yang diproses melalui fungsi `payable` yang dimaksudkan atau dicatat secara internal.
Kontrak yang salah menggunakan `address(this).balance` untuk pemeriksaan logika kritis menjadi rentan. Misalnya, kontrak mungkin memeriksa bahwa `address(this).balance == jumlahYangDiharapkan`. Penyerang dapat mengeksploitasi ini dengan menggunakan `selfdestruct` untuk mengirim sejumlah kecil Ether, sehingga memanipulasi saldo. Hal ini dapat menyebabkan:
Denial of Service (DoS): Pemeriksaan kesetaraan ketat dapat rusak secara permanen, membuat fungsi tidak dapat digunakan.
Manipulasi Logika: Ambang batas dapat tercapai sebelum waktunya, memicu perubahan status atau pembayaran yang tidak diinginkan.
Pelanggaran `assert`: Dalam kasus yang jarang terjadi, saldo tak terduga dapat menyebabkan inkonsistensi status internal yang menyebabkan `assert()` gagal, menghabiskan semua gas transaksi.
Mitigasi mendasar adalah jangan pernah mengandalkan `address(this).balance` untuk logika kontrak. Sebaliknya, kontrak harus memelihara akuntansi internal yang akurat menggunakan variabel status khusus, memperbaruinya hanya dalam fungsi penanganan dana yang sah. Semua pemeriksaan kritis dan transisi status harus didasarkan pada variabel internal yang andal ini.
Kerentanan Penolakan Layanan (Denial of Service, DoS) dalam smart contract Solidity bertujuan untuk mengganggu atau menghentikan sepenuhnya fungsionalitas yang dimaksud dari kontrak, mencegah pengguna yang sah mengakses layanannya. "Layanan" yang ditolak adalah kemampuan kontrak untuk mengeksekusi fungsinya sebagaimana diprogramkan dan diharapkan oleh penggunanya.
Penyerang mencapai ini dengan mengeksploitasi celah dalam logika kode kontrak, memanipulasi batasan sumber daya (terutama gas), atau memanfaatkan dependensi eksternal.
Pola umum meliputi:
Kehabisan Gas (Gas Exhaustion): Membuat transaksi atau memanipulasi state (status) agar biaya eksekusi fungsi melebihi batas gas blok atau batas gas transaksi. Hal ini sering kali melibatkan pemicuan operasi yang mahal secara komputasi atau, yang sangat umum, melakukan iterasi pada array tak terbatas (unbounded arrays) yang ukurannya dapat bertambah tanpa batas. Seiring bertambahnya data, biaya gas loop melampaui batas, membuat fungsi tersebut tidak dapat digunakan.
Revert (Pengembalian) Tak Terduga: Menyebabkan fungsi kritis mengalami revert (pengembalian kondisi sebelumnya) secara tak terduga. Hal ini dapat dipicu dengan memaksa panggilan eksternal gagal (misalnya, mengirim dana ke kontrak yang menolaknya), memanipulasi state agar kondisi `require` gagal, atau pengecualian (exception) lain yang tidak ditangani. Jika kontrak bergantung pada panggilan eksternal yang gagal (mungkin disebabkan secara jahat), seluruh operasi dapat diblokir.
Sifat imutabel (tidak dapat diubah) dari smart contract membuat DoS menjadi sangat parah. Serangan yang berhasil dapat menyebabkan dana terkunci secara permanen atau fungsionalitas yang tidak dapat dipulihkan, karena kode kontrak tidak dapat diperbaiki dengan mudah setelah deployment (penerapan).
Mitigasi bergantung pada praktik pengkodean yang aman: menggunakan operasi terbatas alih-alih loop tak terbatas, memilih pola "pull-payment" (pengguna menarik pembayaran) daripada mendorong dana ke pengguna ("push-payment"), yang mengisolasi kegagalan transfer, menangani kegagalan panggilan eksternal secara tangguh (misalnya, menggunakan `try/catch` jika sesuai), dan manajemen gas yang cermat.
Kerentanan integer overflow (luapan bilangan bulat) dan underflow (kekurangan bilangan bulat) merupakan ancaman persisten dalam domain keamanan kontrak pintar (smart contract), yang berasal dari keterbatasan fundamental aritmetika bilangan bulat ukuran tetap. Overflow terjadi ketika hasil operasi aritmetika melebihi nilai maksimum untuk tipenya, dan underflow terjadi ketika hasil jatuh di bawah nilai minimum.
Secara historis, dalam versi Solidity sebelum 0.8.0, kesalahan aritmetika ini menyebabkan nilai "melingkar" (wrap around) secara diam-diam. Misalnya, menambahkan 1 ke nilai maksimum uint8 (255) akan menghasilkan 0, dan mengurangi 1 dari 0 akan menghasilkan 255. Perilaku yang dapat diprediksi tetapi tidak diperiksa ini adalah sumber utama eksploitasi, memungkinkan penyerang memanipulasi saldo token (misalnya, mencetak jumlah besar atau menguras dana dengan menyebabkan saldo melingkar), melewati pemeriksaan keamanan kritis, merusak status kontrak, atau menyebabkan penolakan layanan (denial-of-service).
Solidity versi 0.8.0 memperkenalkan peningkatan keamanan krusial: operasi aritmetika standar (+, -, *, /) sekarang melakukan pemeriksaan overflow dan underflow secara default. Jika suatu operasi akan mengakibatkan pelingkaran, transaksi akan dibatalkan (revert) sebagai gantinya, mencegah kerusakan status secara diam-diam.
Namun, risikonya tidak sepenuhnya dihilangkan. Pengembang dapat secara eksplisit melewati pemeriksaan default ini menggunakan blok `unchecked`, seringkali untuk optimasi gas. Kode di dalam blok `unchecked` kembali ke perilaku pelingkaran diam-diam yang berbahaya dari versi pra-0.8.0 dan memerlukan validasi yang sangat hati-hati. Demikian pula, kode assembly EVM tingkat rendah tidak mendapat manfaat dari pemeriksaan Solidity, menuntut manajemen keamanan manual untuk operasi aritmetika. Selain itu, operasi geser (shift operations) (<<, >>) tetap tidak diperiksa bahkan dalam mode default >=0.8.0 dan akan memotong hasil. Konversi tipe (type casting) yang tidak tepat (misalnya, mengonversi uint256 besar ke tipe yang lebih kecil seperti uint8) juga dapat menyebabkan pemotongan nilai, berpotensi menyebabkan perilaku tak terduga dalam perhitungan berikutnya.
Oleh karena itu, meskipun secara signifikan diminimalisir secara default di Solidity modern, integer overflow/underflow tetap menjadi kerentanan yang relevan, terutama dalam kontrak lawas (legacy contracts), kode yang menggunakan blok `unchecked` atau assembly, dan melalui operasi spesifik yang tidak diperiksa atau konversi tipe yang ceroboh.
Penggunaan `tx.origin` untuk logika otorisasi dalam kontrak pintar (smart contracts) Solidity merupakan kerentanan keamanan yang kritis. Hal ini berasal dari kesalahpahaman mendasar tentang perilakunya dibandingkan dengan `msg.sender`. Meskipun `tx.origin` secara konsisten mengidentifikasi EOA (Externally Owned Account / Akun Milik Eksternal) yang memulai transaksi, `msg.sender` mengidentifikasi pemanggil langsung. Menggunakan `tx.origin` untuk pemeriksaan izin gagal memvalidasi entitas yang berinteraksi langsung dengan kontrak.
Celah ini membuka pintu bagi serangan gaya phishing, di mana kontrak perantara yang jahat, yang dipanggil oleh pengguna berhak istimewa, dapat berhasil memanggil fungsi terproteksi pada kontrak target. Pemeriksaan `tx.origin` secara keliru memvalidasi pengguna asli, memungkinkan kontrak jahat untuk mengeksekusi tindakan dengan otoritas pengguna. Konsekuensinya berkisar dari pencurian langsung Ether dan token hingga manipulasi status kontrak yang tidak sah, berpotensi menyebabkan kerugian finansial yang signifikan dan kerusakan yang tidak dapat diperbaiki pada integritas dan reputasi protokol.
Kontrol Akses Tidak Memadai adalah kerentanan kritis dalam kontrak pintar (smart contract) Solidity di mana batasan tentang siapa yang dapat menjalankan fungsi mana hilang atau diimplementasikan secara tidak tepat. Karena Solidity tidak memiliki model izin bawaan, pengembang harus menambahkan pemeriksaan secara manual, sering kali menggunakan pengubah (modifier) seperti onlyOwner atau mengimplementasikan Kontrol Akses Berbasis Peran (RBAC). Kegagalan melakukannya dengan benar menciptakan celah keamanan.
Kerentanan ini biasanya bermanifestasi sebagai fungsi yang tidak terlindungi. Fungsi yang ditujukan untuk operasi administratif atau sensitif - seperti mentransfer kepemilikan kontrak (changeOwner), menarik dana (withdraw), menjeda kontrak, mencetak token (minting token), atau bahkan menghancurkan kontrak (selfdestruct) - mungkin dibiarkan dapat dipanggil oleh akun eksternal mana pun. Hal ini sering terjadi karena hilangnya pengubah kontrol akses atau visibilitas fungsi yang salah (misalnya, fungsi secara default bersifat public jika tidak ditentukan). Fungsi inisialisasi yang terekspos, yang seharusnya hanya berjalan sekali, juga bisa menjadi vektor serangan jika tetap dapat dipanggil setelah deployment, berpotensi memungkinkan penyerang untuk mengatur ulang kepemilikan atau parameter kritis.
Konsekuensinya parah, mulai dari pengguna yang tidak sah mendapatkan hak administratif hingga pencurian dana sepenuhnya yang dikelola oleh kontrak atau penghancuran kontrak itu sendiri yang tidak dapat diubah. Eksploitasi dunia nyata, seperti insiden Parity Wallet dan peretasan LAND Token, menunjukkan potensi merusak dari kontrol akses yang tidak memadai.
Mitigasi melibatkan penerapan pemeriksaan kontrol akses secara ketat ke semua fungsi sensitif, mematuhi Prinsip Hak Istimewa Terkecil (Principle of Least Privilege), menggunakan pola yang sudah mapan seperti Ownable atau RBAC (seringkali melalui pustaka seperti milik OpenZeppelin), dan melakukan pengujian serta audit menyeluruh.
Menghasilkan keacakan (randomness) yang aman di Ethereum Virtual Machine (EVM) merupakan tantangan karena sifat deterministiknya, yang penting untuk konsensus jaringan. Hal ini menciptakan "ilusi entropi" di mana nilai-nilai yang tampaknya acak yang murni berasal dari data on-chain sebenarnya dapat diprediksi.
Pengembang sering menyalahgunakan variabel blok yang tersedia seperti block.timestamp, blockhash, dan prevrandao pasca-Merge (diakses melalui block.difficulty) sebagai sumber pseudo-randomness (keacakan semu). Variabel-variabel ini tidak aman karena dapat diprediksi atau dipengaruhi.
Penambang (dalam Proof-of-Work) atau validator (dalam Proof-of-Stake) dapat memanipulasi nilai-nilai ini sampai batas tertentu untuk mendapatkan keuntungan yang tidak adil, seringkali sebagai bagian dari strategi MEV (Maximal Extractable Value). Yang terpenting, bahkan pengguna biasa atau kontrak penyerang seringkali dapat memprediksi hasil jika logika keacakan hanya bergantung pada input yang diketahui sebelum atau selama eksekusi transaksi, memungkinkan eksploitasi seperti front-running. Prediktabilitas ini merusak keadilan aplikasi seperti lotere, game, dan pencetakan NFT.
Kolisi Hash melalui `abi.encodePacked` dengan Beberapa Tipe Dinamis tidak muncul dari kelemahan fungsi hash Keccak-256 yang mendasarinya, tetapi dari cara data dikodekan sebelum di-hash, khususnya saat menggunakan fungsi `abi.encodePacked` dari Solidity. Tidak seperti `abi.encode` standar, yang menambahkan padding pada argumen hingga 32 byte dan menyertakan awalan panjang (length prefix) untuk tipe dinamis, `abi.encodePacked` membuat pengkodean yang ringkas dan non-standar dengan menggabungkan argumen menggunakan byte minimum yang diperlukan, menghilangkan padding untuk tipe statis kecil dan, yang terpenting, menghilangkan informasi panjang untuk tipe dinamis seperti `string`, `bytes`, atau array dinamis.
Masalah inti terjadi ketika `abi.encodePacked` digunakan dengan dua atau lebih argumen tipe dinamis yang berdekatan. Karena panjang setiap argumen dinamis tidak dikodekan, batas di antara keduanya menjadi ambigu dalam string byte yang dihasilkan. Ambiguitas ini memungkinkan, seringkali dengan mudah, untuk membuat set input logis yang berbeda yang menghasilkan urutan byte terpaket yang sama persis. Misalnya, `abi.encodePacked("a", "bc")` menghasilkan output byte yang sama dengan `abi.encodePacked("ab", "c")`.
Ketika output byte yang identik ini kemudian di-hash (misalnya, `keccak256(abi.encodePacked(...))`), hasilnya adalah nilai hash yang sama, sebuah kolisi hash yang disebabkan oleh pengkodean.
Kerentanan kolisi pengkodean ini dapat dieksploitasi dalam beberapa cara jika hash yang dihasilkan digunakan dalam konteks yang sensitif terhadap keamanan:
Bypass Verifikasi Tanda Tangan (Signature Verification Bypass): Penyerang dapat mengambil tanda tangan valid yang dibuat untuk satu set parameter dan menggunakannya kembali dengan set parameter yang berbeda dan berbahaya yang menghasilkan hash yang bertabrakan. Verifikasi tanda tangan kontrak (`ecrecover`) akan berhasil, memberikan eksekusi yang tidak sah.
Korupsi State melalui Kolisi Kunci Mapping (State Corruption via Mapping Key Collisions): Jika hash yang rentan terhadap kolisi digunakan sebagai kunci dalam mapping (`mapping(bytes32 => ...)`), penyerang dapat membuat input untuk menghasilkan kunci yang bertabrakan dengan kunci pengguna yang sah, berpotensi menimpa data mereka, melewati kontrol akses, atau menyebabkan penolakan layanan (Denial of Service).
Masalah Otentikasi Pesan (Message Authentication Issues): Kerentanan ini merusak pemeriksaan yang mengandalkan hash untuk memastikan integritas data, karena pesan logis yang berbeda dapat tampak identik setelah di-hash.
Konsekuensi dari eksploitasi yang berhasil bisa parah, termasuk Akses Tidak Sah ke fungsi atau data, Pencurian Dana langsung (Fund Theft), Korupsi State Kritis, dan Penolakan Layanan (Denial of Service - DoS).
Kerentanan kehilangan presisi berasal dari ketergantungan pada aritmetika integer dan kurangnya dukungan asli untuk angka floating-point. Desain ini memprioritaskan eksekusi deterministik tetapi mengharuskan pengembang untuk mengelola nilai pecahan secara manual, sehingga menciptakan peluang untuk kesalahan.
Masalah intinya adalah pemotongan pembagian integer: Solidity membuang sisa bagi dan membulatkan hasil pembagian ke arah nol. Perilaku yang dapat diprediksi ini dapat dieksploitasi, seringkali melalui pola seperti:
Pembagian Sebelum Perkalian: Menghitung (a / b) * c alih-alih (a * c) / b akan memotong hasil antara a / b, memperbesar kehilangan presisi.
Pembulatan ke Bawah Menjadi Nol: Jika pembilang A lebih kecil dari penyebut B (dan keduanya positif), A / B selalu menghasilkan 0. Ini berisiko untuk perhitungan yang melibatkan biaya, hadiah, atau konversi token dalam jumlah kecil.
Penyerang mengeksploitasi properti matematika ini untuk memanipulasi logika kontrak demi keuntungan finansial. Strategi umum meliputi:
Manipulasi Status/Harga: Memicu kesalahan pembulatan untuk mendistorsi nilai protokol penting seperti nilai tukar, cadangan pool, harga saham vault, atau rasio agunan, yang kemudian dapat dieksploitasi dalam transaksi berikutnya.
Menargetkan Kasus Tepi (Edge Cases): Menggunakan transaksi dengan input yang sangat kecil atau input yang dirancang untuk berinteraksi dengan nilai internal yang besar untuk memaksimalkan dampak pemotongan, seringkali menyebabkan hasil perhitungan menjadi nol.
Serangan kehilangan presisi yang berhasil dapat menyebabkan konsekuensi negatif yang signifikan:
Biaya yang Dikurangi: Penyerang membayar biaya/ongkos yang lebih rendah atau nol.
Keuntungan yang Digembungkan: Penyerang secara tidak sah menerima lebih banyak token, saham, atau hadiah.
Peluang Arbitrase: Menciptakan perbedaan harga buatan dalam protokol untuk dieksploitasi oleh penyerang.
Menghindari Mekanisme Risiko: Melewati likuidasi atau pemeriksaan keamanan lainnya karena perhitungan yang tidak akurat.
Pengurasan Dana Bertahap: Menyedot nilai melalui transaksi berulang yang mengeksploitasi kesalahan pembulatan kecil ("serangan 1 wei").
Mitigasi melibatkan penanganan aritmetika yang cermat, seperti melakukan perkalian sebelum pembagian, menggunakan penskalaan numerik (mensimulasikan matematika titik-tetap), menggunakan pustaka matematika khusus, dan menerapkan logika pembulatan yang sesuai. Pemeriksaan overflow standar (seperti SafeMath atau Solidity >=0.8) tidak mencegah kehilangan presisi akibat pembagian.
Kerentanan ini terjadi ketika sebuah kontrak pintar (smart contract) secara tidak tepat menggunakan msg.value di dalam sebuah loop (perulangan). Masalah intinya berasal dari fakta bahwa msg.value tetap konstan selama seluruh konteks eksekusi sebuah transaksi. Jika sebuah loop beriterasi berkali-kali, melakukan pemeriksaan atau tindakan berdasarkan msg.value awal ini di setiap iterasi tanpa melacak nilai kumulatif yang diproses atau dibelanjakan secara benar di seluruh iterasi tersebut, ini menciptakan peluang eksploitasi.
Seorang penyerang dapat mengeksploitasi ini dengan mengirimkan sejumlah Ether tertentu untuk memicu fungsi yang rentan. Di dalam loop, pemeriksaan seperti require(msg.value >= amount_per_item) mungkin lolos berulang kali, atau pembaruan status mungkin secara keliru menggunakan msg.value awal penuh berkali-kali. Ini terjadi karena logika kontrak gagal memperhitungkan nilai yang secara efektif 'dibelanjakan' atau dialokasikan dalam iterasi sebelumnya dari loop yang sama.
Celah ini memungkinkan penyerang untuk memicu tindakan (seperti transfer Ether atau kredit saldo internal) yang nilai totalnya secara signifikan melebihi Ether yang sebenarnya mereka kirimkan dengan transaksi tersebut.
ecrecover adalah precompile EVM yang penting yang memungkinkan smart contract untuk memulihkan alamat penanda tangan dari hash pesan dan tanda tangan ECDSA (v, r, s). Ini mengaktifkan fungsionalitas penting seperti memverifikasi pesan yang ditandatangani di luar rantai (off-chain) untuk meta-transaksi atau fungsi izin (permit functions). Namun, penggunaannya secara langsung menghadirkan risiko keamanan yang signifikan dan sering diremehkan jika tidak ditangani dengan hati-hati.
Kerentanan Pengembalian Alamat Nol: Masalah kritis berasal dari penanganan kesalahan unik `ecrecover`. Ketika diberikan tanda tangan yang tidak valid atau secara matematis tidak mungkin, ia tidak mengembalikan (revert) transaksi. Sebaliknya, ia gagal secara diam-diam dan mengembalikan alamat nol (`address(0)`). Kontrak yang memanggil `ecrecover` tetapi tidak memiliki pemeriksaan alamat nol sangat rentan. Penyerang dapat dengan sengaja mengirimkan data tanda tangan yang tidak valid, menyebabkan `ecrecover` mengembalikan `address(0)`. Jika output ini tidak diperiksa dan ditolak secara eksplisit, kontrak mungkin melanjutkan secara keliru, memperlakukan `address(0)` sebagai penanda tangan yang sah. Hal ini dapat menyebabkan konsekuensi parah seperti perubahan status yang tidak sah, emisi event yang salah, atau pemberian izin, terutama jika alamat nol memiliki hak istimewa atau status berarti dalam logika spesifik kontrak. Kode yang kuat harus selalu memvalidasi `recoveredAddress != address(0)` segera setelah pemanggilan `ecrecover`.
Kerentanan Kelenturan Tanda Tangan (Signature Malleability): Risiko besar kedua muncul dari properti inheren dari algoritma ECDSA itu sendiri: kelenturan tanda tangan. Untuk setiap pesan dan kunci pribadi yang diberikan, dapat ada beberapa representasi tanda tangan yang berbeda namun valid secara kriptografis (secara spesifik, tanda tangan yang menggunakan komponen `s` seringkali dapat diubah menjadi tanda tangan yang valid menggunakan `n-s`, di mana `n` adalah urutan kurva). Ini menjadi kerentanan jika kontrak secara keliru mengasumsikan bahwa tanda tangan untuk suatu pesan bersifat unik. Penyerang dapat mengeksploitasi ini dengan melewati pemeriksaan keunikan. Misalnya, jika kontrak menggunakan hash dari tanda tangan itu sendiri sebagai nonce untuk mencegah pemutaran ulang (replay) (pola yang cacat), penyerang dapat mengambil tanda tangan yang valid, menghitung padanannya yang lentur, dan mengirimkannya untuk mengeksekusi tindakan lagi, karena hash tanda tangan akan berbeda. Ini juga dapat menyebabkan perilaku tak terduga atau pemutaran ulang dalam sistem yang mengharapkan bentuk tanda tangan tertentu, jika sistem eksternal atau bagian dari logika kontrak tidak dirancang untuk menangani kedua bentuk tanda tangan yang valid. Mitigasi yang efektif melibatkan penegakan kanonisasi tanda tangan – sebuah pemeriksaan yang diimplementasikan secara kuat di pustaka standar seperti ECDSA OpenZeppelin, yang sebaiknya lebih diutamakan daripada penggunaan `ecrecover` secara langsung.
Serangan Ulang Lintas Rantai (Cross-Chain Replay Attack - CCRA): Transaksi yang dieksekusi secara sah di satu rantai EVM ditangkap dan berhasil dikirim ulang di rantai EVM yang berbeda. Ini mengeksploitasi kesamaan dalam format transaksi dan tanda tangan di seluruh rantai, terutama ketika transaksi tidak memiliki pengidentifikasi rantai unik (Chain ID). Hard fork Ethereum/Ethereum Classic adalah contoh klasik di mana risiko ini terwujud. EIP-155 diperkenalkan untuk memitigasi hal ini dengan menyematkan Chain ID ke dalam tanda tangan transaksi standar, membuatnya spesifik untuk rantai tersebut. Namun, kontrak pintar (smart contract) yang menggunakan verifikasi tanda tangan khusus juga harus secara eksplisit memeriksa Chain ID. Eksploitasi Optimism senilai $20 juta terhadap Wintermute diakibatkan oleh tidak adanya pemeriksaan Chain ID semacam itu dalam kontrak yang diterapkan lintas rantai (cross-chain).
Pengulangan Tingkat Kontrak Pintar (Rantai yang Sama): Pesan atau transaksi yang ditandatangani diulang (replayed) terhadap kontrak pintar yang sama, atau berpotensi terhadap kontrak lain di rantai yang sama. Ini biasanya mengeksploitasi kerentanan dalam logika kontrak itu sendiri, terutama dalam skema verifikasi tanda tangan khusus yang digunakan untuk fitur seperti meta-transaksi (meta-transactions) atau fungsi izin (permit) ERC-20. Celah yang paling umum adalah tidak adanya atau implementasi nonce tingkat aplikasi yang tidak tepat. Nonce («nomor yang digunakan sekali») adalah penghitung unik yang terkait dengan penanda tangan yang harus disertakan dalam intisari (digest) pesan yang ditandatangani dan dilacak secara on-chain oleh kontrak untuk memastikan setiap tanda tangan spesifik hanya mengotorisasi satu tindakan.
Dukungan Solidity untuk pewarisan berganda memungkinkan sebuah kontrak untuk mewarisi fitur dari beberapa kontrak induk secara bersamaan. Meskipun kuat untuk penggunaan kembali kode, ini menimbulkan potensi ambiguitas, yang dikenal sebagai "Masalah Berlian" (Diamond Problem): jika dua atau lebih kontrak dasar mendefinisikan fungsi dengan nama dan parameter yang sama.
Untuk mengatasi ini, Solidity menggunakan algoritma linearisasi C3 untuk menetapkan Urutan Resolusi Metode (Method Resolution Order, MRO) tunggal dan deterministik untuk setiap kontrak. MRO ini menentukan urutan pasti di mana kontrak dasar diperiksa saat menyelesaikan panggilan fungsi.
Kerentanan muncul secara langsung dari bagaimana MRO ini ditentukan. Faktor krusialnya adalah urutan di mana pengembang mencantumkan kontrak dasar dalam pernyataan `is`. Solidity mengharuskan pencantuman kontrak dari "paling mirip dasar" hingga "paling turunan". Urutan yang ditentukan ini secara langsung memengaruhi MRO akhir yang dihasilkan oleh algoritma C3.
Kerentanan terjadi ketika pengembang memberikan urutan pewarisan yang tidak sesuai dengan hierarki atau prioritas logis yang dimaksud. Jika kontrak yang lebih umum dicantumkan setelah kontrak yang lebih spesifik, atau urutan tersebut menyebabkan MRO memprioritaskan implementasi fungsi yang tidak diinginkan, kontrak dapat berperilaku tidak terduga. Misalnya, panggilan mungkin diselesaikan ke fungsi dasar yang tidak memiliki pemeriksaan keamanan penting atau logika yang diperbarui yang diimplementasikan dalam penimpaan kontrak turunan yang dimaksudkan tetapi salah urutan.
Konsekuensi dari mengeksekusi fungsi yang salah karena urutan pewarisan yang salah termasuk melewati kontrol akses, mengeksekusi logika bisnis yang usang atau salah, kerusakan status, dan potensi kerugian finansial. Pada dasarnya, alur eksekusi aktual kontrak menyimpang dari desain pengembang, merusak keamanan dan fungsionalitas.
Nilai Maksimal yang Dapat Diekstraksi (Maximal Extractable Value - MEV) mewakili keuntungan yang dapat ditangkap oleh produsen blok dan pencari khusus (searchers) dengan memanipulasi penyertaan dan urutan transaksi dalam sebuah blok, di luar hadiah blok standar dan biaya gas. Awalnya disebut "Nilai yang Dapat Diekstraksi Penambang" (Miner Extractable Value), namanya berkembang menjadi "Maksimal" untuk mencerminkan keserakahan akan hadiah.
MEV muncul karena transaksi yang tertunda sering kali berada di area tunggu publik yang disebut mempool, yang dapat dilihat oleh siapa saja. Produsen blok memiliki wewenang untuk memutuskan urutan akhir transaksi dalam sebuah blok. Bot otomatis, yang dijalankan oleh "pencari" (searchers), terus-menerus memantau mempool, mensimulasikan hasil potensial, dan mengeksploitasi peluang yang menguntungkan dengan menyusun urutan transaksi secara strategis, sering kali menggunakan penawaran gas (Lelang Gas Prioritas - PGA) untuk memastikan penempatan preferensial.
Strategi MEV yang umum, sering dianggap sebagai serangan, meliputi:
Front-Running: Menempatkan transaksi penyerang sebelum transaksi korban (misalnya, perdagangan DEX besar) untuk mendapatkan keuntungan dari dampak harga yang diantisipasi.
Serangan Sandwich (Sandwich Attacks): Kombinasi front-running dan back-running (mengikuti) perdagangan DEX korban untuk menangkap perbedaan harga (slippage) yang disebabkan oleh manipulasi.
Likuiditas Tepat Waktu (JIT Liquidity): Menambah dan menghapus likuiditas untuk sementara waktu di sekitar pertukaran (swap) besar pada DEX likuiditas terkonsentrasi untuk menangkap biaya.
Manipulasi Oracle (Oracle Manipulation): Mengeksploitasi pembaruan atau ketidakakuratan oracle harga untuk keuntungan, sering kali berdampak pada protokol peminjaman.
Jenis lainnya termasuk sniping NFT (NFT sniping) dan serangan debu (dust attacks).
Konsekuensi bagi pengguna meliputi peningkatan biaya transaksi karena perang gas (gas wars), harga eksekusi yang lebih buruk (slippage) pada perdagangan, kerugian tidak permanen (impermanent loss) yang diperburuk bagi penyedia likuiditas, dan likuidasi yang dipicu secara tidak adil.
Strategi mitigasi bertujuan untuk mengurangi dampak negatif MEV. Mengirim transaksi melalui mempool pribadi atau relay (seperti Flashbots Protect atau MEV Blocker) menyembunyikannya dari pandangan publik. Desain tingkat aplikasi seperti skema Commit-Reveal (Komitmen-Ungkap) mengaburkan detail transaksi hingga urutannya ditetapkan, sementara menggunakan Harga Rata-Rata Tertimbang Waktu (TWAP) untuk oracle dapat mengurangi risiko manipulasi.