Latar Belakang
Pada Mei 2026, proyek ShapeShift FOX Colony yang dikerahkan di Arbitrum mengalami serangan terhadap kontrak EtherRouterCreate3. Penyerang memanfaatkan kemampuan 'self-calling' dalam mekanisme transaksi meta kontrak, bersama dengan logika otorisasi otomatis DSAuth terhadap address(this), untuk melewati modifikasi auth dan mengganti komponen inti routing kontrak, resolver, dengan versi jahat. Melalui delegatecall, semua aset ERC20 yang dimiliki kontrak berhasil dikuras. Esensi serangan ini adalah akibat dari 'konflik semantik antara transaksi meta dan mode otorisasi self-calling internal' yang menyebabkan pelanggaran hak akses yang total.

Ikhtisar serangan

Akar penyebab kerentanan
Self-call sembarang dari executeMetaTransaction: address(this).call(callData) tidak memfilter selector sensitif
Kontrak EtherRouter itu sendiri adalah arsitektur proxy yang dapat ditingkatkan berdasarkan resolver: untuk selector fungsi yang tidak diketahui, fallback() memanggil resolver.lookup(msg.sig) untuk menemukan alamat implementasi, lalu mengeksekusi melalui delegatecall. Fungsi meta-transaksi (executeMetaTransaction) dirouting oleh resolver lama 0x7490022b0e44aa65c030ac0d6728382a29458fc5 ke kontrak implementasi 0x4e7f1e1e263678590007e89b7e129686ba7758d4. Kontrak implementasi ini tidak open-source, berikut berdasarkan hasil dekompilasi:


Esensi masalah: desain executeMetaTransaction bertujuan untuk memungkinkan pengguna melakukan beberapa operasi non-sensitif melalui tanda tangan, tetapi tidak melakukan filter pada functionSignature. Penyerang dapat menggunakan tanda tangan validnya sendiri, membuat kontrak memanggil setResolver(alamat jahat).
Otorisasi otomatis DSAuth.isAuthorized: src == address(this) dilepaskan
EtherRouter.setResolver(address) dilindungi oleh modifier auth, seharusnya hanya boleh dipanggil oleh pemilik atau otoritas:

Namun, ada logika otorisasi otomatis dalam DSAuth.isAuthorized(address src, bytes4 sig):

Ketika executeMetaTransaction dipicu melalui address(this).call(setResolver(...)), msg.sender yang terlihat dalam setResolver adalah kontrak itu sendiri 0x5c59..., sehingga dilepaskan otomatis oleh DSAuth.
Dari sudut pandang sendiri, kedua desain ini tidak dianggap sebagai kerentanan yang jelas—otorisasi self-call cukup umum dalam banyak model proxy, mekanisme meta-transaksi itu sendiri juga masuk akal. Tetapi ketika kedua logika ini ada bersamaan, konflik semantik muncul: kemampuan 'self-call sembarang' yang diberikan oleh meta-transaksi tepat bertabrakan dengan logika 'self-call dipercaya' dari DSAuth, ketika digabungkan menjadi rantai bypass otorisasi yang lengkap.
Pengalihan delegatecall di EtherRouter.fallback(): Kontrol penuh diserahkan setelah Resolver dibajak

Setelah resolver diganti, penyerang hanya perlu memanggil selector fungsi sembarang yang tidak ada di EtherRouter, fallback() akan tanpa syarat mendelegasikan ke implementasi jahat yang dikendalikan penyerang.
Resolver jahat dan implementasi Drain: pendaftaran pemetaan fungsi tanpa izin + pengosongan aset address(this)
Penyerang telah men-deploy dua kontrak sebelumnya:
Resolver jahat
0x4e321af09012e15a67756522187c05b108b7ee0a (tidak open-source, dekompilasi):

Implementasi Drain jahat
0x0b971e0a8ecc7d5b2465c903cf75aeaedbfc39e2 (tidak open-source, dekompilasi):

Rumus keuntungan serangan

