# price conversion using chainlink ETHUSD price

I'm storing a product's USD value in contract. `mapping (string => uint256) productUSD;`

For example, if it's \$52 I'd store it as `productUSD[_product] = 52;`

Now, when people paying in ETH, I want to make sure they sent in a correct converted amount.

i.e. `0.013 ETH`

Chainlink's `getThePrice()` returns the latest `ETH/USD` price and found it was returning like this. `price = 348365740274`

``````    function getThePrice() public view returns (int) {
(
uint80 roundID,
int price,
uint startedAt,
uint timeStamp,
) = priceFeed.latestRoundData();
return price;
}
``````

Simple math, I can drop 8 decimals from `348365740274` and use `3483` to get a converted ETH amount

i.e. `52 / 3483 = 0.0149296583405111 ETH`

1. how do I calculate this in solidity? not sure how to drop decimals from `348365740274`
2. how do I verify user has sent correct eth amount? i.e. `require(msg.value >= ...)`

As far as chainlink price feeds are concerned, ETH pairs (USD/ETH, AAVE/ETH, UNI/ETH, etc.) have 18 decimals while non-ETH pairs (ETH/USD, etc.) have 8 decimals. Source

solidity integer division automatically rounds off towards 0.(Docs Reference), so you can do `price/10**8` to get rounded off integer for dividend representing 8 decimals.

To verify the value sent with the transaction is greater than some threshold when ETH compared with USD, you would divide the minimum required value in USD with USD per ETH, for e.g:

``````int min_required = 50; // minimum required in USD
int _price = getThePrice() / 10 ** 8; // price of 1 ether in USD

require(msg.value >= min_required / _price, "NOT ENOUGH ETHER");
``````

you can omit using variables to save gas and use values directly, this is just for a clearer explanation.

If you are using a solidity compiler version less than 0.8.x then use SafeMath to take care of integer overflow and underflow

• awesome thanks! May 11, 2021 at 20:29

No, I don't think hack3r_Om's solution works. Consider my example:

• The ether price in USD is 2000 dollars. So the pricefeed will give you 2000*10**8.
• Now if you divide the returned value by 10**8, you will get 2000.
• Your min_required is 50 dollars, if you convert that 50 dollars to ether by 50/2000, solidity will give you zero because it don't like decimal. Which means the

`require(msg.value >= min_required / _price, "NOT ENOUGH ETHER"); `

will never fails, because 50/2000 = 0 in solidity.

My solution is, according to PatrickAlpha's tutorial, you have to multiply your min_required and the pricefeed returned value to some number before dividing, so that it will not be rounded. This is my example contract:

``````contract Test{
uint256 minRequiredUSD;
uint256 etherPriceUSD;
uint256 public minRequiredEther;

constructor() {
minRequiredUSD = 50*10**18; // multiply your minRequired to 10**18
etherPriceUSD = 2000*10**18; // multiply your etherPrice to 10**18

// this means (50*10*18)/2000, it converts your minReqiredEther to wei first
// before divide. The result is 25*10**15 wei.
minRequiredEther = (minRequiredUSD*10**18)/etherPriceUSD;
}