DeclarationError: Undeclared identifier error when using sendValue()

Hi, I am currently working on my own project, but my compile fails due to a declaration error with the sendValue() function within Address.sol.

Here is the code handling the inheritance and constructor of my contract:

pragma solidity ^0.8.0;

// This is an open source for the ERC721 Token Standard
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
import "@openzeppelin/contracts/utils/Address.sol"; 

contract nftSmartContract is ERC721 {
    using Counters for Counters.Counter;
    using Address for address;

    Counters.Counter private _tokenIdTracker;
    string private _baseTokenURI;
    bool lock = false;

    event Sent(address indexed payee, uint256 amount, uint256 balance);
    event Received(address indexed payer, uint tokenId, uint256 amount, uint256 balance);

    constructor(string memory name, string memory symbol, string memory baseTokenURI) ERC721(name, symbol) {
        _baseTokenURI = baseTokenURI;
    }

Here is the function that calls the sendValue() function:

    //gets called in the tokenSale() function
    //sends the eth from the buyer to the seller, with commission held within this contract
    function salePayout(
        address payable _payee, 
        uint256 _value
    ) 
        internal 
    {
        require(_payee != address(0) && _payee != address(this), "the person you are trying to payout to is the '0' address or this address");
        require(_value > 0 && _value <= address(this).balance, "there is not enough eth in this contract to send to the payee");
        require(!lock, "function is currently locked, failing due to potential re-entry attack");
        lock = true;

        sendValue(_payee, _value);
        emit Sent(_payee, _value, address(this).balance);

        lock = false;
    }

Here is the compile error I am receiving:

DeclarationError: Undeclared identifier.
  --> /C/Users/Brend/Documents/Programming/SpaceForce/ContractService/SmartContract/contracts/nftSmartContract.sol:79:9:
   |
79 |         sendValue(_payee, _value);
   |

I have imported Address.sol into my contract, so I am unsure as to why it is unable to see the function.

Any help or guidance is appreciated!

Library functions are not visible in the global namespace. You need to qualify the call with the library name:

Address.sendValue(_payee, _value);

Since you have using Address for address there you can alternatively use the function as a member of the address type:

_payee.sendValue(_value);

But this will only work if the using statement is in the same contract that contains salePayout(). using statements are not inherited from base contract (at least in recent Solidity versions).

3 Likes

Thank you! That seems to take away the error. Now I am able to call the function, but it does not actually send the ether.

The code for sendValue() is:

    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        // solhint-disable-next-line avoid-low-level-calls, avoid-call-value
        (bool success, ) = recipient.call{ value: amount }("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

For context, I am calling salePayout() as the contract to move ether from the contract to the _payee. for example, I am calling Address.sendValue(_payee, 1) After calling the salePayout() function, the state of the contract does not seem to change. I would expect to see either “Address: insufficient balance” or “Address: unable to send value, recipient may have reverted” if it fails, but I receive neither of these messages, but both balances stay the same.

Assuming the contracts balance is 3 ether and the account I am sending the ether to, _payee, has a balance of 0 eth before calling the function, the balances stay the same after the function is called as well. Any thoughts on why it may not be sending the eth?

1 Like

Is _payee actually a contract? If it's not the call will succeed but do nothing. The high level calls have a protection against that but you're using the low-level call which does not.

Units and global variables > Members of address type:

Due to the fact that the EVM considers a call to a non-existing contract to always succeed, Solidity includes an extra check using the extcodesize opcode when performing external calls. This ensures that the contract that is about to be called either actually exists (it contains code) or an exception is raised.

The low-level calls which operate on addresses rather than contract instances (i.e. .call() , .delegatecall() , .staticcall() , .send() and .transfer() ) do not include this check, which makes them cheaper in terms of gas but also less safe.

1 Like

So _payee is actually intended to be a person’s wallet address. So in this case, I won’t be able to use the sendValue() function, as it requires the recipient to be the address of a contract and I will need to use something like .transfer()?

1 Like

Sorry, what I said was not entirely correct. I think your call() should still successfully send the ether even if it “does nothing”, i.e. does not actually call any function on the other side when it’s an EOA.

So another possible cause - are you sure that the balance of _payee after the operation is exactly 0? You’re sending a very small fraction of an ether (1 means one wei; for one ether you need to use 1 ether or 10**18) so maybe it actually works but the UI you’re using to view the balance rounds that down and shows you zero?

1 Like

Hey sir , can u help me to solve this error

The error message is similar but your problem is completely unrelated to this thread. It would have been better to create a new one.

Also, please read How do I ask a good question? before posting, especially this part:

  • DO NOT post images of code, data, error messages, etc. - copy or type the text into the question. Please reserve the use of images for diagrams or demonstrating rendering bugs, things that are impossible to describe accurately via text. For more information please see the Meta FAQ entry Why not upload images of code/errors when asking a question?

As to your problem, the screenshot is a bit hard to read but it looks like the issue is exactly what the compiler is telling you: you have not declared prime and pwc anywhere. Were they meant to be the constructor parameters?

And you have one more bug in there, though this one does not result in an error: you're assigning the values to name and symbol which are constructor parameters. This has no effect on the state of the contract. You probably meant _name and _symbol state variables?

2 Likes

Thnks issue is solved I don't put double inverted commas dats why it's showing error .

Fixed my error for where I knew a function came from. Thanks! Would not have known that.
But question. What if we dont know where a function came from?
I have no idea where "lastBoughtTime" comes from. Is there a way to search this or do I need to go through every include and check manually?
Thanks!

DeclarationError: Undeclared identifier.
--> project:/contracts/DEAI.sol:90:23:
|
90 | require(now - lastBoughtTime[_buyer] >= lockTime, "You have to wait to buy token");

Well, the compiler says you it cannot find a declaration of anything called lastBoughtTime so it obviously can't tell you where it comes from. It might be misspelled or you might have forgotten to inherit from some contract.

right.
But I have about 15 includes.
Is there a trick or short cut to figure out where I need to inherit it from? or is it a manual job of checking every file?

Just use search in your editor. But why are you using lastBoughtTime if you do not even know what contract it comes from or what it is?

Our dapp developer died in a car accident (or something. we cannot find the guy or his next of kin) and we are trying to put the pieces together.

Well. I went through every include and that function does not exist. So that partially explains.
I wonder if he was planning to write a library or if he forgot to include a library?

Oh, sorry to hear that. In any case such problems are usually trivial to solve with some knowledge of the code. Without it it might be tedious but a search feature should help.

Well. I went through every include and that function does not exist. So that partially explains.
I wonder if he was planning to write a library or if he forgot to include a library?

It does not look like a function. I think it's a state variable.

Thanks Cameel.

Does Open Zeppelin have a search feature for individual functions?

Like if I want a function that stores the time for when somebody bought the token, how would I know where to look?

ya. I think you are right.

modifier saleIsOpen(address _buyer) {

        require(now - lastBoughtTime[_buyer] >= lockTime, "You have to wait to buy token");

        require( totalSoldCount >= lockSoldCount, "Not enough tokens left");

        require( now - deployTime >= lockPastTime,"Sales is locked!");

        ///Price is readhed check!!!!

        _;

    }

    modifier sellIsOpen(address _seller) {

        if( _seller == corporateAddress ) _;

        if( finishedIDO == 1 ) _;

    }

The OZ repo has a search feature but I tried it and there's nothing with that particular name. And the name sounds like something very specific to a sale contract so I'd expect it to be something in your code, not a library. Unless you're using a library specifically to implement the sale contract.

1 Like

I remember him talking about using chainlink to access external data. I found a file, IAggregator.sol and it seems incomplete.

// SPDX-License-Identifier: UNLICENSED

// Calls data from outside the blockchain

pragma solidity 0.8.6;

interface IAggregator {

  function latestAnswer() external view returns (int256);

    function latestRoundData()

        external

        view

    returns (

        uint80 roundId,

        int256 answer,

        uint256 startedAt,

        uint256 updatedAt,

        uint80 answeredInRound

    );

}