Smart Contract Audits: What Auditors Check—and What an Audit Does Not Guarantee

การตรวจสอบ smart contract คือการทบทวนโค้ดและสถาปัตยกรรมโดยอิสระภายในขอบเขตที่กำหนด มีวัตถุประสงค์เพื่อค้นหาช่องโหว่ ข้อผิดพลาดในการนำไปใช้ และความไม่ตรงกันระหว่างพฤติกรรมที่ตั้งใจไว้กับพฤติกรรมจริง

การตรวจสอบช่วยลดความไม่แน่นอนได้ แต่ไม่ได้ทำให้สัญญาปราศจากความเสี่ยง แนวทางความปลอดภัยอย่างเป็นทางการของ Ethereum อธิบายว่าการตรวจสอบเป็นการทบทวนเพิ่มเติม ไม่ใช่วิธีวิเศษที่ตรวจพบข้อผิดพลาดทุกอย่าง

บทความนี้มีวัตถุประสงค์เพื่อการศึกษาเท่านั้น รายงานการตรวจสอบไม่รับประกันความปลอดภัย การกู้เงินคืน หรือผลตอบแทน

เริ่มจากขอบเขต

รายงานที่มีประโยชน์จะระบุอย่างชัดเจนว่าตรวจสอบอะไรบ้าง:

  • repository และแฮช commit;
  • ไฟล์และสัญญา;
  • เวอร์ชัน compiler และการตั้งค่า build;
  • การพึ่งพา;
  • สถาปัตยกรรมและบทบาทที่มีสิทธิ์พิเศษ;
  • branch หรือ release;
  • ข้อยกเว้น ข้อจำกัด และข้อสันนิษฐาน;
  • วันที่ตรวจสอบ

เรื่องนี้สำคัญเพราะรายงานการตรวจสอบจริงอาจครอบคลุมเวอร์ชันเก่า ระบบที่ติดตั้งใช้งานคนละชุด หรือเพียงส่วนหนึ่งของระบบที่ใหญ่กว่า

สิ่งที่ผู้ตรวจสอบมักตรวจสอบ

1. พฤติกรรมที่ตั้งใจไว้และเงื่อนไขคงที่

ผู้ตรวจสอบเปรียบเทียบโค้ดกับข้อกำหนด:

  • ใครเรียกใช้แต่ละฟังก์ชันได้;
  • วิธีคำนวณจำนวนและค่าธรรมเนียม;
  • การเปลี่ยนสถานะเกิดขึ้นเมื่อใด;
  • คุณสมบัติใดต้องเป็นจริงเสมอ;
  • วิธีจัดการกรณีขอบเขตและความล้มเหลว

หากข้อกำหนดละเว้นเงื่อนไขสำคัญ แม้โค้ดจะถูกต้องในทางเทคนิคก็ยังอาจสร้างรูปแบบที่ไม่ปลอดภัยหรือไม่ตรงความต้องการ

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

ผู้ตรวจสอบจะตรวจสอบบทบาท owner, admin, operator และบทบาทที่มีสิทธิ์พิเศษอื่น ๆ รวมถึงอำนาจในการ:

  • มอบหรือเพิกถอนสิทธิ์;
  • หยุดระบบชั่วคราว;
  • เปลี่ยนค่าธรรมเนียมและขีดจำกัด;
  • สร้างโทเคน;
  • ถอนสินทรัพย์;
  • อัปเกรด implementation

ยังพิจารณาด้วยว่าคีย์เดียวสามารถเปลี่ยนแปลงเรื่องสำคัญได้หรือไม่ และมีการควบคุมอย่าง multisig หรือ timelock อยู่ในการออกแบบหรือไม่

3. การเรียกภายนอกและการเรียกซ้ำแบบ reentrancy

ระหว่างการดำเนินการ สัญญาอาจส่งต่อการควบคุมให้อีกสัญญาหนึ่ง ซึ่งอาจเปิดทางให้เกิด reentrancy เมื่อสัญญาภายนอกเรียกกลับก่อนการเปลี่ยนสถานะเดิมจะเสร็จสมบูรณ์ คำแนะนำอย่างเป็นทางการของ Solidity ระบุให้จัดลำดับการตรวจสอบ ผลต่อสถานะ และการโต้ตอบภายนอกอย่างระมัดระวังเมื่อเหมาะสม

4. การคำนวณและหน่วย

ผู้ตรวจสอบค้นหา:

  • การปัดเศษและการสูญเสียความแม่นยำ;
  • จำนวนทศนิยมของโทเคนไม่ตรงกัน;
  • ลำดับการดำเนินการไม่ถูกต้อง;
  • ค่าขอบเขต;
  • การหารด้วยศูนย์;
  • unsafe unchecked arithmetic;
  • ความคลาดเคลื่อนระหว่างหน่วยภายในกับหน่วยที่แสดง

