KillSwitch v0.0.1 Incident Report

เจาะโค้ด และ วิธีแก้ไข แบบละเอียด

Tanopwan
KILLSWITCH
3 min readApr 3, 2021

--

หลังจากที่ KillSwitch ได้เปิดให้ Community Test กันไป ในช่วง 2–3 วันแรกก็พบปัญหาดังนี้

Issue #1 Web UI Error เมื่อฝาก 0 LP

เนื่องจากไม่ได้ดักว่าไม่ให้ทำการ Stake ถ้ามี LP ≤ 0 ในฝั่ง UI และฝั่ง Smart Contract เนื่องจากเป็น early version สุด ทำให้อาจจะมีแต่ MVP จริงๆ ซึ่งไม่ได้มีผลอะไรกับเงินของทุกคน แต่อาจจะเสียค่า gas ที่ฝาก 0 LP ไปฟรีๆ

Version UI ยังไม่ได้ปั้น ทีมงานต้องขอบคุณ fc ขาซิ่ง ทุกคนจริงๆ ที่มาช่วยกันทดสอบใน version นี้ 🙏🙏🙏

ซึ่งทีมงานจะแก้ใน version 0.0.2 นะคะ 💁

Issue #2 เมื่อทำการ Stake LP มากกว่า 1 ครั้ง ทำให้ balance LP ในรอบแรกหายไปอยู่ในหลุม 😵

เนื่องจาก KillSwitch Smart Contract ของเราทำหน้าที่เสมือนเป็นตัวแทนในการฝาก LP Token เข้าไปใน 🍰 Smart Contract แปลว่า KillSwitch Smart Contract จะต้องมี map เอาไว้สำหรับเก็บว่าแต่ละคนนั้นฝากมาแล้วเท่าไร

ซึ่ง Bug ของบรรทัดนี้คือการที่เราจะ เซ็ตค่า _amountLP ใหม่ทับไปเสมอ ทำให้ balance ของเก่าถูก rewrite ไปนั่นเอง ส่วนวิธีแก้คือ การใช้ += แทน เพื่อให้จำนวน LP accummulate เพิ่มทุกครั้งที่ฝากเพิ่มนั่นเอง

❗️❗️❗️สำหรับคนที่ฝากมาเกิน 1 รอบ จะเกิดอะไรขึ้น จริงๆแล้ว LP Token ที่ KillSwitch ได้นำฝากไปให้ ก็ไม่ได้หายไปไหน ยังคง Lock อยู่ใน Smart Contract และเนื่องด้วยยังอยู่ในขั้นตอน development จึงยังเปิดให้ Dev wallet account (owner) ที่ deploy Smart Contract สามารถถอน LP Token ออกมาแบบ manual ได้ แต่จำเป็นต้องคำนวนจาก transaction logs แทน เพื่อคืน LP ให้กับผู้เข้าร่วมทดสอบแต่ละคน

เนื่องจากมีผู้เข้าทดสอบ KillSwitch Alpha 0.0.1 จำนวนมาก ทางทีมงานจึงต้องเขียน script ในการดึง transaction history จาก Smart Contract เพื่อหาย้อนหลังว่าใครฝากมาเท่าไรบ้าง

วิธีการดู transfer events

Binance Smart Chain ได้มีการ provide API ในการดึง transaction events ของ Token ออกมาได้ ตามหลักก็ให้ใส่ startblock
เริ่มที่ Smart Contract เราถูก deploy (ใส่ startblock=1 ก็คงไม่บาปมากหรอกมั้ง 😆)

