1

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?

1 Answer 1

1
require(msg.value <= 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) // or type(uint256).max/2

would work. Its unlikely someone try to send more than 5.7*10^58 ETH to your contract though x)

1
  • To address your other question, i would keep using decimals(), most tokens have 18 decimals but you never know
    – Foxxxey
    Sep 24, 2021 at 9:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.