無論是開發DeFi協議還是其他的智能合約應用,在上線到區塊鏈主網前都需要考慮到許多安全因素。很多團隊在審核代碼時只關注Solidity相關的陷阱,但要確保dApp的安全性足夠支撐上線主網,通常還有很多工作要做。了解大多數流行的DeFi安全漏洞可能會為你和你的用戶節省數十億美元并且免除后續的各種煩惱,如預言機攻擊、暴力攻擊和許多其他威脅等。
考慮到這一點,我們將在下文研究有關DeFi安全的十大最佳實踐,這將有助于防止你的應用程序成為攻擊的受害者、避免與用戶的不愉快對話,并能保護和加強你作為一個超級安全的開發者的聲譽。
1 了解重入攻擊
一種常見的DeFi安全攻擊類型是重入攻擊,這也是臭名昭著DAO攻擊的形式。這種情況就是當一個合約在更新自己的狀態之前調用了一個外部合約。
引用Solidity文檔的內容:
"一個合約(A)與另一個合約(B)的任何交互,以及任何ETH的轉賬都會將控制權移交給該合約(B)。這使得B有可能在這個交互完成前回調到A。"
我們來看看一個例子:
在這個函數中,我們用msg.sender.call調用另一個賬戶。我們要記住的是,這可能是另一個智能合約!
在(bool success,) = msg.sender.call{value: shares[msg.sender]}(""); 返回之前,被調用的外部合約可以被編碼為再次調用withdraw(提款)函數。這將允許用戶在狀態更新前提取合約中的所有資金。
合約可以有幾個特殊函數,即receive(接收)和fallback(回退)函數。如果你發送ETH到另一個合約,它將自動被路由到receive函數。如果該receive(接收)函數再指向原來的合約,那么在你有機會將余額更新為0之前,你就可以不斷提款。
讓我們看看這種合約可能是什么樣子的:
在這個函數中,當你把ETH發送到steal合約后,它將調用receive函數,該函數指向Fund合約。此時,我們還沒有運行shares[msg.sender] = 0,所以合約仍然認為用戶有可以提取的余額。
解決方案:在轉移ETH/通證或調用不受信任的外部合約之前,更新合約的內部狀態
有幾種方法可以做到這一點,從使用互斥鎖到甚至簡單地排序你的函數調用,你只在狀態被更新后才能接觸到外部合約或函數。一種簡單的修復方法是在調用任何外部未知合約之前更新狀態:
轉移、調用和發送
長期以來,Solidity安全專家建議不要使用上述方法。他們建議不使用call函數,而是使用transfer,像下面這樣:
我們之所以提到這一點,是因為你可能會看到外面有一些相互矛盾的資料,它們的建議與我們的建議相反。此外,你也會聽到send函數。每一個函數都可以用來發送ETH,但都有輕微的差異。
transfer: 最多需要2300個gas,失敗時會拋出一個錯誤
send: 最多需要2300個gas,失敗時返回false
call: 將所有gas轉移到下一個合約,失敗時返回false
transfer和send在很長一段時間內被認為是 "更好 "的做法,因為2300個gas真的只夠發出一個事件或其他無害的操作;接收合約除了發出事件不能回調或做任何惡意操作,因為如果他們嘗試這樣做的話,他們會耗盡gas。
然而,這只是目前的設置,由于不斷變化的基礎設施生態,gas成本在未來可能會發生變化。我們已經看到有EIP改變了不同操作碼的gas成本。這意味著未來可能有一段時間,你可以以低于2300個gas的價格調用一個函數,或者事件的成本將超過2300個gas,這意味著任何現在要發出事件的接收函數會在未來會失敗。
《元宇宙十大技術》出版,中國移動通信聯合會元宇宙產業委組織撰寫:8月19日消息,中國移動通信聯合會元宇宙產業委組織撰寫的《元宇宙十大技術》已出版,本書將元宇宙技術體系歸納為五大地基性技術和五大支柱性技術,“五大地基性技術”包括:計算技術、存儲技術、網絡技術、系統安全技術和AI技術;“五大支柱性技術”包括:交互與展示的技術、數字孿生與數字原生的技術、創建身份系統與經濟系統的技術、內容創作技術和治理技術。(光明日報)[2022/8/19 12:35:37]
這意味著最好的做法是在調用項目外的任何合約之前更新狀態。另一個可能的緩解措施是對關鍵函數施加一個互斥鎖,例如ReentrancyGuard中的非重入修改器。采用這樣的互斥鎖將阻止交易合約被重入。這實質上是增加了一個“鎖”,所以在合約執行過程中,任何調用合約的人都不能“重新進入”該合約。
重入攻擊的另一個版本是跨函數重入。下面是一個跨函數重入攻擊的例子,為了便于閱讀,使用了transfer函數:
有可能在另一個函數完成之前調用一個函數。這應該是一個明確的提醒,在你發送ETH之前一定要先更新狀態。一些協議甚至在他們的函數上添加了互斥鎖,這樣如果另一個函數還沒有返回,這些函數就不能被調用。
除了常見的重入漏洞外,還有一些重入攻擊可以由特定的EIP機制觸發,如ERC777。ERC-777(EIP-777)是建立在ERC-20(EIP-20)之上的以太坊代幣標準。它向后兼容ERC-20并增加了一個功能,使“運營商”能夠代表通證所有者發送通證。關鍵是該協議還允許為通證所有者添加“send/receive鉤子”,以便在發送/接收交易時自動采取進一步行動。
從Uniswap imBTC黑客事件中可以看出,該漏洞實際上是由Uniswap交易所在余額變化之前發送ETH造成的。在那次攻擊中,Uniswap功能的實現沒有遵循已被廣泛采用的“Check-Effect-Interact”模式,該模式是為了保護智能合約免受重入攻擊而發明的,按照該模式,通證轉移應該在任何ETH轉移之前進行。
2使用DEX或AMM儲備作為價格預言機將導致漏洞攻擊
這既是用于攻擊協議的最常見方法之一,也是最容易防止的DeFi安全攻擊面之一。如果你使用getReserves()作為量化價格的方法,這應該是一個警示信號。當用戶操縱訂單簿或基于自動做市商的去中心化交易所(DEX)的現貨價格時,這種集中式價格預言機攻擊就會發生,通常是使用閃電貸。然后使用DEX報告價格作為他們的價格預言機的協議,會導致智能合約的執行出現偏差,其形式包括觸發虛假清算、發放過多的貸款或觸發不公平交易。由于這個漏洞的存在,即使是流行的DEX,如Uniswap,也不建議單獨使用他們的儲備池作為價格預言機。
預言機可以是任何外部實體,它獲取外部數據并將其傳遞到區塊鏈上,或進行某種外部計算并將結果傳遞給智能合約。在基于DEX或AMM的預言機機制的情況下,預言機提取的數據源是由DEX上一次成功交易調整的儲備金價格,它可能會與資產的更廣泛的市場價格不同步,例如,在流動性不足的情況下進行大額交易。這將導致價格與所有交易所的成交量加權平均價格相比,要么升得很高(大額買單),要么降得很低(大額賣單)。
閃電貸加劇了這個問題,因為它允許任何用戶在沒有任何抵押的情況下獲得大量的臨時資金,以執行大額交易。用戶經常把問題歸咎于閃電貸,并稱其為“閃電貸攻擊”。然而,根本問題是,DEX本身就是不安全的價格預言機,因為現貨價格很容易被操縱,會導致依賴該預言機的協議參考了不準確的價格。這些攻擊更準確的描述是 “預言機操縱攻擊”,在DeFi生態系統中有大量的此類漏洞。所有的開發者都應該在他們的智能合約中刪除預言機操縱攻擊面。
讓我們看看最近一次攻擊的代碼,這次攻擊造成了3000萬美元的損失,隨后該協議的獎勵通證的價格下跌:
為了便于理解,該函數被稍作修改,但實際上效果是相同的。
Casa聯合創始人:比特幣在M1貨幣供應量方面距全球前十大貨幣僅有20%的差距:2月13日,加密貨幣托管公司Casa聯合創始人兼CTO Jameson Lopp發推稱:“就M1貨幣供應量而言,比特幣距離成為全球前十大貨幣只有20%的差距,距離成為全球前五大貨幣也只有10倍的差距。”[2021/2/13 19:39:08]
該協議有一個從DEX中獲取現貨價格的預言機設置。在DEX中,用戶可以將一對代幣存入流動性池合約(如通證A+通證B),允許用戶根據匯率在這些通證之間進行交換,匯率由池中每一方的流動性數量計算。假設該協議是安全的,因為其大部分代碼是Uniswap的協議的分叉。然而,在上面添加了一個獎勵通證項目,這樣當用戶將流動性存入特定的資金池時,他們不僅獲得一個收據通證(LP 通證),代表他們對自己流動性的取回憑證和礦池費用的百分比,而且還能獲得流動性挖礦獎勵。黑客能夠操縱這個獎勵的鑄造函數,通過閃電貸,并將這些額外的資金存入流動池。這使他們能夠以錯誤的匯率鑄造獎勵通證。
在這個函數中,我們可以看到,攻擊者做的第一件事就是根據流動池中兩種資產的儲備量,獲得流動性池中資產之間的匯率。下面這行代碼被調用以獲得流動性池中的儲備:
你可以想象一個有5個WETH和10個DAI的流動性池子會使reserve0為5,reserve1為10。WETH代表“封裝的ETH”,它是ETH的ERC20版本,ETH和WETH之間的匯率為1比1。
一旦你有了協議中的儲備量,獲取兩種資產的價格的簡單方法就是將兩種儲備量相除,得到一個匯率。例如,如果我們的流動資金池中有5個WETH和10個DAI,那么兌換率是1個WETH兌換2個DAI,因為我們只是用10除以5。
雖然使用去中心化的交易所可以很好地交換具有即時流動性的資產,但它們并不是很好的現貨價格預言機,因為它們的價格很容易被操縱,特別是通過閃電貸,而且DEX只占任何特定資產的總交易量的一小部分。當用于鑄造獎勵通證時,智能合約的執行很容易變得不準確(為便于理解稍作修改)。
在這個例子中,向用戶付款的主要函數是_mint(mintReward, to); 這行。我們可以看到,該函數是根據用戶在流動池中鎖定的價值多少來鑄造的。因此,如果一個用戶突然在流動池中擁有大量的資產(由于閃電貸的攻擊),那么該用戶可以很容易地給自己鑄造大量的獎勵通證,這是從該通證的用戶那里偷取獎勵。
然而,這仍然不會給他們帶來他們想要的利潤。而當通證價格預言機被操縱時,他們能得到的通證數量會大大增加。比如說,該協議認為它將給用戶5美元的獎勵--但實際它將發出5000美元的獎勵。這正是這個特定漏洞所發生的情況。
在這種設置下,用戶可以很容易地進行閃電貸,將該臨時資金存入流動池的一方,鑄造大量的獎勵,然后償還閃電貸,犧牲其他流動性提供者以獲利。
為了避免閃電貸市場操縱問題,一種常被提起的解決方案是采取DEX市場的時間加權平均價格(TWAP)(例如,一個資產在一小時內的平均價格)。雖然這可以防止閃電貸歪曲預言機價格,因為閃電貸只存在于一個交易/區塊中,而TWAP是多個區塊的平均值,但這并不是一個完整的解決方案,因為TWAP有其自身的權衡。在波動時期,TWAP預言機會變得不準確,這可能會導致下游事件,如無法在足夠的時間內清償抵押不足的貸款。此外,TWAP預言機不能提供足夠的市場覆蓋,因為只有一個DEX被跟蹤,使其容易受到不同交易所的流動性/交易量變化的影響,使TWAP預言機給出的價格出現偏差。
解決方案:使用一個去中心化的預言機網絡
DeFi安全最佳實踐不是使用一個中心化的預言機(如一個單一的鏈上交易所)來確定匯率,而是使用一個去中心化的預言機網絡來尋找反映廣泛市場覆蓋的匯率的真實數值。DEX作為交易所是去中心化的,但作為價格參考信息它是中心化的。
相反,你要收集所有中心化和去中心化交易所的價格,按交易量加權并去除異常值,能夠獲得相關資產的全球匯率的去中心化且準確的視圖,這能確保全面的市場覆蓋。如果你有代表所有交易環境的成交量加權的全球平均值的資產價格,如果閃電貸操縱了單一交易所的資產價格,那也就無所謂了。
2個區塊鏈崗位位列十大新興職業 月薪可達7-10萬:人社部在今年5月份新增十大新興職業,分別是區塊鏈工程技術人員、區塊鏈應用操作員、社區網格員、互聯網營銷師、信息安全測試員、核酸檢測員、老年健康評估師、在線學習服務師、社群健康助理員、增材制造(3D打印)設備操作員,其中區塊鏈相關崗位占到2席,央視頻信息顯示,這些崗位在北上廣起薪是1-2萬,資歷深的從業人員,月薪可以達到7-10萬。[2020/7/30]
此外,由于閃電貸只存在于單個交易中(同步),它們對去中心化的Price Feed沒有影響,這些Price Feed在單獨的事務中生成具有廣泛市場范圍定價的預言機更新(異步更新)。Chainlink預言機網絡的去中心化架構和它們實現的廣泛的市場覆蓋保護了DeFi協議免受閃電貸資助的市場操縱,這就是為什么越來越多的DeFi項目正在整合Chainlink Price Feed以防止價格預言機的攻擊,并確保在突然的交易量變化中準確定價。
你可以不用getReserves來計算價格,而是從Chainlink Data Feed獲得轉換率,這是去中心化的預言機網絡在鏈上提供反映所有相關CEX和DEX的成交量加權平均價格(VWAP)。
上面的代碼是實現訪問Chainlink價格預言機的全部內容,你可以閱讀文檔,開始在你的應用程序中實現它們。如果你是智能合約或預言機的新手,我們有一個初學者教程幫助你開始使用,并保護你的協議和用戶免受閃電貸和預言機操縱攻擊。
如果你想了解更多并實際體驗,可以玩一下OpenZeppelin的DEX Ethernaut關卡,它顯示了操縱DEX的現貨價格是多么容易。
3不要使用Keccak256或Blockhash作為隨機性的來源
使用block.difficulty、block.timestamp、blockhash或任何與block相關的東西來獲得一個隨機數到你的應用程序中,都會使你的代碼被攻擊。智能合約中的隨機性對許多用例都是有用的,比如在無偏見的情況下確定獎勵的贏家,或者公平地將一個罕見的NFT分配給用戶。然而,區塊鏈是確定的系統,不能提供隨機數的防篡改來源,所以試圖從鏈上獲得一個隨機數總是會出現問題,并有可能導致被漏洞利用。隨機數漏洞并不像預言機操縱攻擊或重入攻擊那樣普遍,但它們在Solidity教學資料中出現的頻率令人震驚。很多教育內容會教導區塊鏈開發者用下面這樣的代碼獲得一個隨機數:
這里的想法是使用nonce、區塊難度和時間戳的某種組合來創建一個“隨機”數字。然而這有幾個明顯的缺點。
實際上,你可以用取消交易不斷地“回滾”,直到你得到一個你喜歡的隨機數字。這對任何人來說都非常容易做到。
使用對block.difficity這樣對象的哈希值(或者鏈上的任何其他東西)作為隨機數時,礦工對結果有巨大的影響力。與“回滾”策略類似,如果結果對礦工不利,礦工可以利用他們交易排序的能力,將某些交易從區塊中排除。如果這是用于隨機性的鏈上數據的來源,礦工也可以選擇扣留對他們不利的區塊哈希的區塊。
使用block.timestamp這樣的東西則無隨機性,因為時間戳是任何人都可以預測的。
這種方式的鏈上隨機數生成器,用戶和/或礦工都能對“隨機”數字產生影響和控制。如果你想擁有的是一個公平系統,這種方式的隨機性只會極度有利于惡意行為者。隨著被隨機性功能保障的價值的增加,這個問題會變得更糟,因為攻擊它的動機也在增加。
解決方案:使用Chainlink VRF作為一個可驗證的隨機性預言機
為了防止漏洞,開發者需要一種方法來創建可驗證的隨機性,并防止礦工和回滾用戶的篡改。所需要的是來自于預言機的鏈外隨機性。然而,許多提供隨機性來源的預言機沒有辦法真正證明他們提供的數字確實是隨機產生的(被操縱的隨機性看起來就像正常的隨機性,你無法區分)。開發者需要能夠從鏈外獲取隨機性,同時也要有辦法明確地、并且可通過密碼學證明隨機性沒有被操縱。
動態 | 數字資產管理公司CoinShares公布2019十大加密趨勢:據Bitcoinist今日報道,數字資產管理公司CoinShares公布了2019十大加密趨勢:1. 宏觀趨勢正在為比特幣創造條件;2. 炒作已經過渡到成熟;3.從消費者轉向機構;4. 從分散到集中;5. 最大的ico未能達到預期;6. 加密幣快速擴張;7. 首次國家發行;8. 科技希望進入金融業;9. 密碼衍生工具火了;10. 盡管人們對接受加密的興趣逐漸減弱,但接受人數仍在上升。[2019/11/13]
Chainlink可驗證隨機函數(VRF)正是實現了這一點。它使用預言機節點在鏈外生成一個隨機數,并提供該數字的完整性的加密證明。然后由VRF協調器在鏈上檢查該加密證明,以驗證VRF的完整性是確定且防篡改的。它的工作流程如下:
一個用戶從Chainlink節點請求一個隨機數,并提供一個種子值(使用最新的VRF不需要用戶提供種子值)。這會發出一個鏈上事件日志。
鏈外的Chainlink預言機讀取該日志并使用可驗證的隨機函數(VRF)創建一個隨機數和密碼學證明,依據的是節點的keyhash、用戶給定的種子和請求時未知的區塊數據。然后,它在第二筆交易中把隨機數返回鏈上,并在鏈上通過VRF協調器合約使用該密碼學證明驗證此隨機數。
Chainlink VRF是如何解決上述問題的呢?
你不能回滾攻擊
由于這個過程需要兩筆交易,第二筆交易是創建隨機數的地方,你無法看到隨機數或取消你的交易。
礦工沒有影響力
由于Chainlink VRF不使用礦工可以控制的值,如block.difficulty或block.timestamp等可預測的值,所以他們無法控制隨機數。
用戶、預言機節點或dApp開發者無法操縱Chainlink VRF提供的隨機性數值,這就使得Chainlink VRF提供的隨機性數值是智能合約應用程序可用的極其安全的鏈上隨機性來源。
你可以按照文檔的要求開始在你的代碼中實現Chainlink VRF,或者按照我們的初學者指南來使用Chainlink VRF,其中包括一個視頻教程。
4避免常見故障
這一點是對Solidity的一個概括,但要有一個安全的合約,你需要在構建它時將所有的DeFi安全原則銘記于心。要寫出真正可靠的Solidity代碼,你必須知道它在底層是如何工作的。否則,你可能會受到影響:
上溢出/下溢出
在Solidity中,uint256和int256是“封裝”的。這就是說,如果你有一個uint256能表示的最大的數字,然后再對它加1,它將會得到它能表示的最小的數字。請務必檢查這一點。在0.8之前的Solidity版本中,你會使用類似safemath的東西。
在Solidity 0.8.x中,算術運算被默認檢查。這意味著x + y在溢出時將拋出一個異常。所以請確保你知道你使用的是什么版本!
循環的gas限制
當編寫動態大小的循環時,需要非常小心它們能有多大。一個循環可以很容易地超過區塊的最大gas限制,并在恢復時使得合約無用。
避免使用tx.origin
tx.origin不應該被用于智能合約的授權,因為它可能會導致類似釣魚的攻擊。
代理存儲碰撞
對于一個采用代理實現模式的項目,實現合約可以通過改變代理合約中的實現合約地址來更新。
通常,在代理合約中,有一個特定的變量來存儲實現合約的地址。如果這個變量的存儲位置是固定的,而恰好有另一個變量在實現合約中的存儲位置有相同的索引/偏移,那么就會出現存儲碰撞。
為了觸發存儲碰撞,可以在Remix中遵循下面這些步驟:
部署實現合約;
部署代理合約,將實現合約的部署地址作為其構造函數參數;
在代理合約的部署地址上運行實現合約;
動態 | 日本安全審計協會調查:“虛擬貨幣盜竊”關注度位列十大趨勢第一位:據jasa.jp消息,據日本安全審計協會做的2019年信息安全十大趨勢報告顯示,“虛擬貨幣被盜、欺詐事件增長”位列關注趨勢第一位。[2019/1/8]
調用myAddress()函數。它將返回一個非零的地址,這就是存儲在代理合約中的otherContractAddress變量中的部署地址。
那么,在上面的四個步驟中發生了什么呢?
首先實施合約被部署,生成了合約地址;
代理合約部署時用到實現合約的部署地址,其中代理合約的構造器被調用,otherContractAddress變量用實現合約的部署地址賦值;
在步驟3中,實現合約與代理存儲進行交互,即在部署的實現合約中的變量可以讀取部署的代理合約中相應的哈希碰撞變量的值。
myAddress可以通過碰撞讀取otherContractAddress的
4.myAddress()函數的返回值只是部署的實現合約中的myAddress變量的值,它與部署的代理合約中的otherContractAddress變量相碰撞,可以在那里獲得otherContractAddress變量的值。
為了避免代理存儲碰撞,我們建議開發者為存儲變量選擇偽隨機槽來實現非結構化的存儲代理。
一種常見的做法是為項目采用一個可靠的代理模式。最廣泛采用的代理模式是通用可升級代理標準(UUPS)和透明代理模式。它們都提供了具體的存儲偏移offset,以避免在代理合約和實現合約中使用相同的存儲槽。
下面是一個使用透明代理模式實現隨機存儲的例子:
通證轉移計算的準確性
通常情況下,對于一個普通的ERC20通證,收到的通證數量應該等于用函數調用的原始數量;例如,下面的函數retrieveTokens()。
然而如果通證是通縮的,即每次轉讓都有費用,那么實際收到的通證數量將少于最初要求轉讓的通證數量。
在下面修改后的函數retrieveTokens(address sender, uint256 amount)中,金額是根據轉移操作前后的余額重新計算的。無論通證轉移機制如何,這都能準確地計算出已經轉移到address(this)的通證數量。
正確的數據刪除
有很多情況下需要刪除合約中不再需要的某個對象或值。在像Java這樣的成熟語言中,有一個垃圾回收機制,可以自動和安全地處理這個問題。然而在Solidity中,開發者必須手動處理“垃圾”。因此,不正確地處理垃圾可能給智能合約帶來安全問題。
例如,當用delete刪除數組中的一個元素時,即delete array[member],array[member]仍然存在,但會根據array[member]的類型重置為一個默認值。開發者應該記得跳過這個元素或者重新組織數組并減少其長度。比如說:
這些只是需要注意的一些漏洞,但深入了解Solidity將幫助你避免這些“麻煩”。你可以查看審計工程師Sigma Prime關于常見Solidity漏洞的文章:https://blog.sigmaprime.io/solidity-security.html
5函數的可見性和限制
在Solidity語言的設計中,有四種類型的函數可見性:
private:該函數只在當前合約中可見;
internal:該函數在當前合約和派生合約中是可見的;
external:該函數只對外部調用可見;
public:該函數對內部和外部調用都是可見的。
函數可見性是指上述四種可見性中的一種,用于限制某組用戶的訪問。至于限制,它指的是專門為訪問限制目的而編寫的自定義代碼段。
可見性和限制可以結合起來,為特定的功能設置一個適當的訪問授權。例如,在ERC20實現的函數_mint()中:
函數_mint()的可見性被設置為internal,這正確地保護了它不能被外部調用。為了給mint函數設置一個適當的訪問授權,可以使用下面的代碼片段:
函數mint()只允許合約的所有者進行鑄造,require()語句防止所有者鑄造過多的通證。
正確使用可見性和限制有利于合約管理。也就是說,一方面缺乏這樣的設置可能會讓惡意攻擊者調用管理配置功能來操縱項目,另一方面,過度的限制設置可能會給合約帶來中心化的擔憂,也可能會引起社區的質疑。
6在部署到主網前做好外部審計
可以將代碼審計視為以安全為中心的同行評審。審計員將逐行檢查你的整個代碼庫,并使用形式化驗證技術來檢查你的智能合約是否存在任何漏洞。在沒有審計的情況下部署代碼或在審計后更改代碼并重新部署是會讓合約暴露于潛在漏洞的威脅。
有多種方法可以幫助你和審計員確保代碼審計盡可能全面:
使用文檔記錄所有內容,以便他們更輕松地跟蹤正在發生的事情
與他們保持溝通渠道暢通,以防他們有任何疑問
在你的代碼中添加注釋,會讓你的團隊和他們的團隊更容易
然而,不要依賴審計人員來捕捉一切問題。你應該首先有一個安全心智模型,因為在未來某一天,如果你的協議被黑客攻擊,你仍然會是那個最終負責的團隊。安全審計不一定能解決所有問題,但它們確實提供了額外的一輪審查,對捕捉你沒有發現的錯誤有一定幫助。
Tincho有一個關于如何最好地與審計工程師合作的很好的推特內容。
如果你想找推薦的審計工程師,請隨時聯系我們的技術專家。
7進行測試和使用靜態分析工具
你需要對你的應用程序進行測試。人類是偉大的,但他們永遠無法提供自動化測試套件所能提供的代碼覆蓋率。Chainlink的入門套件倉庫有一些測試套件的樣本供你參考作為起點。像Aave和Synthetix這樣的協議也有很好的測試套件,查看他們的代碼了解一些測試的最佳實踐(也包括更通用的編碼實踐)可能是一個好的思路。
靜態分析工具也能幫助你更早地發現錯誤。它們被設計成自動運行你的合約并尋找潛在的漏洞。目前最流行的靜態分析工具之一是Slither。CertiK目前也在根據其在審計、驗證和監控智能合約方面的豐富經驗,建立下一代靜態分析、語法分析、漏洞分析和形式化驗證工具。
8將安全視為整個生命周期的工作
雖然毫無疑問你應該盡力在產品部署前創建一個安全可靠的智能合約,但現實是區塊鏈和DeFi協議快速發展以及新攻擊的不斷發明意味著你不能止步于此。相反,你應該獲取并跟蹤最新的監測和警報情報。如果可能的話,嘗試在智能合約中引入面向未來的功能,以獲取快速增長的動態安全情報并從中受益。
同時也可以引入一些額外的幫助。CertiK Skynet作為一個24/7的安全智能引擎,為智能合約的鏈上部署提供多維度和實時的透明安全監控。它包括社會情緒、治理、市場波動、安全評估等,為區塊鏈客戶、社區和通證投資者提供一般的安全理解。CertiK安全排行榜提供透明的、易于理解的安全洞察和最新的項目狀態,并提供獎勵改進的社區問責制。
9制定一個災難恢復計劃
根據你的協議,如果你被黑客攻擊,有一個救助計劃是很好的。一些流行的方法是:
購買保險
添加一個緊急“暫停”功能
有一個升級計劃
保險協議越來越受歡迎,這是是最去中心化的災難恢復方式之一。它們在不影響去中心化的情況下增加了一定程度的財務安全。即使你也有其他災難恢復計劃,你也應該持有保險。一種解決方案是CertiK的ShentuShield,這是一個增加了去中心化和透明度的保險產品。
設置緊急“暫停”功能是一個有利有弊的策略。在發現漏洞的情況下,這種功能會停止與你的智能合約的所有交互。如果你設置了這個功能,你需要確保你的用戶知道誰能夠操作它。如果只有一個用戶擁有權限,這就不是一個去中心化的協議,并且精明的用戶可以通過你的代碼找到答案。要小心你的實現方式,因為你實際上可能最終在一個去中心化的平臺上得到一個中心化的協議。
升級計劃也有同樣的問題。轉移到一個沒有錯誤的智能合約可能很好,但你需要以一種深思熟慮的方式升級你的合約,以免犧牲去中心化。一些安全公司甚至強烈建議不要采用可升級的智能合約模式。你可以在這篇《智能合約升級現狀》的演講中或者Patrick Collins關于這個話題的YouTube視頻中了解更多關于可升級智能合約的話題。
如果你正在尋找一些保險建議,可隨時加入Chainlink Discord。
10防范搶跑交易
在區塊鏈中,所有的交易在mempool中都是可見的,這意味著每個人都有機會看到你的交易,并有可能在你的交易進行之前進行交易,以便從你的交易中獲利。
例如,假設你使用DEX以當前的市場價格將5個ETH兌換成DAI。一旦你將交易發送到mempool進行處理,一個搶跑者可以在你之前進行交易,購買大量的ETH,導致價格上漲。然后他們可以以更高的價格向你出售他們購買的ETH,并以你為代價獲利。目前,搶跑機器人在區塊鏈世界中橫行,并以犧牲普通用戶的利益為代價獲利。這個術語來自于傳統的金融世界,其中交易員試圖做完全相同的事情,只是涉及的是股票、商品、衍生品和其他金融資產和相應的工具。
另一個例子,下面列出的函數有很高的被搶跑的風險。根據修改器initializer,該函數只能被調用一次。如果調用initialize()函數的交易被攻擊者在mempool中監控,那么攻擊者就可以用一組定制的通證(token)、分銷商(distributor)和工廠(factory)的參數來復制該交易,并最終控制整個合約。由于函數initialize()只能被調用一次,合約所有者沒有辦法防御或減輕這種攻擊。
這通常也與所謂的礦工可提取價值,即MEV有關。MEV是指礦工或機器人對交易進行重新排序,以便他們能以某種方式從排序中獲利。就像搶跑者支付更多的gas以使他們的交易領先于你的交易一樣,礦工可以直接重新排序交易,使他們的交易領先于你的交易。在整個區塊鏈生態系統中,MEV每天從普通用戶那里竊取數百萬美元。
幸運的是,包括Chainlink實驗室首席科學家Ari Juels在內的一群世界級智能合約和密碼學研究人員正在努力解決這個確切的問題,其解決方案名為“公平排序服務”(FSS)。
開發中的解決方案:Chainlink公平排序服務(FSS)
Chainlink 2.0白皮書概述了公平排序服務的主要特點,這是一項由Chainlink去中心化預言機網絡(DON)提供的安全的鏈外服務,將用于根據dApp陳述的公平性的時間概念對交易進行排序(例如首次在mempool中看到)。FSS旨在極大地緩解搶跑交易和MEV的影響,并為整個區塊鏈生態系統的用戶減少交易費用。你可以在這篇介紹性的文章中閱讀更多關于FSS的內容,并在Chainlink 2.0白皮書的第五節中查看擴展內容。
除了FSS之外,緩解搶跑問題的最好方法之一是盡可能降低交易排序的重要性,從而抑制交易重新排序和MEV在你的協議中的作用。
總結和下一步工作
在保護你的智能合約時,有許多關鍵的DeFi安全因素需要考慮,我們已經看到了太多的漏洞和攻擊使用戶損失了數千萬美元。掌握上面的提示將幫助你在構建智能合約時避免這些漏洞。然而,永遠不會有一個列表涵蓋每一個獨特的漏洞。我們會繼續看到圍繞中心化機制的新的和復雜形式的經濟漏洞,以及圍繞脆弱的抵押品的閃電貸資助的市場操縱。DeFi社區必須共同努力,在整個生態系統中發現并減輕這些新出現的風險。
通過參考CertiK安全排行榜等列出的頂級項目學習圍繞安全智能合約開發的最佳實踐,是提高項目安全性的一個有益方法。智能合約的世界是開放和協作的,開發者們希望盡其所能相互幫助。
你可能會發現回顧以前的一些漏洞的價值,并將其作為了解過去如何進行攻擊的手段。你還可以通過CertiK Skynet等24/7安全情報服務,實時接收最新的鏈上安全漏洞的更新并從中學習。
對于那些想要深入了解安全并將整個過程游戲化的人來說,一定要看看Ethernaut游戲。它包含了DeFi的安全實例,深入淺出教你Solidity的許多來龍去脈,它是了解DeFi中一切安全問題的好方法。另一個學習安全的游戲化項目是Damn Vulnerable DeFi。你也可以在“防止閃電貸攻擊”網站上了解更多關于閃電貸攻擊的信息。
作為一個社區,讓我們從錯誤中學習,以確保智能合約被安全地構建并盡可能廣泛地采用。要了解更多關于如何實現這里提到的一些解決方案,請前往Chainlink文檔和CertiK文檔閱讀。
Tags:ChainCHAHAIAINPEPECHAIN幣Chain Estate DAOluckchainEXRNchain
北京時間12月16日凌晨三點,美聯儲公布12月貨幣政策委員會決議聲明,為了支持在較長時期內實現充分就業和2%的通貨膨脹率的目標,委員會決定將聯邦基金利率的目標范圍保持在0-0.25%不變.
1900/1/1 0:00:001.美聯儲暗示可能會更快結束經濟支持 加密發展速度暫緩就在令人擔憂的新型冠狀病開始傳播之際,外媒消息指出,美聯儲主席表示,美聯儲可能會更快地減少對經濟的支持,這讓華爾街感到震驚.
1900/1/1 0:00:00中國人民銀行數字貨幣研究所副所長狄剛12月5日在國際金融論壇(IFF)第18屆全球年會上表示,區塊鏈技術在數字金融領域應用成果初現.
1900/1/1 0:00:0010月28日,馬克·扎克伯格宣布臉書更名為“Meta”,并稱要把旗下產品逐步整合打造一個「超越現實的元宇宙平臺」,從而使“元宇宙”一躍成為人盡皆知的熱詞.
1900/1/1 0:00:00OpenSea是最大的NFT市場,憑借先發優勢,現在每個月處理著幾十億美元的交易,幾乎處于壟斷地位。所以這也出現了很多OpenSea的挑戰者.
1900/1/1 0:00:00隨著加密貨幣市場市值已突破2萬億美元,如何監管日漸成為各國政府需要迫切面對的問題。比如,美國加密貨幣領域的一些大人物將于12月8日前往美國國會山出席聽證會.
1900/1/1 0:00:00