0

Essentially what I am trying to achieve is a dynamic price to be used for a erc721 contract.

The idea is to use chainlinks price aggregator to call eth/usd price and dividing a set usd value by the current cost of eth with the price feed.

Going to go through the process of how I am trying to attack it feel free to correct as needed.

I am using ChainLink price aggregator to give me Eth/USD price.

Code below:

    pragma solidity ^0.8.7;


    contract PriceConsumerV3 {

AggregatorV3Interface internal priceFeed;

/**
 * Network: Rinkeby
 * Aggregator: ETH/USD
 * Address: 0x8A753747A1Fa494EC906cE90E9f37563A8AF630e
 */
constructor() {
    priceFeed = AggregatorV3Interface(0x8A753747A1Fa494EC906cE90E9f37563A8AF630e);
}

/**
 * Returns the latest price
 */
function getLatestPrice() public view returns (int) {
    (
        /*uint80 roundID*/,
        int price,
        /*uint startedAt*/,
        /*uint timeStamp*/,
        /*uint80 answeredInRound*/
    ) = priceFeed.latestRoundData();
    return price / 10**8;
}
}

Now that I have the eth/usd price being triggered with the getlatestPrice,

I figure I can use this to be called within another contract to use the value retrieved. Queation 1: How would i set it so this value can be called in another contract. i have come across a few post going over how to call contract a into contract b, but the values used throw off my understanding what is happening. thank you for this

The other issue i have seen is that solidity does not like to display anything in decimal format. example: usd / ethvalue = x.xxx

I have come across a contract that essentially a division calculator that allows for decimal place set and seems to display the decimal value correctly.

Code Below:

   // SPDX-License-Identifier: MIT

   pragma solidity ^0.8.1;

   import "@openzeppelin/contracts/utils/Strings.sol";

   contract Division {
       using Strings for uint256;

function division(uint256 decimalPlaces, uint256 numerator, uint256 denominator) public 
    pure returns(uint256 quotient, uint256 remainder, string memory result) {
    uint256 factor = 10**decimalPlaces;
    quotient  = numerator / denominator;
    bool rounding = 2 * ((numerator * factor) % denominator) >= denominator;
    remainder = (numerator * factor / denominator) % factor;
    if (rounding) {
        remainder += 1;
    }
    result = string(abi.encodePacked(quotient.toString(), '.', numToFixedLengthStr(decimalPlaces, remainder)));
}

function numToFixedLengthStr(uint256 decimalPlaces, uint256 num) pure internal returns(string memory result) {
    bytes memory byteString;
    for (uint256 i = 0; i < decimalPlaces; i++) {
        uint256 remainder = num % 10;
        byteString = abi.encodePacked(remainder.toString(), byteString);
        num = num/10;
    }
    result = string(byteString);
}

Question 2 & 3:

Using these two contracts cant i set the usd value to be fixed in the second contract as numerator and call the first contract to fill the eth usd value which in this case would be the denominator to then display "cost in decimal format"?

Once deployed and it is giving me correct values, can i set the erc721 price to call the contract value upon mint? or is it something to be set in front end ?

I have also come across a method which states to convert the usd value into wei and use that to set the value based on eth. price conversion using chainlink ETHUSD price

Another angle of attack that came to mind would be to use an AMM to set the price as you would when you swap for tokens the front end automatically displays the tokens to be received based on the input value that would be a locked cost..

I know that there are different facets to the post but any information provided would be greatly appreciated.

Thanks ahead of time for any answers received.

Quick overview: Trying to use chainlinks price aggregator to create a dynamic price tracker based on the value set in used. this is to be used in an erc721 contract..

1 Answer 1

0

About decimal format:

Yes, Solidity doesn't use decimal format, but every token has the number of decimal places. It is used to show the decimals at the frontend, per example.

I will share with you an example where I am using the DataFeed ETHUSD to calculate the amount of tokens a user will receive when the token price is defined in USD. My token has only 2 decimal places.

// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;

import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";

contract TokenPrice {
    
    AggregatorV3Interface internal priceFeed;
    uint256 tokenPrice = 20000; //1 token = 200 usd, with 2 decimal places
    
    constructor() {
        /**
        * Network: Rinkeby
        * Aggregator: ETH/USD
        * Address: 0x8A753747A1Fa494EC906cE90E9f37563A8AF630e
        */
        priceFeed = AggregatorV3Interface(0x8A753747A1Fa494EC906cE90E9f37563A8AF630e);
    }

    /**
     * Returns the latest price
     */
    function getLatestPrice() public view returns (int) {
        (
            /*uint80 roundID*/,
            int price,
            /*uint startedAt*/,
            /*uint timeStamp*/,
            /*uint80 answeredInRound*/
        ) = priceFeed.latestRoundData();
        return price;
    }

    function tokenAmount(uint256 amountETH) public view returns (uint256) {
        //Sent amountETH, how many usd I have
        uint256 ethUsd = uint256(getLatestPrice());
        uint256 amountUSD = amountETH * ethUsd / 1000000000000000000; //ETH = 18 decimal places
        uint256 amountToken = amountUSD / tokenPrice / 10000;  //2 decimal places
        return amountToken;
    } 
   
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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