Solidity

ERC2981 版稅四捨五入問題

  • September 7, 2022

我最近一直在開發一個實現 ERC2981 ( https://eips.ethereum.org/EIPS/eip-2981 ) 代幣標準的智能合約。

我實現的royaltyInfo功能遵守標準,按代幣收取版稅。這是功能。

function royaltyInfo(uint256 tokenId, uint256 value)
   external
   view
   override
   returns (address receiver, uint256 royaltyAmount)
{
   RoyaltyInfo memory royalties = _royalties[tokenId];
   receiver = royalties.recipient;
   royaltyAmount = (value * royalties.amount) / 10000;
}

問題是,當我有一些版稅金額時,退回的金額會四捨五入。

例如,如果一個代幣的版稅金額為 50(即 0.5% 的版稅),而value我在函式中輸入的參數是 1000,則返回 5。這是正確的值。

但是,當我輸入 100 作為value參數時,會返回 0,而 0.5 是正確的值。

無論如何要返回正確的值,同時仍然遵守 ERC2981 令牌標準?

如果沒有,是否有解決方案可以避免人們像上面的範例中那樣收不到版稅,您將如何實施?

從 EIP 中讀取:

由於前面提到的原因,使用的百分比值必須獨立於銷售價格(即如果百分比值為 10%,則無論 _salePrice 是 10、10000 還是 1234567890,都必須應用 10%)。如果版稅計算結果為餘數,實施者可以向上或向下舍入到最接近的整數。例如,如果版稅為 10%,_salePrice 為 999,則實現者可以返回 99 或 100 的值,兩者都是有效的。

所以四捨五入是可以接受的,你可以這樣做:

// return royaltyAmount rounded up
function royaltyInfo(uint256 tokenId, uint256 value)
   external
   view
   override
   returns (address receiver, uint256 royaltyAmount)
{
   RoyaltyInfo memory royalties = _royalties[tokenId];
   receiver = royalties.recipient;

   uint256 tmp = value * royalties.amount;
   if (tmp == 0) {
       royaltyAmount = 0;
   } else {
       royaltyAmount = (tmp - 1) / 10000 + 1;
   }
}

然而,一般來說,市場會使用帶有很多小數的代幣(WETH 有 18 個,USDC 有 6 個)。在這種情況下,值的最後一位並不那麼重要,這就是人們通常向下取整的原因。

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