Solidity
ERC2981 版稅四捨五入問題
我最近一直在開發一個實現 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 個)。在這種情況下,值的最後一位並不那麼重要,這就是人們通常向下取整的原因。