Gas
從 uint256 到 int256 的安全轉換/轉換
我有一個小函式
getConversionRate
(),它使用AggregatorV3Interface.latestRoundData()
. 這priceFeed
是AggregatorV3Interface
在地址處使用指向 rinkeby ETH/USD 的 chainlink的實現0x8A753747A1Fa494EC906cE90E9f37563A8AF630e
(來自這裡https://docs.chain.link/docs/ethereum-addresses/)。function getConversionRate(int256 amount) public view returns (int256) { (,int256 price,,,) = priceFeed.latestRoundData(); // Fetch decimals uint8 decimals = priceFeed.decimals(); // Normalize to 18 decimal places (aka converting to WEI) price = price * int256(10 ** (18 - decimals)); // In wei int256 weiAmountInUsd = price * amount; // In ETH int256 ethAmountInUsd = weiAmountInUsd / (10 ** 18); return ethAmountInUsd; }
一直使用這個函式
int256
只是因為它也可以用來轉換正值或負值。然後我試著用這個
getConvertionRate()
似乎msg.value
是uint256
。function fund() public payable { int256 minimumUSD = 50; int256 minimumETH = minimumUSD * 10 ** 18; // Hidden bug HERE uint256 -> int256 require(getConversionRate(int256(msg.value)) >= minimumETH); addressToAmountFunded[msg.sender] += msg.value; }
這裡有一個隱藏的錯誤,因為 if
msg.value
位於int256
. 該值將轉換為負整數。(我不想要那個)。我的問題是,如何處理這種情況?
decimals()
並行問題:我使用該函式對聚合器返回的值中的小數位進行了一些處理。這太複雜/太貴了嗎?我是否應該始終相信具有相同數量的小數並對轉換小數位進行硬編碼?這種方法的主要缺點是什麼?
require(msg.value <= 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) // or type(uint256).max/2
會工作。不太可能有人試圖向你的合約發送超過 5.7*10^58 ETH,儘管 x)