หน้าแรก / คลัง
อ้างอิง

คลังช่องโหว่ของสมาร์ตคอนแทร็กต์

อธิบายช่องโหว่แต่ละประเภท พร้อมตัวอย่างที่มีช่องโหว่และเวอร์ชันที่แก้ไขแล้ว

Reentrancy

การเรียกภายนอกที่ทำก่อนอัปเดตสถานะทำให้ผู้โจมตีสามารถเข้าฟังก์ชันซ้ำก่อนที่ยอดจะถูกหักลด ปฏิบัติตาม checks-effects-interactions และใช้ reentrancy guard

// vulnerable
function withdraw(uint a) public {
  require(bal[msg.sender] >= a);
  (bool ok,) = msg.sender.call{value:a}("");
  bal[msg.sender] -= a; // too late
}
// fixed
function withdraw(uint a) public nonReentrant {
  require(bal[msg.sender] >= a);
  bal[msg.sender] -= a;                 // effects first
  (bool ok,) = msg.sender.call{value:a}("");
  require(ok);
}

การยืนยันตัวตนด้วย tx.origin

การใช้ tx.origin เพื่ออนุญาตทำให้สัญญาตัวกลางสามารถทำการแทนผู้ใช้ได้ ให้ใช้ msg.sender

การจัดการออราเคิล / ราคา

การอ่านราคาสปอตจากพูลเดียวทำให้ถูกจัดการได้ด้วยการสวอปขนาดใหญ่ ซึ่งมักได้ทุนจาก flash loan ควรใช้ราคาเฉลี่ยถ่วงน้ำหนักตามเวลา (TWAP) หรือออราเคิลแบบรวม

ขาดการควบคุมการเข้าถึง

ฟังก์ชันที่อ่อนไหวโดยไม่มี modifier จำกัดสามารถถูกเรียกได้โดยใครก็ตาม ป้องกันฟังก์ชันที่มีสิทธิพิเศษด้วย onlyOwner หรือการตรวจสอบบทบาท

การเรียกภายนอกที่ไม่ตรวจสอบ

การเพิกเฉยต่อค่าที่คืนจากการเรียกระดับต่ำทำให้สัญญาทำงานต่อหลังการโอนที่ล้มเหลว ตรวจสอบค่าบูลีนที่คืนเสมอ

ข้อบกพร่องของตรรกะทางธุรกิจ

การเปรียบเทียบที่กลับด้านหรือการคำนวณส่วนแบ่งที่ผิดทำลาย invariant ข้อบกพร่องเหล่านี้เฉพาะกับสัญญา หลุดรอดจากตัวตรวจจับทั่วไป และมักแพงที่สุด อธิบายพฤติกรรมที่ตั้งใจไว้แล้วเทียบกับโค้ด

อยากฝึกใช้ประโยชน์อย่างปลอดภัย? ดู เรียนรู้ พร้อมสแกนสัญญาของคุณแล้ว? เปิดสแกนเนอร์

▶ เปิดสแกนเนอร์