5. การปฏิเสธการให้บริการและค่า gas

ลูปที่ไม่จำกัด อาร์เรย์ที่ขยายขึ้น การเรียกใช้ภายนอกที่ล้มเหลว หรือการดำเนินการที่มีต้นทุนสูงอาจทำให้ฟังก์ชันใช้งานจริงไม่ได้ ผู้ตรวจสอบจะทดสอบว่าการออกแบบยังใช้งานได้เมื่อข้อมูลเพิ่มขึ้นและเมื่อรับอินพุตผิดปกติหรือไม่

6. Proxy และการอัปเกรด

สำหรับระบบที่อัปเกรดได้ การตรวจสอบควรครอบคลุม:

  • สัญญาพร็อกซีและ implementation;
  • สิทธิ์ upgrader หรือ admin;
  • การเริ่มต้นระบบ;
  • ความเข้ากันได้ของโครงสร้าง storage;
  • ช่องทางอัปเกรดโดยไม่ได้รับอนุญาต;
  • ผลกระทบจากการเปลี่ยนตรรกะหลังการตรวจสอบ

Proxy สามารถคงที่อยู่ที่ผู้ใช้เห็นไว้เหมือนเดิมขณะมอบหมายการทำงานให้ตรรกะใหม่ ดังนั้นคำกล่าวว่า «สัญญาเปลี่ยนแปลงไม่ได้» ต้องตรวจสอบเทียบกับสถาปัตยกรรมจริง

7. การเชื่อมต่อระบบ

สัญญาอาจพึ่งพาโทเคน Oracle ราคา สะพาน DEX ลายเซ็น หรือสัญญาอื่น ผู้ตรวจสอบจะพิจารณาสมมติฐานเกี่ยวกับส่วนพึ่งพาเหล่านี้ ข้อมูลที่ล้าสมัย พฤติกรรมโทเคนที่ผิดปกติ และรูปแบบความล้มเหลวภายนอก

8. เหตุการณ์และการติดตาม

ผู้ตรวจสอบอาจตรวจสอบว่า event แสดงการดำเนินการสำคัญได้ถูกต้องหรือไม่ เช่น การเปลี่ยนบทบาท การอัปเกรด การหยุดชั่วคราว และการโอน event ช่วยในการเฝ้าติดตาม แต่ไม่ทดแทนการตรวจสอบสถานะ

วิธีที่ใช้ในการตรวจสอบ

โดยทั่วไปการทบทวนจะรวม:

  • การวิเคราะห์โค้ดและสถาปัตยกรรมด้วยตนเอง;
  • การทดสอบหน่วยและการผสานรวม;
  • การวิเคราะห์แบบ static และ dynamic;
  • การทดสอบ fuzzing ด้วยอินพุตที่สร้างขึ้น;
  • การทดสอบตามคุณสมบัติ;
  • การตรวจสอบช่องโหว่ประเภทที่รู้จัก;
  • การตรวจสอบ build และการติดตั้งใช้งาน;
  • บางครั้งใช้การตรวจสอบอย่างเป็นทางการกับคุณสมบัติที่เลือก

ไม่มีวิธีเดียวที่ครอบคลุมทุกอย่าง การตรวจสอบอย่างเป็นทางการพิสูจน์ได้ว่าโค้ดเป็นไปตามข้อกำหนดเชิงรูปแบบ แต่ไม่สามารถพิสูจน์คุณสมบัติที่ข้อกำหนดไม่ได้ระบุ

ผู้ใช้ควรอ่านรายงานการตรวจสอบอย่างไร

1. ตรวจสอบให้ตรงกับเวอร์ชันที่ได้รับการทบทวน

ค้นหาแฮช commit และตรวจสอบว่า:

  • implementation ปัจจุบันสร้างจากโค้ดนั้นหรือไม่;
  • มีการอัปเกรดหลังวันที่ในรายงานหรือไม่;
  • เชนและที่อยู่ที่ติดตั้งใช้งานตรงกันหรือไม่;
  • การพึ่งพาที่สำคัญอยู่ในขอบเขตหรือไม่

หากยืนยันเรื่องนี้ไม่ได้ รายงานจะให้หลักฐานเกี่ยวกับระบบที่ใช้งานจริงได้อย่างจำกัด

2. อ่านข้อค้นพบ ไม่ใช่เฉพาะบทสรุป

สำหรับข้อค้นพบแต่ละรายการ ให้ตรวจสอบ:

  • ระดับความรุนแรงและสถานการณ์;
  • โค้ดที่ได้รับผลกระทบ;
  • คำแนะนำ;
  • การตอบสนองของนักพัฒนา;
  • สถานะปัจจุบัน;
  • ผู้ตรวจสอบได้ทดสอบการแก้ไขซ้ำหรือไม่

