Q1ngying

今朝梦醒与君别,遥盼春风寄相思

0%

DeFi中的精度问题

精度问题

在 Solidity 中(直观的说针对于 以太坊 来说)是没有真正意义上带小数点的小数的,而在 Solidity 中指的小数,是:还原成传统意义上的数字,他应该是具有几位小数点

以下来自网上的描述:

传统小数到以太坊小数

  • 在传统金融中,美元金额可能表示为带有小数点的数值,例如 $100.50
  • 在以太坊智能合约中,由于不支持小数点,这个金额需要转换为一个大整数。这就是为什么将其乘以 1e18PRECISION),将美元金额转换为以太坊的标准精度格式。

举例:

以 Chainlink 预言机为例,其**”小数”**(即精度)是8位

  • 其返回值为 1234567890 时,对应现实意义中的”小数”实际上为:12.34567890

所以在 DeFi 领域中,设计到货币相关的计算时,就要严格的考虑精度问题了(即保证精度一致性)。

比如,在抵押被清算的过程中:

计算清算者需要多少 $ 来清算被清算者的抵押时,需要将 $ 转换为**”小数”**,即乘以以太坊精度(1e18),而从 chainlink 获取如今 $ 价格时,要统一精度,因为,chainlink 获得的价格为 8 位”小数”,为了统一精度,需要乘以 1e10。

代码实例:

1
2
3
4
5
6
7
8
uint256 private constant ADDITIONAL_FEED_PRECISION = 1e10;
uint256 private constant PRECISION = 1e18;
function getTokenAmountFromUsd(address token, uint256 usdAmountInWei) public view returns (uint256) {
AggregatorV3Interface priceFeed = AggregatorV3Interface(s_priceFeeds[token]);
(, int256 price,,,) = priceFeed.latestRoundData();
// 上面两行代码:从 chainlink 价格预言机中获取当前的美元价格
return (usdAmountInWei * PRECISION) / (uint256(price) * ADDITIONAL_FEED_PRECISION);
}