DEV Community

Chakrit Likitkhajorn
Chakrit Likitkhajorn

Posted on

บ่นโค้ดใน Smart Contract ของ Pancake Bunny

อันนี้จะบ่นสั้นๆ คือวันนี้อยากรู้ว่า Pancake Bunny มันพลาดตรงไหน แล้วเห็นโค้ดชุดนึงที่น่าพูดถึง

คือออกตัวก่อน เวลาเขียน Smart contract มันจะมีเรื่องค่า Gas ซึ่งมันมีผลให้การเขียนโค้ดแบบปกติอาจจะสิ้นเปลือง จุดนี้ผมยังไม่เข้าใจมาก และที่เขาเขียนมันอาจจะดีที่สุดในโดเมน Smart Contract แล้วก็ได้นะครับ

แต่ถ้าเราเอามาเขียนในภาษาอื่นๆ ที่ไม่มีค่า Gas อย่าลอกเขามาทื่อๆ นะ

จากภาพนี้

Src

(ต้นทาง https://peckshield.medium.com/pancakebunny-incident-root-cause-analysis-7099f413cc9b)

ขอลอกส่วนนี้มา

if (IPancakePair(asset).token0() == WBNB) {
  valueInBNB = amount.mul(reserve0).mul(2).div(IPancakePair(asset).totalSupply());
  valueInUSD = valueInBNB.mul(priceOfBNB()).div(1e18);
} else if (IPancakePair(asset).token1() == WBNB) {
  valueInBNB = amount.mul(reserve1).mul(2).div(IPancakePair(asset).totalSupply());
  valueInUSD = valueInBNB.mul(priceOfBNB()).div(1e18);
}
// ต่อ ไม่ได้เอามาด้วย
Enter fullscreen mode Exit fullscreen mode

จาก

valueInBNB = amount.mul(reserve0).mul(2).div(IPancakePair(asset).totalSupply());

// และ 

`valueInBNB = amount.mul(reserve1).mul(2).div(IPancakePair(asset).totalSupply());

Enter fullscreen mode Exit fullscreen mode

สองบรรทัดนี้เหมือนกันเด๊ะๆ เลยแค่ใช้ reserve คนละตัว แล้วพอรวมกับ if token1() == WBNB ทำให้รู้ว่าจุดประสงค์ของโค้ดนี้คือมันต้องการจะเอา Reserve ของ WBNB มาใช้ในสูตร amount * reserve * 2 / totalSupply() นั่นแหละครับ

ดังนั้นการเขียนให้เจตนาตรงนี้เคลียร์กว่า ทำได้แบบนี้

uint reserveBNB
if (IPancakePair(asset).token0() == WBNB) {
  reserveBNB = reserve0
} else if (IPancakePair(asset).token1() == WBNB) {
  reserveBNB = reserve1
}

valueInBNB = amount.mul(reserveBNB).mul(2).div(IPancakePair(asset).totalSupply());
Enter fullscreen mode Exit fullscreen mode

โค้ดชุดหลังมันทำให้อ่านปราดเดียวรู้เลยว่า มันมีสูตรคำนวนแค่สูตรเดียวนะ และสูตรต้องการค่า BNB ที่อยู่ใน Pool มาใช้งานนะ ต่างกับชุดแรกที่ต้องเพ่งนานมากกว่าจะรู้ว่า "อ้อ สูตรเหมือนกันนั่นแหละไม่มีอะไรหรอก แค่ต้องเลือก Reserve มาให้ถูกที่" ผมเพ่งหลายนาทีกว่าจะถึงบางอ้อ

ผมเดาว่าที่เขาไม่เขียนแบบนี้เพราะจริงๆ มันมี Condition ที่ 3 แล้วใน Solidity การเช็ค if ทุกครั้งมันมีค่า Gas ซึ่งผมไม่เชี่ยวชาญพอที่จะบอกได้ว่าโค้ดแบบนี้ในบริบทของ Solidity ดีหรือไม่ดี อาจจะดีสุดแล้วก็ได้พอเอาเรื่องความประหยัดเข้ามาร่วม

แต่อยากจะบอกโปรแกรมเมอร์ที่เขียนโปรแกรมทั่วๆ ไปว่า โค้ดแบบนี้จริงๆ อย่าลอกไปใช้ในภาษาที่ไม่ติดเรื่องค่า Gas นะครับ มันอ่านยากครับ

Top comments (0)