Defi Scams —Yield Farming: วิธีการเอา LP Token ออก พร้อมทั้ง Remove Liquidity จากเว็บที่บินหรือโดน Rug Pull (2/2021)
Disclaimer: This article only aims to provide basic knowledge to the smart contract fraudulent schemes and prevent scams to grow and hurt the Defi community. This is NOT financial advice.
This guide wrote especially for Specific yield farming in Binance smart chain, Other protocols may differ.
Introduction
ในปี 2021 เรียกว่าเป็นช่วงเวลาที่ฮอทฮิตที่สุดของ Decentralize Finance หรือโดยย่อ “Defi” มี Dapp (Decentralize Application) ผุดขึ้นมาเป็นดอกเห็ด คอยให้บริการเหล่านักซิ่งไม่ว่าทั้งเร็วหรือช้า ไม่ว่าจะเป็น DEX (Decentralize Exchange), Yield Farming, Liquidity Mining, Collateral Loans, Stable coins, และเทคโนโลยีที่ถูกสร้างขึ้นมาโดย Blockchain Smart Contract อื่นๆอีกมากมาย
แต่ใช่ว่าทุกผู้ให้บริการ Smart Contract จะหวังดีต่อผู้ใช้เสมอไป บางเจ้ามีประสงค์ร้ายและคอยกัดกินผู้ใช้งาน Defi ทั้งทางตรงและทางอ้อม คอยสรรหาวิธีการ Scam ผู้ใช้โดยวิธีต่างๆ ไม่ว่าจะเป็นช่องโหว่ของระบบ Smart Contract, หรือแม้แต่ User Error.
ทั้งนี้ ถึงแม้ว่า Smart Contract จะสามารถตรวจสอบได้ 100% แต่ไม่ได้หมายความว่าทุกคนจะมีความสามารถในการมองเห็นช่องโหว่ที่ถูกสร้าง(หรือไม่ได้จงใจสร้าง) ในนั้น ผู้ใช้งานสมควรจะรู้ถึงหลักการทำงานต่างๆและอ่าน Source code ของ Smart contract ในเบื้องต้นได้ เพื่อป้องกันตัวเองจากภัยอันตรายของโลก Defi ที่พร้อมจะกลืนกินผู้ใช้หน้าใหม่ที่ไม่ระวังตัวและตกเป็นเหยื่อในที่สุด
Rug Pull Execution
ตามรายงานและข้อมูลที่เก็บได้แล้ว แต่ละเดือนมี % ของการ Rug pull เพิ่มขึ้นมากเรื่อยๆ และเพิ่มขึ้นสูงมากกว่าช่วงเวลาก่อนๆเป็นพิเศษในเดือนนี้(Feb 2021) ด้วยเหตุผลของจำนวนผู้ใช้งานที่เพิ่มมากขึ้น และโอกาสในการทำกำไรของ Scammer เอง ด้วยเหตุนี้ผู้ใช้ถึงต้องระวังตัวเป็นพิเศษ
จะไม่ขอลงรายละเอียดวิธีการและประเภทของ Rug pull ในส่วนนี้ แต่พูดง่ายๆ, Rug pull, ก็คือเว็บบิน — โดนโกงเงินนั่นแหละ เราจะไม่สามารถถอน LP Token โดยผ่านทางเว็บได้อีกต่อไป (เพราะเว็บมันปิด) จึงต้องทำการถอนด้วยตัวเองผ่าน Smart Contract Function Execution ผ่านหน้าเว็บ Bscscan
Verify Your Token
เมื่อเรา Stake LP Token ของเราลงไปในเว็บ นั่นหมายความว่า LP Token ที่อยู่ในกระเป๋าเงินของเรา ถูก”ส่ง”ไปให้กระเป๋าเงินของ Smart Contract — แปลว่าเรา ”ไม่มี Token จริงๆอยู่ในกระเป๋าเงินของเราอีกต่อไป” แต่มี Allowance หรือ การยินยอมให้ใช้จ่าย Token ใน Smart Contract ตามจำนวน Token ที่เราส่ง (Stake)
ดังนั้นตัว Contract ก็จะสามารถแยกแยะได้ว่า Token ที่อยู่ใน Contract นั้นเป็นของใครบ้าง จำนวนเท่าไหร่บ้าง
ก่อนที่เราจะเอา LP Token ออกได้นั้น เราต้องมาดูก่อนว่า Token ของเรา “อยู่ใน Pool ไหน” — เช่น BNB/BUSD, BNB/EGG, BUSD/EGG เป็นต้น
วิธีเช็คเบื้องต้น
เริ่มต้น เข้าไปที่ Contract ของ MasterChef หรือ Main Staking Contract หลักที่เป็นตัวจัดการ Token, Mint เหรียญ, ปล่อย Farm, จัดการ Assets ต่างๆตามหลักแล้วจะใช้ชื่อ Masterxxx, xxxChef, ฯลฯ และกดที Tab Contract และเลือก Read Contract
วิธีหา MasterChef Contract ง่ายๆคือ เข้าไปที่ Transaction ที่เรา Stake LP Token ของเรา จะเห็นได้ชัดว่าเรา Interact กับ Staking Contractให้กดเข้าไปใน Contract นั้น
จากนั้นหา Function ที่ชื่อว่า poolInfo
, Function นี้จะเป็นตัวบอกตำแหน่งของ Pool ของเรา เอาไว้ใช้เป็นข้อมูลในการทำอย่างอื่นต่อไป จากนั้นใส่ตัวเลขไปเริ่มจาก 0 (0 เป็นอันแรก) แล้วคลิกใน lpToken
address ดูว่า pool นี้เป็นของ LP อะไร ถ้าคลิกเข้าไปแล้วจะเจอหน้า LP Token Contract ให้สุ่มเลขไปเรื่อยๆจนกว่าจะกดเข้าไปแล้วเจอหน้า LP Token ของเรา แล้วจำเลข pool แล้วไปใช้ใน Function ถัดไป
จากนั้นหา Function ที่ชื่อว่า userInfo
(ชื่ออาจแตกต่างกันไปในแต่ละ Contract) ช่องแรกให้ใส่ poolId
ที่เราได้จาก Function ด้านบน ช่องที่สองให้ใส่ address
ของกระเป๋าเรา, Function นี้จะทำให้เราสามารถดูได้ว่าเรา Stake ใน pool นั้นและมี LP อยู่ใน pool เท่าไหร่ในช่อง amount
และดู Token ที่เราสามารถ Harvest ได้ที่ rewardDebt
ซึ่งในตัวเลขพวกนี้จะมีหน่วยเป็น Wei หรือ 10¹⁸, เช่นมันขึ้นเป็นเลข 46304767801968835341 เราก็เอามาหาร 18 จะได้ 46.3 กว่าๆ นั่นหมายความว่าเรา Stake LP Token ของเราใน pool 0 อยู่ 46.3 LP Token นั่นเอง
ต่อไปให้จำเลข amount
นี้ไว้ แล้วกลับไปที่ poolInfo
และกดเข้า address ของ lpToken
มันจะเด้งไปหน้า LP Token Contract
พอเข้าหน้า LP Token Contract มาแล้วเราสามารถดูธุรกรรมได้ว่าใครทำอะไรกับ LP Token นี้บ้าง รวมถึงสามารถกดดูจำนวนและมูลค่าของ Token ต้น (เช่น BNB หรือ USD) ที่อยู่ใน Contract นี้ได้ด้วย
จากนั้นให้มองตรงฝั่งขวา จะมีที่เขียนว่า Token Tracker ให้กดเข้าไป จะเจอหน้าของ Token นั้นๆ แล้วให้กดตรง Holder, Tab ที่ 2 นับจาก Transfer
ให้กดตรงแว่นขยายขวาบน จะเป็นการ Search Token Holder จาก address ซึ่งตรงนี้ให้คุณใส่ address ของ MasterChef เข้าไป เพื่อเป็นการ Recheck ว่า MasterChef มี LP Token ของคุณอยู่ จ ริ ง ๆ หรือเปล่า
ถ้าเกิดว่า Balance ของ Contract มีมากกว่า amount
ที่คุณจดมาตอนแรก ยินดีด้วย 🎆 เงินของคุณยังอยู่ดี (แม้มูลค่าของ LP จะลดลงเนื่องจาก Impermanent Loss จากการโดน Dump แต่ก็ยังได้เหรียญต้นกลับมา)
แต่ถ้า Balance มีน้อยกว่า amount
หรือ Balance เป็น 0
ยินดีด้วย คุณโดน รั บ น้ อ ง แบบ ส ม บู ร ณ์ แ บ บ
คือถ้า Balance เป็น 0 นั่นหมายความว่ามีคนอื่นหรือเจ้าของ Contract สามารถเข้าถึง LP Token ของคุณได้ บอกได้สองอย่าง 1. คุณโดน Backdoor ใน Contract Code 2. คุณไม่ควรเชื่อใจ Smart Contract ใดๆบนโลกอีก
หากยังเหลือ Balance แต่ว่า น้อยกว่า amount
ของคุณ ให้จดค่า Balance นั้นไว้ อย่าลืมนับจุด Decimal ให้ครบ 18 ตัว ขั้นตอนต่อไปเราจะไป Unstake จาก Contract แล้วเอา LP Token กลับมากัน
Unstake
ก่อนอื่นให้กลับไปที่ MasterChef Contract และเลือก Write Contract แทน
ถ้า Balance เหลือมากกว่าหรือเท่ากับ amount
ให้มองหา Function ที่ชื่อว่า emergencyWithdraw
ก่อนที่จะกดใช้ เรามาดู Code ก่อนว่ามันทำงานยังไง, emergencyWithdraw
รับค่า _pid
(Pool Id) และเรียกดู amount
ของเราใน poolId
จากนั้นใช้ safeTransfer
เข้าสู่ address ของเรา, และ set rewardDebt
หรือ Token ที่ยังไม่ถูก Harvest เป็น 0, แต่ใครจะสนใจกันล่ะตอนนี้
safeTransfer
เป็น Standard ของ OpenZeplin ที่หลักการทำงานของมันคือ ถ้า amount
มากกว่า balance
ในตัว, Transaction จะถูก revert นั่นแปลว่าถ้าเรามี amount
ที่เรา Stake ไปเกิน balance
ของ Contract เราจะไม่สามารถถอนได้
ถ้าไม่มีอะไรแล้วก็ใส่ _pid
เป็น Pool Id ของ LP เราแล้วกด Write หากไม่มีอะไรผิดพลาด LP Token จะกลับมาใน Wallet ของเรา
ถ้า Balance เหลือน้อยกว่า amount
ให้มองหา Function ที่ชื่อว่า withdraw
Source code ของ withdraw
ก็จะทำงานคล้ายๆ emergencyWithdraw
แต่จะโอน Token ที่ยังไม่ถูก Harvest เข้ากระเป๋าของเราด้วย ทำให้ใช้ Gas มากกว่า
ถ้าพร้อมแล้วก็ใส่ _pid
เป็น Pool Id ของ LP เรากับ amount
ที่เราจดมาจาก BSC Scan ( amount
ต้องมากกว่า 0 ) ให้ลบจุด Decimal ออกด้วย เช่น 44.5128 Token ให้ x 10¹⁸ เข้าไป ก็จะกลายเป็น 44512800000000000000 เสร็จแล้วกด Write
หากได้ LP Token ออกมาแล้วให้กลับไป Remove Liquidity ที่ PancakeSwap ถ้าเป็น LP/ใช้ AMM ของ Pancake แต่ถ้าเป็นของเจ้าอื่นหรือเป็นของเว็บที่ปิดไปแล้ว ขั้นตอนถัดไปจะมาสอน Remove Liquidity โดยใช้ BSCScan กัน
Remove Liquidity
ก่อนอื่นเข้าไปที่หน้า LP Token Contract ของเราก่อน แล้วเข้าไป Recheck ว่ามี Token ต้นอยู่ใน LP Contract ไหม วิธีการเช็คมีอยู่ 2 วิธีให้ลองทำทั้ง 2 วิธี
- กดดูตรง Token Dropdown
- กด Read Contract แล้วหา Function ที่ชื่อว่า
getReserves
ถ้าเกิดว่าอันใดอันหนึ่งมีค่าเป็น 0 ขึ้นมา นั่นยังไม่ได้แปลว่าเงินคุณหาย เช่นเดียวกับการที่คุณยังเห็นตัวเลขในนั้น ไม่ได้แปลว่าเงินคุณยังอยู่ เพราะว่าค่าของ getReserves
อาจจะยังไม่ถูกอัพเดตโดย sync
อย่างไรก็ถาม ให้ลอง Remove Liquidity/Unwrap LP เลย
หากจะ Remove Liquidity ต้องไปทำที่ Router Contract, ซึ่ง remove,add liquidity เป็น periphery ของ swap อยู่ใน Contract เดียวกัน
วิธีหา Router Contract ง่ายๆคือ เข้าไปที่ Transaction ที่เราแลก Token เป็น LP Token จะเห็นได้ชัดว่าเรา swap หรือ add liquidity บน Router ให้กดเข้าไปใน Contract
ให้เข้าไปที่ Contract แล้วกด Write Contract จากนี้ไปจะซับซ้อนเล็กน้อย ให้หา Function ที่ชื่อว่า removeLiquidity
จะเห็นได้ว่ามีช่องให้กรอกเยอะแยะเต็มไปหมด เราจะไปกันอย่างช้าๆในตรงนี้
ช่อง tokenA
/ tokenB
ให้ใส่ address Token ต้นทั้งสองอันของ LP Token เข้าไป เช่นถ้ามี LP ของ BNB/BUSD ช่องแรก Token A ให้ใส่ Contract Address ของ BNB (ซึ่งปกติแล้วถ้าใช้ BNB ในการ Stake จะถูกแปลงเป็น WBNB โดยอัตโนมัติ) คือ 0xbb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c และ Token B ให้ใส่ Contract Address ของ BUSD คือ 0xe9e7cea3dedca5984780bafc599bd69add087d56
ช่อง liquidity
ให้ใส่จำนวน LP Token ที่เรามีในหน่วย Wei (x10¹⁸)
ช่อง amountAMin
/amountBMin
เป็นช่องที่กำหนดว่าเราจะได้รับ Token ต้นของเราคืนมาขั้นต่ำเท่าไหร่ (ถ้าเว็บยังใช้ได้มันจะถูกเรียกว่า Slippage) ในส่วนนี้ให้ใส่ไปที่ 0 ทั้งสองช่องเพราะเราจะเอา Token เราออกมาไม่ว่าจะได้เท่าไหร่
ช่อง to
ให้ใส่ Address ของกระเป๋าเรา
ช่อง deadline
จะเป็นช่องที่กำหนดเวลา Transaction มากสุด ในหน่วย Unix Epoch Time หากเกินเวลานี้ Transaction จะถูก Revert, ให้ไปดูเวลาที่ https://www.epochconverter.com/ แล้วปรับเวลาให้มากขึ้นสัก 1 ชม เสร็จแล้วก็ก็อป Unix Timestamp กลับมาแปะที่ช่องนี้
เสร็จแล้วให้กด Write ตามหลักการแล้วถ้ายังมี Token อยู่ใน Reserve แม้แต่ 0.0000001 มันก็จะถูกโอนมาให้เรา แต่ถ้า Transaction ถูก Revert แปลว่า
RIP 💤
ถ้าอยากจะ Recheck อีกรอบ ให้กด Write ที่ Function sync
เพื่อให้ LP Token Contract Re-calculate getReserves
ใหม่ หรือไปเช็คจาก Contract ของ Token ต้นโดยใส่ Address ของ LP Token เข้าไป
ถ้าทำทั้งสองทางแล้วยังเจอ Balance ที่เป็น 0 อยู่ก็
That’s all for now. Remember to ape in responsibly and your funds will be SAFU, stay safe my fellow degens.
Feedback is always appreciated.