I have a small function getConversionRate
() that converts a value in ETH to USD using AggregatorV3Interface.latestRoundData()
. Here priceFeed
is a implementation of AggregatorV3Interface
using chainlink pointing to rinkeby ETH/USD at address 0x8A753747A1Fa494EC906cE90E9f37563A8AF630e
(from here 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;
}
This function was kept using int256
just because it can be also used to convert both, positive or negative values.
Then I try to use this getConvertionRate()
with msg.value
that seems be 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;
}
There is a hidden bug here, since, if msg.value
is in upper half of int256
. The value will be converted to negative integers. (and I don't want that).
My question is, how to handle this case?
Parallel question: I did some handling for the decimal places in values returned from the aggregator using the decimals()
function. IS that TOO convolute/expensive? Should I trust always to have the same amount of decimals and hardcode the convertion decimal places? What are the main drawbacks in this approach?