Fixed or Resolved is meaningful only when tied to a specific corrected version.

3. อ่านข้อจำกัด

รายงานอาจไม่ครอบคลุม:

  • ระบบ frontend และ backend;
  • การจัดการคีย์;
  • การออกแบบทางเศรษฐกิจ;
  • สัญญาของบุคคลที่สาม;
  • โครงสร้างพื้นฐานการติดตั้งใช้งาน;
  • การกำหนดค่าระบบ production;
  • ปัญหาด้านกฎหมายและการดำเนินงาน

ผู้ใช้โต้ตอบกับระบบทั้งหมด ไม่ใช่เพียงไฟล์ Solidity

4. ทบทวนความเสี่ยงด้านการดูแลระบบ

ให้สอบถามว่า:

  • ใครควบคุมการอัปเกรด;
  • การดำเนินการหยุดชั่วคราวได้หรือไม่;
  • ค่าธรรมเนียมหรือที่อยู่ที่เชื่อมโยงเปลี่ยนได้หรือไม่;
  • มี timelock หรือไม่;
  • มีการใช้ multisig หรือไม่;
  • วิธีที่ผู้ใช้รับรู้การเปลี่ยนแปลง

สิ่งเหล่านี้เป็นคำถามด้านการกำกับดูแลและความไว้วางใจ แม้จะยังไม่พบช่องโหว่ในโค้ด

5. ตรวจสอบความปลอดภัยหลังการตรวจสอบ

มาตรการต่อเนื่องที่มีประโยชน์ ได้แก่:

  • การทดสอบทุก release;
  • การตรวจสอบการอัปเกรดที่สำคัญ;
  • โปรแกรม Bug Bounty;
  • การเฝ้าติดตามบทบาทและ implementation;
  • ขั้นตอนตอบสนองเหตุการณ์;
  • การจำกัดจำนวนสินทรัพย์ที่รับความเสี่ยง

What an audit does not guarantee

การตรวจสอบไม่ได้รับประกันว่า:

  • การไม่มีข้อบกพร่องใด ๆ;
  • ความปลอดภัยของโค้ดที่เปลี่ยนหลังการตรวจสอบ;
  • ความปลอดภัยของเว็บไซต์ กระเป๋าเงิน DNS หรือเซิร์ฟเวอร์;
  • ความปลอดภัยของคีย์ที่มีสิทธิ์พิเศษ;
  • ความถูกต้องของโทเคนภายนอก oracle และบริดจ์;
  • ความต้านทานต่อการโจมตีทางเศรษฐกิจทุกรูปแบบ;
  • ความน่าเชื่อถือของทีม;
  • การปฏิบัติตามกฎหมาย;
  • สภาพคล่องของโทเคน;
  • การคืนเงิน;
  • ผลตอบแทนคงที่หรือผลตอบแทนอื่นใด

คำถามที่ผู้ใช้ซึ่งรอบคอบควรถาม

Is an auditor’s logo enough?
No. Find the report from the auditor’s own source and check its scope, commit, date, and findings.

If every finding was fixed, is the contract safe?
It means the listed findings were addressed in a stated version. Unknown issues and out-of-scope risks remain.

Are several audits automatically better?
The count alone says little. Coverage, quality, independence, recency, and version matching matter more.

Does an audit still apply after a proxy upgrade?
Only if the new implementation and configuration are covered by the reviewed version.

รายการตรวจสอบรายงาน

  • รายงานหาได้จากผู้ตรวจสอบ
  • ระบุ repository และแฮช commit แล้ว
  • สัญญาและส่วนพึ่งพาที่สำคัญรวมอยู่ในขอบเขต
  • เวอร์ชันที่ตรวจสอบตรงกับระบบที่ใช้งานจริง
  • ขอบเขตครอบคลุมพร็อกซี implementation และ admin
  • มีการบันทึกสถานะที่พบและผลการทดสอบซ้ำไว้
  • ได้อ่านข้อสันนิษฐานและรายการที่ไม่รวมแล้ว
  • ประเมินความเสี่ยงภายนอกโค้ดแยกต่างหากแล้ว

แหล่งข้อมูลและเนื้อหาอ่านเพิ่มเติม

  1. Ethereum.org — ความปลอดภัยของ smart contract
  2. Ethereum.org — การทดสอบ smart contract
  3. Ethereum.org — การตรวจสอบ smart contract อย่างเป็นทางการ
  4. Solidity Documentation — ข้อควรพิจารณาด้านความปลอดภัย
  5. OpenZeppelin Docs — รูปแบบการอัปเกรดพร็อกซี