巧妙設計合約讓stETH自動獲得收益


筆者將部分ETH兌換為stETH後發現每天都有收益成長,而帳戶並未看到交易記錄。本文分享攻略設計揭露背後秘密。 stETH透過質押ETH獲取收益,用戶獲得對應stETH作為收益。 Lido將收益產生給持有stETH地址。 stETH收益每天更新,受到_handleOracleReport呼叫影響。 ERC20合約中代幣不固定在地址,透過合約方法返回。儘管質押ETH為stETH可獲穩定收益,仍存在風險。文章提供質押合約技術研究,不構成投資建議。值得一提的是之前發表的有關「再質押」的文章,讀者可深入了解。

筆者把自己為數不多的ETH兌換為stETH後,發現stETH每天都在自然成長,不斷獲得收益。但是卻沒有看到帳戶有交易,這是為什麼呢?本文帶大家一起來看看背後的攻略設計,揭開成果的秘密。

1 個stETH 在過去幾天後已經獲得了一些收益

在這之前先介紹一下stETH的流程圖背後的邏輯,以及以太坊的質押(Stake),已經了解了這部分概念的讀者可以直接跳到後面。

巧妙的合約設計,看看stETH如何自動獲得收益?

最初的以太坊和比特幣一樣是透過工作量證明(Proof of Work,PoW)來作為它因為的共識機制,但是PoW 耗電以及其他安全性和性能上發展的考慮,以太坊從2022 年9 月開始升級為權益證明(Proof of Stake,PoS)。

到底依靠算力挖礦來吸引礦工實現以太坊的思想,搖身一變,變成了依靠大家透過質押ETH獲取投票權,透過投票來獲取收益,從而激勵大家透過PoS的方式來實現共識。

透過質押32 個ETH 可以加入以太坊網絡,可以成為驗證者,負責儲存資料、處理交易以及向區塊鏈添加新區塊。只需運行將交易正確的資源為新區塊並檢查其他驗證者工作,即可獲得ETH 獎勵,這相當於你可以透過質押的方式讓ETH 可以擁有相對穩定的收益。

但是這樣的質押對於一般使用者來說還是太麻煩了,畢竟32個以太坊和一個要能夠實現最高峰無休止以太接入坊網路的專用電腦還是有一定的承載量的。而且質押ETH會造成損失了這於是產生了流動性質押衍生品(Liquid Stake Derivatives,LSD),它旨在解決傳統質押中的勞動力和流動性問題,允許用戶質押32個以下的ETH,以及不需要自己擁有節點,而是把ETH 委託給第三方質押,並獲取相應的質押代幣(如Lido 的stETH 或Rocket Pool 的rETH),這些流動性代幣可以在其他平台上交易、網絡或用於其他金融這樣,用戶既能更方便地參與質押中獲得獎勵,又能保持資金的彈性。

巧妙的合約設計,看看stETH如何自動獲得收益?

所以stETH 本質上的邏輯就是把ETH 給予Lido,Lido 會用這些ETH 去參與以太坊的PoS 來獲得收益,用戶會得到對應的stETH 作為收益。接下來就是Lido 將收益收益給予這些擁有stETH 的地址。

我們可以看到stETH的收益每天都會自動更新,下圖是我們測試的收益情況,每天的回應都可以檢查數位貨幣包驗證相關內容。

巧妙的合約設計,看看stETH如何自動獲得收益?

但到這裡我想熟悉智能合約開發的同學就會懷疑了:每天提供這麼少的收益,可能收益都不夠支付GAS 的。

確實,如果麗都採取最簡單的做法來獲得收益的話,那確實難以覆蓋GAS 的成本。從我們的直覺來看,要往如此大規模的地址發送代幣,GAS 是難以想像的。

但確實Lido 就實現了錢包中的stETH 收益自動增長,而且我們並沒有發現該地址有任何交易,這是怎麼實現的呢?

我們找到了Lido的合約https://etherscan.io/token/0xae7ab96520de3a18e5e111b5eaab095312d7fe84後續合約的balanceOf方法:

巧妙的合約設計,看看stETH如何自動獲得收益?

BalanceOf 是符合ERC20 規範的方法,而錢包就是透過該方法取得用戶有多少代幣的。

我們可以在這裡看到stETH 的合約呼叫了getPooledEthByShares該方法參與是mapping (address => uint256) private shares;這代表使用者有多少stETH?顯然不是,不然每天都需要更新每個地址的數據,雖然這樣也可以實現只需調用承諾中的方法來更新shares來實現一次交易就可以更新所有地址的代幣,但是顯然這樣做GAS 的消耗同樣也是巨大的。

想必到這裡大家已經要猜測到合約是怎麼實現的了,我們繼續看看getPooledEthByShares方法。

巧妙的合約設計,看看stETH如何自動獲得收益?

可以看到最終回傳的結果是用位址中sharesAmount 乘以_getTotalPooledEther()再除_getTotalShares。

_getTotalPooledEther代表總共有多少stETH(依照stETH 兌ETH 為1:1 的話也代表有多少ETH),_getTotalShares代表有多少貢獻。這樣算一每個位址有多少stETH就是動態計算出來的了。

舉例來說如果現在共有1000 個共享(Shares,則) _getTotalShares回傳方法的數量),其中A位址有100份(回覆上面的sharesAmount)。這1000個貢獻對應1000個stETH(大概_getTotalPooledEther回傳的數量。那麼按照這個計算,一個地址就對應有100個stETH。那Lido拿這總得1000個ETH去質押獲得到1個ETH的收益後對應更新_getTotalPooledEther 為1001,原來總共1000個stETH變成了1001個了,那麼新的計算出來一個地址就擁有了100 * 1001 / 1000 = 100.1個stETH。

簡單點說就是每個地址擁有的股份不變,股份對應的stETH變多了,那麼一計算自然stETH就變多了。

我們繼續看程式碼,_getTotalPooledEther 中的邏輯是會受到的handleOracleReport具體的呼叫是會透過https://etherscan.io/address/0x852deD011285fe67063a08005c71a85690503Cee

巧妙的合約設計,看看stETH如何自動獲得收益?

我們每天都會看到有調用更新相關內容,這就是為什麼雖然我們無法將我們的地址獲得收益的交易,但金額仍然每天在變化的原因。

這背後其實體現了以太坊但是ERC20智能合約的一個特點,就是這些ERC20的合約擁有多少代幣不是寫死地址在上面的,而是合約方法返回的,所以可能會出現帳號雖然沒有任何交易,代幣的數量也可能會改變。這一方面讓ERC20合約更加靈活,但是另一方面也給很多對合約不熟悉的朋友帶來了困惑,希望本文可以幫助大家更多的理解智能合約,更安全的和智能的交互。

另外,雖然透過將ETH 質押為stETH 能夠獲得穩定的質押收益,但仍可能存在的風險,本文僅作為質押合約的技術研究參考,不構成任何投資建議。

另外之前我們發表過一篇關於『再質押』的文章https://www.panewslab.com/zh/articledetails/789w051y.html,有興趣的讀者可以繼續閱讀,深入了解更多內容。

資訊來源:0x資訊編譯自網際網路。版權歸作者ZAN Team所有,未經許可,不得轉載

Total
0
Shares
Related Posts