โดย tokentx (token transaction คือ action ที่เราสนใจ

ปล. เราสามารถสมัครและขอ API Key ได้ที่เว็บ https://bscscan.com/apis

https://bscscan.com/apis#accounts

ซึ่ง API นี้จะดึง transfer events ของ Token ใน address ของ Smart Contract เรามาทั้งหมด ซึ่งเราสนใจเฉพาะคนที่ฝากคู่เหรียญ LP เข้ามา และ ถอนออกไป เพื่อหาคู่เหรียญ LP ที่ค้างสำหรับแต่ละ user

ขั้นตอนการฝากเหรียญ LP เพื่อไปฟาร์มใน pancakeswap เป็นรายการ token transfer event

ซึ่งเราสามารถไป filter หา transfer event นี้ได้ โดยการหา event ของ Token ที่เราสนใจ ว่าใครโอนเข้ามาหา KillSwitch Contract บ้าง

โดย from คือ กระเป็า wallet ของ user กับ value ที่โอนเข้ามา

ปล เวลา filter อย่าลืมว่า LP ที่เข้า KillSwitch Smart Contract ไม่ได้มีแค่ user wallet เท่านั้น แต่จะมีจาก Masterchef ด้วย เพราะฉะนั้นอย่าลืม filter ออก (อธิบายได้ในรูปถัดไป)

ในทางกลับกันเวลาเราถอน LP ออกมา flow จะซับซ้อนกว่า เนื่องจากนี่คือสุดยอด feature ของ KillSwitch ที่จะทำการเผาคู่ LP เก็บ cake reward ให้แล้วก็แปลงกลับเป็นเหรียญที่มีมูลค่าให้ user ตามรูปข้างล่าง

ขั้นตอนการถอนเหรียญ LP เป็นรายการ token transfer event หลายๆ รายการ

ซึ่งในกรณีนี้เราจะสนใจจำนวน LP ที่ถูกถอนออกมาเท่านั้น

ปล สังเกตุว่า hash นี้จะมีหลาย transfer events มาก เพราะใน 1 liquidate function ของ KillSwitch เราทำหลาย operation เลย จึงต้องดูดีๆ ว่าเราสนใจ transaction ไหน ซึ่งจาก transfer event ด้านบนที่เราสนใจคือ จำนวนเหรียญ LP ที่โอนจาก Masterchef 👩‍🍳 มาที่ KillSwitch Smart Contract แต่สังเกตุว่าเราไม่สามารถหาว่า user คนไหนเป็นคนถอนได้จาก transfer event นี้

แต่เรารู้ transaction hash ทำให้เราสามารถนำไปหาต่อได้ว่าสุดท้ายแล้ว KillSwitch ของเราได้โอน BNB กลับไปให้ wallet ไหนนั่นเอง

ซึ่งเราก็จะรู้ได้ว่า แต่ละ wallet มีการฝาก และ ถอน ไปเท่าไร

ถ้ามีการฝากมากกว่าถอน ทีมงานเราจะทำการคืน LP โดยการนำ LP ที่ค้างอยู่ ไป init ใหม่ให้ใน Smart Contract v0.0.1 fixed version (จะไม่ได้เป็นการ โอนเงินให้รายคน)

รายชื่อ wallet ที่ทำการคืน LP ทั้งหมด

สำหรับใครที่ยังไม่ได้เอาคืนมากดเอาคืนได้นะคะ เพราะว่า ทางทีมงานจำเป็นต้อง Migrate Smart Contract เพื่อเพิ่ม feature ใน version 0.0.2 ต่อไป

อย่าทิ้งเอาไว้เลย ทีมงานไม่สบายใจ~~~~ หรือจะ seed fund กันแน่นะ :D

ซึ่ง code ในการ หา Diff ของ LP นี้ ทางทีมงานก็ได้เปิดเป็น opensource ไว้ สำหรับสาย Deep tech ก็สามารถมาดูได้ที่นี่เลย อาจจะดูดิบๆ หน่อย จะพยายามคลีนให้นะคะ :D

https://github.com/level11x/killswitch-incident-report-1

Issue #3 🍰 Cake Rewards จากการฟาร์ม คำนวนไม่ถูกต้อง

ตรงนี้อาจจะต้องทำความเข้าใจการทำงานของ Masterchef 👩‍🍳 สักหน่อยก่อน คือ ทุกครั้งที่มีการฝากหรือถอน LP จะทำให้ rewards ทั้งหมดหลุดออกมาด้วย ซึ่ง rewards นี้เป็น rewards ที่เกิดจาก LP ที่ Smart Contract KillSwitch ฝากไปทั้งหมด ซึ่ง KillSwitch ลืม aware ข้อเท็จจริงตรงจุดนี้ ทำให้เอา rewards ที่หลุดมาทุกครั้ง มาให้กับคนสุดท้ายที่ถอนออกไป และ การ show cake rewards ในหน้า UI จะถูก reset เป็น 0

ซึ่งทีมงานจะทำการแก้ไขใน version 0.0.2 ต่อไป จะขออธิบายวิธีการคำนวน rewards ใหม่แบบละเอียดในบทความหน้าค่า

--

--

Tanopwan
KILLSWITCH

Software Engineer based in Bangkok, Thailand