Web3js

使用 BigNumber.js 轉換/轉換每秒和年化利率

  • March 31, 2021

在 MakerDao 合約中,年化百分比和每秒百分比之間存在轉換。例如,他們的Stability Fees文件給出了這個例子:

如果穩定費設置為 2%,它將以每秒 1.0000000006279371924910298109948% 的速度累積。在第一年年底,使用者將欠本金 2%。

從年化格式轉換為每秒格式(反之亦然)的基本方法是這樣的,其中31536000是一年中的秒數:

1.0000000006279371924910298109948^31536000 = 2%

1.02^(1/31536000) = 1.0000000006279371924910298109948%

由於 Solidity 僅支持整數,因此可以使用定點算法在年化率和每秒率之間進行轉換。我的第一個問題:這兩個速率的整數表示是什麼(以射線為單位)?

我的下一個問題是如何使用 BigNumber.js 實用程序來轉換每秒/年化率?

我在下面的 JavaScript 程式碼不起作用。

PER_SECOND_RATE.pow(toBN(SECONDS_IN_YEAR).toString())
ANNUALIZED_RATE.pow(toBN(-SECONDS_IN_YEAR).toString())

Maker Protocol 不使用或儲存年費率,內部也沒有任何代表。

所有速率均以每秒為單位,使用RAY正常 uint256 值的數字格式,並且始終由特殊數學函式處理,例如rmul自動rdiv將最右邊的 27 個數字視為 RAY 定點數的小數部分。

所以整數表示1.02%將是 uint256 值10000000006279371924910298109948

我嘗試過使用 BN.js,但由於數字的大小和所涉及的冪運算,它對這兩種計算都不起作用。

年化到每秒的速率轉換

使用來自 javascript的命令執行此操作有一種稍微有點 hacky 的方法,這bc對我來說效果很好。

該函式的輸入是年利率。例如:5.6432% bc輸出帶小數點和小數點後 27 位的值。從輸出中刪除小數點以獲得RAY智能合約使用的格式的數字。

public async getRatePerSecond(annual: number) {
   let annRate = ((annual / 100) + 1).toFixed(4);
 
   const { stdout, stderr } = await exec(
     "bc -l <<< 'scale=27; e( l(" +
       annRate.toString() +
       ")/31557600 )'"
   );
 
   if (stderr) {
     console.error(`error: ${stderr}`);
     return;
   }
 
   let ratePerSec = BigNumber.from(
     stdout
       .toString()
       .replace(".", "")
       .replace(/(\r\n|\n|\r)/gm, "")
   );
 
   return ratePerSec;
 }

例如:getRatePerSecond(2.75)=1000000000859655594846036300

每秒到年化率的轉換

這不能回答你的問題,但我把這個 python 腳本留在這裡,供其他人尋找一種簡單的方法來做這個計算,

$ python -c "print 1.000000000627507392906712186**31557600"

1.01999999956

如果您有興趣了解更多資訊,那麼匯率機制簡介指南會介紹 Maker 協議中的匯率。

引用自:https://ethereum.stackexchange.com/questions/96452