0

Hello Stack Exchange community! I am currently working on a project that involves an NFT contract called DynamicSvgNft. The contract is designed to change the SVG image URI of the NFT based on a price feed from Chainlink. However, I am facing an issue where the getHighSVG() and getLowSVG() functions are returning mixed-up values.
Here is the relevant code for the contract:

// DynamicSvgNft.sol

         contract DynamicSvgNft is ERC721, Ownable {
     uint256 private s_tokenCounter;
     string private s_lowImageURI;
     string private s_highImageURI;
     AggregatorV3Interface internal immutable i_priceFeed;
 
     mapping (uint256 => int256) private s_tokenToHighValue;
 
     event CreatedNft(uint256 indexed tokenId, int256 highValue);
 
     constructor(address priceFeedAddress, string memory lowSvg, string memory highSvg) ERC721("Dynamic SVG NFT", "DSN") {
         s_tokenCounter = 0;
         i_priceFeed = AggregatorV3Interface(priceFeedAddress);
         s_lowImageURI = svgToImageUri(lowSvg);
         s_highImageURI = svgToImageUri(highSvg);
 
     }
 
     // functionalities
     
     function mintNft(int256 highValue) public {
         _safeMint(msg.sender, s_tokenCounter);
         s_tokenToHighValue[s_tokenCounter] = highValue;
          s_tokenCounter = s_tokenCounter + 1;
         emit CreatedNft(s_tokenCounter, highValue);
     }
 
     function svgToImageUri(string memory svg) public pure returns (string memory) {
         // convert the svgs to image uris and store them in variables for later use
         string memory baseURL = "data:image/svg+xml;base64,";
         string memory svgBase64Encoded = Base64.encode(bytes(string(abi.encodePacked(svg))));
         return string(abi.encodePacked(baseURL, svgBase64Encoded));
     }
 
 
     function _baseURI() internal pure override returns (string memory) {
         return "data:application/json;base64,";
     }
 
     function tokenURI(uint256 tokenId) public view override returns (string memory) {
         if(!_exists(tokenId)) {
             revert ERC721Metadata__URI_QueryFor_NonExistentToken();
         } 
 
         (, int256 price, , , ) = i_priceFeed.latestRoundData();
 
         string memory imageURI;
         if (price >= s_tokenToHighValue[tokenId]) {
               imageURI = s_highImageURI;
         } else {
              imageURI = s_lowImageURI;
         }
         return
             string(
             abi.encodePacked(
                 _baseURI(),
                 Base64.encode(
                     bytes(
                         abi.encodePacked(
                             '{"name":"',
                             name(),
                             '", "description":"An NFT that changes based on the chainlink feed",',
                             '"attributes": [{"trait_type": "coolness", "value": 100}], "image":"',
                             imageURI,
                             '"}'
                         )
                     )
                 )
             )
             );
     }
     function getLowSVG()  public view returns (string memory) {
         return s_lowImageURI;
     }
       function getHighSVG()  public view returns (string memory) {
         return s_highImageURI;
     }
     function getTokenCounter() public view returns (uint256 ) {
         return s_tokenCounter;
     }
     function getPriceFeed() public view returns (AggregatorV3Interface) {
         return i_priceFeed;
     }
 }

And here is the test code where the issue is being observed:

// DynamicSvgNft.test.js


//imports

const highSVGImageUri = "data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjAwIDIwMCIgd2lkdGg9IjQwMCIgIGhlaWdodD0iNDAwIiB4bWxucz0";
    const lowSVGImageUri = "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/...";
!developmentChains.includes(network.name)
  

? describe.skip
  : describe("Dynamic Svg Nft unit test", () => {
      let dynamicSvgNft, MockV3Aggregator, deployer;
      beforeEach(async () => {
        accounts = await ethers.getSigners();
        deployer = accounts[0];
        await deployments.fixture(["mocks", "dynamicsvg"]);
        dynamicSvgNft = await ethers.getContract("DynamicSvgNft");
        MockV3Aggregator = await ethers.getContract("MockV3Aggregator");
      });
    describe("Constructor", () => {
        it("sets the initial values correctly", async () => {
            const highSVG = await dynamicSvgNft.getHighSVG(); // Returns lowSVGImageUri instead of the highSVGImageUri
            const lowSVG = await dynamicSvgNft.getLowSVG();   // Returns the highSVGImageUri instead of the lowSVGImageUri
              // ... (assertions)
               console.log(`highSVG is => ${highSVG}`)
                assert.equal(highSVG, highSVGImageUri)
                console.log(`lowSVG is => ${lowSVG}`)
                assert.equal(lowSVG, lowSVGImageUri)
                assert.equal(tokenCounter.toString(), "0")
                assert.equal(priceFeed, MockV3Aggregator.address)
        });
    });
    })
    // ... (other test code)

DynamicSvgNft.deploy.js

    const { network } = require("hardhat");
    const { developmentChains, networkConfig } = require("../helper-hardhat-config");
    const { verify } = require("../utils/verify");
    const fs = require("fs")
    
    module.exports = async ({getNamedAccounts, deployments}) => {
        const {deploy, log} = deployments
        const {deployer} = await  getNamedAccounts()
    
        const chainId = network.config.chainId
        let ethUsdPriceFeedAddress
    
        if(developmentChains.includes(network.name)) {
            const EthUsdAggregator = await deployments.get("MockV3Aggregator")
            ethUsdPriceFeedAddress  = EthUsdAggregator.address
        } else {
            ethUsdPriceFeedAddress = networkConfig[chainId].ethUsdPriceFeed
        }
    
        log("#####################################");
    
        // read the nft images
        const lowSVG =  fs.readFileSync("images/dynamicNft/frown.svg", {encoding: "utf8"})
        const highSVG =  fs.readFileSync("images/dynamicNft/happy.svg", {encoding: "utf8"})
        args = [ethUsdPriceFeedAddress, highSVG, lowSVG]
    
        const dynamicSvgNft = await deploy("DynamicSvgNft", {
            from: deployer,
            args:args,
            log: true,
            waitConfirmations: network.config.blockConfirmations || 1
        })
    
        if(!developmentChains.includes(network.name) && process.env.ETHERSCAN_API_KEY) {
            log("verifying.....")
            await verify(dynamicSvgNft.address, args)
            log("verified!")
    
            log("#########################################")
        }
    
    }
    module.exports.tags = ["all", "dynamicsvg", "main"]

The issue is that the getHighSVG() function is returning the value of s_lowImageURI, and vice versa, resulting in incorrect values being returned during the test

I have thoroughly reviewed the contract and test code, but I couldn't identify the root cause of the problem. I suspect that there might be an issue with the contract deployment or the svgToImageUri function used in the contract.

Any insights or suggestions on how to debug and fix this issue would be highly appreciated! If needed, I can also provide the full code for the contract and test files.

Thank you in advance for your help!

1 Answer 1

0

Sorry for the hassle everyone, found the bug! I have already answered the question. check it out here hope this helps someone out. Cheers

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.