I created the ERC20 smartcontract and presale token contract. But when I try to call the function token.isUserBlacklisted(msg.sender) from the ERC20 contract I receive the next error: TypeError: Member "isUserBlackListed" not found or not visible after argument-dependent lookup in contract IERC20. The same situation happens when I try to call function mint, addToBlacklist, removeFromBlacklist. What am I doing wrong?

The code of ERC20 contract is:

pragma solidity 0.8.20;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract SolarGreen is ERC20, ERC20Burnable, Ownable {
    mapping (address => bool) private isBlacklisted;
    event AddressBlacklisted(address indexed addr, bool isBlacklisted);

    constructor(address shop)
        ERC20("SolarGreen", "SGR")
        _mint(msg.sender, 100000000 * 10 ** decimals());

    function mint(address to, uint256 amount) public onlyOwner {
        require(amount > 0, "amount must be positive");
        _mint(to, amount);

    function addToBlacklist(address user) public onlyOwner {
        require(isBlacklisted[user] != true, "user is already in blacklist");
        require(user != address(0), "can't BL 0 address");
        isBlacklisted[user] = true;
        emit AddressBlacklisted(user, true);
    function removeFromBlacklist(address user) public onlyOwner {
        require(isBlacklisted[user] != false, "user is already removed from blacklist");
        require(user != address(0), "can't remove from BL 0 address");
        isBlacklisted[user] = false;
        emit AddressBlacklisted(user, false);

    function isUserBlacklisted(address user) public view returns (bool) {
        return isBlacklisted[user];

The code of sale token contract is:

```// SPDX-License-Identifier: UNLICENSED

pragma solidity 0.8.20;

import "./SolarGreen.sol";

contract TokenSale{
    IERC20 public token;
    address payable public owner;
    uint256 public saleStart;
    uint256 public saleEnd;
    uint256 public tokensBalanceForSale;
    bool public isUserBlacklisted;
    mapping (address => uint256) public userTokenBalances;

    event Bought(uint _amount, address indexed _buyer);

    constructor() {
        token = new SolarGreen(address(this));
        owner = payable(msg.sender);
        saleStart = block.timestamp;
        saleEnd = saleStart + 5 weeks;
        tokensBalanceForSale = token.balanceOf(address(this)) / 2;

    modifier onlyOwner() {
        require(msg.sender == owner, "not an owner");

    modifier onlyActive {
        require(block.timestamp >= saleStart, "sale must be active.");
        require(block.timestamp <= saleEnd, "sale must be active.");

   function getUserTokenBalance(address user) public view returns (uint256){
        return userTokenBalances[user];

   function changeSaleEnd (uint _newSaleEnd) public onlyOwner {
        saleEnd = _newSaleEnd;

    receive() external payable onlyActive {
        uint256 tokensForSale = msg.value / 100; // 1 token = 100 wei
        require(token.isUserBlacklisted(msg.sender) = false, "user is blacklisted");
        require(msg.sender != address(0), "zero address");
        require(msg.sender.balance >= msg.value, "not enough funds");
        require(tokensForSale > 0, "impossible to buy 0 tokens");
        require((getUserTokenBalance(msg.sender) + tokensForSale) <= 50000, "token sale limit" ); //checking the purchase limit of 50,000 tokens per one wallet
        require(tokensForSale <= tokensBalanceForSale, "not enough tokens");

        userTokenBalances[msg.sender] += tokensForSale;
        token.transfer(msg.sender, tokensForSale);
        tokensBalanceForSale -= tokensForSale;
        emit Bought(tokensForSale, msg.sender);

2 Answers 2


You're attempting to call isUserBlackListed with an uppercase L in the function name, which should be isUserBlacklisted.


It appears you're attempting to use the standard IERC20 interface, which does not include any of the custom functions you mentioned. Instead of IERC20, you should use the SolarGreen contract interface.

Change the following code:

contract TokenSale{
    IERC20 public token;


contract TokenSale{
    SolarGreen public token;
  • Thanks! Yes, you are right Commented Mar 30 at 20:55

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.