Alur serangan
Proses serangan diselesaikan dalam satu transaksi, semua logika dieksekusi di constructor kontrak serangan sementara 0x835a701fd76b96a76ee84de037d41f059ee29f5c.
Tahap pertama: Deploy infrastruktur jahat
EOA penyerang 0xeed236afb6967f74099a0a6bf078bc6b865fbf28 memulai transaksi, membuat kontrak serangan sementara 0x835a701fd76b96a76ee84de037d41f059ee29f5c.
Kontrak serangan memanggil resolver jahat 0x4e321af09012e15a67756522187c05b108b7ee0a dengan set(bytes4,address), memetakan selector drain(address,address) 0x837971e4 ke implementasi drain jahat 0x0b971e0a8ecc7d5b2465c903cf75aeaedbfc39e2.
Tahap kedua: Membajak Resolver melalui self-call meta-transaksi
Kontrak serangan memanggil kontrak korban 0x5c59d0ec51729e40c413903be6a4612f4e2452da dengan executeMetaTransaction(). Karena fungsi ini tidak ada dalam ABI EtherRouter itu sendiri, pemanggilan masuk ke fallback(), dirouting oleh resolver lama ke implementasi meta-transaksi 0x4e7f1e....
executeMetaTransaction memverifikasi tanda tangan melalui ecrecover, mengembalikan EOA penyerang, verifikasi tanda tangan berhasil (penyerang menggunakan tanda tangan validnya sendiri, bukan tanda tangan palsu).
executeMetaTransaction membangun calldata self-call setResolver(0x4e321af...) dan mengeksekusi address(this).call(callData). Saat itu konteksnya adalah kontrak korban, sehingga msg.sender == 0x5c59.... DSAuth.isAuthorized() mengembalikan true karena src == address(this), resolver berhasil diganti.
Tahap ketiga: Kosongkan aset melalui Resolver yang dibajak
Kontrak serangan memanggil kontrak korban dengan drain(USDC, 0xeed236...). Fungsi ini tidak ada dalam ABI asli EtherRouter, masuk ke fallback(). Resolver yang dibajak mengembalikan implementasi drain jahat 0x0b971e0..., kontrak korban melakukan delegatecall ke sana. Kode jahat menanyakan USDC.balanceOf(0x5c59...) yang mendapatkan 132704591501 (yaitu 132,704.591501 USDC), lalu memanggil USDC.transfer() langsung ke EOA penyerang.
Kontrak serangan memanggil drain(0xf929..., 0x835a701f...), mengikuti jalur yang sama untuk memindahkan token tengah yang dicuri 841086343608217839604694 unit ke kontrak serangan.
Kontrak serangan melalui Router 0x4752ba5dbc23f44d87826276bf6fd6b1c372ad24 menukar token tengah yang dicuri di Pair 0x5f6ce0ca... menjadi 1.949506469643782660 WETH, WETH langsung masuk ke EOA penyerang.
Tutup profit

Pelacakan dana
Analisis terhadap EOA penyerang 0xeed236afb6967f74099a0a6bf078bc6b865fbf28 menggunakan SlowMist MistTrack:
Jejak utama:
Relay.link — $4,368.08, agregator DEX untuk pertukaran aset.
LI.FI — $137,073.66, agregator lintas rantai/DEX.
Dana yang dicuri oleh penyerang masuk ke Spark.fi Saving, SlowMist MistTrack akan terus memantau pergerakan dana dari alamat terkait.

Ringkasan
Pelajaran inti dari serangan ini adalah: ketika kontrak memiliki dua semantik 'self-call meta-transaksi sembarang' dan 'self-call otorisasi otomatis', keduanya akan membentuk rantai bypass otorisasi yang lengkap—ini bukan kerentanan kode titik tunggal, tetapi hasil dari konflik semantik antar komponen. Pengembang kontrak harus jelas dalam membagi batas fungsi sensitif saat merancang mekanisme meta-transaksi atau relay, setidaknya dalam executeMetaTransaction memelihara daftar selector yang dilarang untuk dipanggil, dan berhati-hati dalam menggunakan otorisasi self-call yang tanpa syarat dengan src == address(this). Tim keamanan SlowMist merekomendasikan proyek untuk melakukan audit keamanan eksternal yang lengkap sebelum deployment.
Catatan: Artikel ini adalah analisis keamanan teknis, hanya untuk referensi pembelajaran, tidak merupakan saran investasi. Semua data on-chain berasal dari informasi publik.

