0

I have 2 diffrent NFT collection. They are both transparentUpgradableProxy smart contracts. I used to call another function like this before I upgraded them to transparentUpgradableProxy.

function mint(uint256 tokenId) public payable {
   IERC721 token = IERC721(mainContractAddress);
   uint256 ownedAmount = token.balanceOf(msg.sender);
   require((ownedAmount / requiredNftAmountFirstStage) - claimedAmountFirstStage[msg.sender] > 0, "You are not eligible for free NFT!");
   require(ownerOf(tokenId) == address(0), "NFT already claimed!");

   _safeMint(msg.sender, tokenId);
   claimedAmountFirstStage[msg.sender] += 1;
}

After I changed it to transparentUpgradableProxy, I tried to do it like this:

IERC721Upgradeable token = IERC721Upgradeable(mainContractAddress);
uint256 ownedAmount = token.balanceOf(msg.sender);

Im guessing this is not how it works. How can I access to another upgradable smart contracts function?

Thanks!

edit1: I cant use delegatecall because it says its unsafe. My both smart contract is upgradableProxy. I tried to do it will call, which returns bool and bytes.

    IERC721Upgradeable token = IERC721Upgradeable(mainContractAddress);
    (bool success, bytes memory result) = address(token).call(abi.encodeWithSignature("balanceOf(address)", msg.sender));
    require(success);
    uint256 ownedAmount = toUint256(result);

Still not working :( My other question is, I need to call that function from proxy smart contract right?

4
  • Yes, you will need to call that function from the proxy to use this pattern. Commented Feb 3, 2022 at 21:30
  • Can you specify what you mean by "not working"? Commented Feb 4, 2022 at 7:29
  • It says: Warning! Error encountered during contract execution [execution reverted] Commented Feb 4, 2022 at 8:54
  • Ok it worked! Thanks for poiting to right direction :) Commented Feb 4, 2022 at 10:34

2 Answers 2

1

You would use delegatecall() with encoding with a function signature:

uint256 ownedAmount = token.delegatecall(abi.encodeWithSignature("balanceOf(address)", msg.sender)

2
  • It returns bool and not uint256 (bool success, ) = address(mainContractAddress).delegatecall(abi.encodeWithSignature("balanceOf(address)", msg.sender)); require(success); Commented Feb 3, 2022 at 16:02
  • Yes, you're right, my bad. I assume that the OP wants returned value from that function. In that case, they would need to use returned bytes data: (bool success, bytes memory data) = address(mainContractAddress).delegatecall(abi.encodeWithSignature("balanceOf(address)", msg.sender)); require(success); Commented Feb 3, 2022 at 19:57
0
    (bool success, bytes memory result) = address(mainContractAddress).call(abi.encodeWithSignature("balanceOf(address)", msg.sender));
    require(success, "Failed to get balance...");
    uint256 ownedAmount = toUint256(result);

Delegatecall cant be use because of safety issues but call works fine. Im calling this from my second logic contract to main proxy address. It returns bool and bytes. Bytes can be transfromed into uint with some libraries.

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.