1

I have followed both answers in the following similar question. I some how cannot seem to get a non-zero result. I tried several different ways to modify the below conversion function. Using MockV3Aggregator in hardhat network, test running correctly pre-conversion. Can anyone see my problem? Thank you.

Similar question: price conversion using chainlink ETHUSD price

My code:

pragma solidity ^0.8.0;

import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol"; int256 public usdPrice; // set to 10 in the constructor

...

function getLatestPrice() public view returns (int256) {
    (, int256 answer, , , ) = s_priceFeed.latestRoundData();
    // ETH/USD rate in 18 digit
    return answer;
}
function conversion() public view returns (int) {
    int minRequiredUSD = usdPrice * 10 ** 18;
    int ethPriceUSD = getLatestPrice() * 10 ** 18;
    int minRequiredEther = (minRequiredUSD * 10 ** 18) / ethPriceUSD;
    return minRequiredEther;
}
//different attempt lowering division down to a seperate step and etc as to try not to return zero
function conversionOne() public view returns (int) {
    int answer = getLatestPrice();
    int ethPriceUSDAdj = answer * 10 ** 18;
    int minRequiredUSD = usdPrice * 10 ** 18;
    int minRequiredEther = minRequiredUSD * 10 ** 18;
    int minRequiredEtherDivided = minRequiredEther / ethPriceUSDAdj;
    return minRequiredEtherDivided;
}

//different attempt from one of the other recommended answers
function conversionTwo() public view returns (int) {
    int _price = getLatestPrice() / 10 ** 8
    int minRequiredEtherDivided = usdPrice / _price;
    return minRequiredEtherDivided;
}

//function that uses the conversion function:
function makePayment(address _account, int256 _periods) public payable {
        int conversionPrice = conversion();
        int priceInEth = conversionPrice * _periods;
        require(int(msg.value) >= priceInEth, "not enough ether submitted");
        epochPaid[_account] = epoch + _periods;
}



My test running correctly to know I am returning the correct mock oracle price:

                  it("It should return the same value as the mock", async () => {
                      const { Subscription, mockV3Aggregator } = await loadFixture(
                          deployContractAndPrice
                      )
                      const priceConsumerResult = await Subscription.getLatestPrice()
                      const priceFeedResult = (await mockV3Aggregator.latestRoundData()).answer
                      assert.equal(priceConsumerResult.toString(), priceFeedResult.toString())
                  })
Stackaccount1
  • 168
  • 10

2 Answers2

0

I believe this may be the answer as if the returned value was alreadty multiplied by *10**18 you remove it from the first conversion() like:

    function getLatestPrice() public view returns (int256) {
        (, int256 answer, , , ) = s_priceFeed.latestRoundData();
        // ETH/USD rate in 18 digit
        return answer;
    }
function conversion() public view returns (int256) {
    int256 minRequiredUSD = usdPrice * 10 ** 18;
    int256 ethPriceUSD = getLatestPrice();
    int256 minRequiredEther = (minRequiredUSD * 10 ** 18) / ethPriceUSD;
    return minRequiredEther;
}

Stackaccount1
  • 168
  • 10
0

In Chainlink data feed, if returned data is xx/USD, the answer is multiplied by 10 ** 8 like BTC/USD(see price by calling function latestRoundData in etherscan UI).

If the returned data is xx/ETH, the answer is multiplied by 10 ** 18 like BTC/ETH(see price by calling function latestRoundData in etherscan UI).

Frank Kong
  • 645
  • 1
  • 6
  • 16