NFT 專案持續火熱,由黃心健、江振誠與張逸軍共創之 NFT 專案 We are What We Eat 2022.1.10 11:00 優先釋出的 200 個 Seed NFTs 在 2 分鐘內全數鑄造完成,市場反應熱烈之下,項目方 EchoX 隔天(1/11)11:00 啟動第二波活動 Public Sale 預計再賣出 50 個。但第二波活動發生超賣和提前購買等問題。
項目方遭發現合約漏洞導致之超額鑄造,當時先行公告未經正常流程鑄造的 NFT 將不享有原本福利並要求退還,而後宣布於二級市場買賣之 NFT 皆可享有其原本福利補償購買客戶損失。
本次專案超賣原訂數量 200 個 NFT,項目方要求未經正常鑄造流程上架到 OpenSea 平台銷售之 NFT 應主動退回,造成已在平台搶購之粉絲錯愕與損失,智能合約在 NFT 專案中更顯重要,小型專案百萬起跳,大型專案 100 個 NFT 市值動輒超過 1 億,我們將從智能合約分析,再談該如何避免 NFT 超賣事件重演。
此次 3 位頂尖創作者與 ExchoX 的事件,我們先從項目方後續處理討論,再分析合約與討論解決方案。
一、EchoX 事件之後續處理
二、從智能合約角度分析為何會超賣與偷跑
- 找出合約 Mint Function
- 合約如何更新與設定?
- 為什麼會發生偷跑?(提早了 30 分鐘)
- 為什麼會發生超賣?(多賣了 200 個)
- 總結
一、EchoX 事件之後續處理
2022.1.11 放棄現有合約,原本透過官方渠道鑄造 Seed NFT 的買家,會重新空投原購買量的 Seed NFT 到你的錢包。在OpenSea 之二級市場買到「非官方 Seed NFT」的買家,EchoX 會直接空投新合約的 Seed NFT 至買家錢包,但需於 1/12 6pm(UTC+8)前 Email:[email protected] 回報。需附上 (1.) 錢包地址 (2.) 你的 OpenSea NFT 連結。
二、從智能合約分析為何會超賣
1. 找出合約 Mint Function

首先我們到 Transactions 看1/10, 1/11的交易紀錄,可以看到 Presale
這個 function被執行多次,Presale 需要傳送 ETH,且傳送的 ETH 也是 mint 的價格 0.095 ETH 的倍數,所以它就是 mint function。


透過 “Write Contract” 跟 “Transactions” 找出 mint function 是 presale
下面再去 “Code” 裡面仔細看 “presale” function 是怎麼作用的
presale function

presale 的功能為購買 NFT,這裡有 2 個條件 :
- 截止時間之前才能購買(沒有規定開始時間)
- 不能超過最大發行數量
接著我們來看一下合約要如何更新和設定。
2. 合約如何更新和設定
透過 setActivity
function 來設定每一波活動
https://etherscan.io/address/0x52afa21bb061bb8a434102802c3d1625a86e9870#writeContract
setActivity 參數:
(1.) 第一波活動的合約設定
https://etherscan.io/tx/0x719ab9537f6d210f6308f22a0adf7ab78cbce11d93c0526b8f391a754162b2e4
把輸入資料(Input Data)放大來看:
從 etherscan 的活動紀錄我們可以明顯看出
第一次的設定是在 Jan-07-2022 10:54:28 AM +UTC (台北時間要 +8 小時)
setActivity 設定內容為 :
活動 ID(activityID) : 3
價格(charges.price) : 0.095 ETH
截止時間(period) : 1672272000 (Thursday, December 29, 2022 12:00:00 AM GMT)
最大發行數量(maxCirculation) : 200
(2.)第一波購買
第一波活動設定完成後就可以等人購買了,這裡 NFT 最大發行數量設定為 200 個,和官網宣布的一樣,這裡沒有問題。
但時間的設定會有點問題,因為 1672272000 的時間是 2022/12/29,這樣等同於沒有限制,但因為沒人發現,所以第一波沒有人提前購買。
訂單成立時間:2022-01-10 11:17:52 – 2022-01-10 11:21:09 (台北時間)
得到 19 eth,共賣出 200 個(每個 NFT 定價 0.095 ETH)
(3.)第二波活動的合約設定
https://etherscan.io/tx/0xf1a55b20727cbf7ee53bf18425e3cd64987337cc0239ed6e3a2982622c6eae03
我們把輸入資料(input data)放大來看:
從 etherscan 的活動紀錄我們可以明顯看出
第二次的設定是在 Jan-11-2022 02:24:32 AM +UTC (台北時間要 +8 小時)
setActivity 設定內容為 :
活動 ID(activityID) : 3
價格(charges.price) : 0.095 ETH
截止時間(period) : 1672272000 (Thursday, December 29, 2022 12:00:00 AM GMT)
最大發行數量(maxCirculation) : 250
(4.) 第二波購買
訂單成立時間:2022-01-11 10:25:32 – 2022-01-11 10:30:55 (台北時間)
得到 23.75 eth,共賣出 250個(每個 NFT 定價 0.095 ETH)
以上是兩波發行的數據,至於為什麼會發生超賣和提前購買的問題,需要從程式碼去解析。
3. 為什麼會發生偷跑? (提早了 30 分鐘)
NFT 合約的部署和設定會在銷售活動開始前,通常程式碼會寫出一個未來的開啟時間,等到區塊鏈時間大於開啟時間才能購買。
通常我們會這麼寫:
require(block.timestamp >= activity.period,
"MSActivityCenter: This activity is out of date")
意思是活動會在設定的時間後才開啟。
註:block.timestamp
為區塊鏈時間,activity.period
為設定的開始時間
但這份合約的邏輯是相反的

時間條件(畫紅線處):
activity.period >= block.timestamp
變成在指定的時間前才能購買,也就是這份合約只設定截止時間。
所以第二波偷跑是怎麼造成的?

第二波項目方設定活動時,區塊鏈時間(block.timestamp
)是 2022/1/11 10:24 (換算秒數:1641896672)
activity.period 被設定為 1672272000
從presale
函式可以看到時間條件:
activity.period >= block.timestamp
1672272000 >= 1641896672
# 時間條件通過
所以項目方早上 10:24 設定活動,(下圖綠框)時間條件有通過,加上最大發行量(maxCirculation)跟本次發行量(circulation) 被設定為 250 跟 0 個,所以數量限制(下圖紅框)也通過了。才造成原本預計販售時間 11 點,卻在合約一設定就立刻變成可以購買,提早了 36 分鐘。

合約優化建議:
- 合約的時間條件可以改成
block.timestamp >= activity.startTime
將原本的 period 命名改成 startTime(開賣時間),這樣程式碼的可讀性會更高。
4.為什麼會發生超賣?(多賣了200個)
超賣
主要是人為操作的問題。因為每一波活動都需設定 setActivity
函式(上圖),這個函式會設定 NFT價格,活動截止時間,最大發行量,並將此次活動目前發行量設置為 0。
在第一波結束後,已售出量為 200。設定第二波活動時,第二波活動初始發行量被設定為 0(下圖 172 行),所以最大發行量(maxCirculation) 應該設定 50,但是第二波設定時把最大發行量設定成 250,多了 200 個。
此合約設計每次活動是獨立的,最大發行量是每次活動的發行量。但是設定活動的人,把第二波的最大發行量當作本項目預計釋出的總發行量,才會有 200 落差。

最大發行量的優化建議
如果只有兩波發行活動,且已確定最大發行量,可以在一開始就設定好 maxSupply,並讓總發行量(totalSupply)不要超過這個數值。
例如 seed NFT如果一開始就打算賣 250 個,可以在 constructor 階段就設定
uint public maxSupply = 250;
總結
整起 EchoX 事件中我們發現到,合約的設計以及人為操作,確實都需要很謹慎。畢竟合約就是法律條文,從部署上鏈以後,就不能夠輕易的更改。因此合約部署之前,團隊成員彼此間及活動的執行者,都需要進行充分的溝通以及討論。如此一來,才能避免兵荒馬亂,讓團隊在應對不管是好的突發狀況,又或者是壞的突發狀況,都可以很從容地去應對,也可以降低人為操作發生問題的可能性,就像是這次 EchoX 設定數量與官網公告的有 3 倍以上的差距。
另外也很值得探討的一點是 NFT 項目方與去中心化平台之間的關係,這次 EchoX 過程中不願意承認在二級市場 Opensea 上買到的 NFT。
從中我們可以了解到去中心化世界的運作是否真的去中心,同時對於 NFT 的擁有權及 NFT 項目方給予社群回饋,中間是存在著不確定性的,原本 EchoX 所承諾的 RAW 優先訂位權以及加購享用專屬的沉浸式「We Are What We Eat」VR 與料理體驗,EchoX 如果拒絕承認,就算持有NFT,到時候也沒辦法在 RAW 使用優先訂位權的。