'Transaction reverted: function selector was not recognized and there's no fallback function
I am interacting with my own smart contract. It's a very simple one.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract ERC20 {
string public name;
string public symbol;
uint8 public decimal = 18;
uint256 public totalSupply;
address internal immutable _owner;
mapping(address => uint256) internal _accounts;
mapping(address => mapping(address => uint256)) internal _allowed;
constructor(
string memory name_,
string memory symbol_,
uint256 totalSupply_
) {
_owner = msg.sender;
name = name_;
symbol = symbol_;
totalSupply = totalSupply_;
_accounts[msg.sender] = totalSupply;
}
// Events
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
// Errors
/// @notice Insufficient Funds.
error InsufficientFunds(
address account,
uint256 currentFunds,
uint256 requestedFunds
);
/// @notice Invalid Address.
error InvalidAddress(address account);
/// @notice Unauthorized.
error Unauthorized(address account);
/// @notice Not Allowed.
error NotAllowed(address owner, address spender, uint256 amount);
// Modifiers
modifier sufficientFunds(address account, uint256 amount) {
if (_accounts[account] < amount)
revert InsufficientFunds(account, _accounts[account], amount);
_;
}
modifier validAddress(address account) {
if (account == address(0)) revert InvalidAddress(account);
_;
}
modifier onlyOwner() {
if (msg.sender != _owner) revert Unauthorized(msg.sender);
_;
}
modifier allowed(address account, uint256 amount) {
if (_allowed[account][msg.sender] < amount)
revert NotAllowed(account, msg.sender, amount);
_;
}
// Functions
function balanceOf(address account_) external view returns (uint256 balance) {
balance = _accounts[account_];
}
function allowance(address owner_, address spender_)
external
view
returns (uint256 amount)
{
amount = _allowed[owner_][spender_];
}
function transfer(address to_, uint256 amount_)
external
validAddress(to_)
sufficientFunds(msg.sender, amount_)
returns (bool result)
{
_accounts[msg.sender] -= amount_;
_accounts[to_] += amount_;
emit Transfer(msg.sender, to_, amount_);
result = true;
}
function approve(address spender_, uint256 amount_)
external
validAddress(spender_)
sufficientFunds(msg.sender, amount_)
returns (bool result)
{
_allowed[msg.sender][spender_] += amount_;
emit Approval(msg.sender, spender_, amount_);
result = true;
}
function transferFrom(
address from_,
address to_,
uint256 amount_
)
external
validAddress(from_)
validAddress(to_)
allowed(from_, amount_)
sufficientFunds(from_, amount_)
returns (bool result)
{
_allowed[from_][msg.sender] -= amount_;
_accounts[from_] -= amount_;
_accounts[to_] += amount_;
emit Transfer(from_, to_, amount_);
result = true;
}
}
This contract is covered by tests and working fine. Deploying it locally however is causing the approve method to revert with this error
Error: Transaction reverted: function selector was not recognized and there's
no fallback function at ERC20.<unrecognized-selector>
Calling decimal(), symbol() or transfer() works perfectly. It's just the approve() method that is causing this problem and I cannot figure out the reason. I am using Hardhat and Ethers by the way.
deploy.ts (working)
const ERC20 = (await ethers.getContractFactory(
'ERC20'
)) as ERC20__factory;
const claimableTokens = [
await ERC20.deploy('Token 1', 'T1', toWei(1000000)),
await ERC20.deploy('Token 2', 'T2', toWei(10000)),
await ERC20.deploy('Token 3', 'T3', toWei(100)),
];
await Promise.all(claimableTokens.map((token) => token.deployed()));
await (
await claimableTokens[0].approve(witSwap.address, toWei(500000))
).wait();
blockchain.ts (not working)
const token1Contract =
new ethers.Contract(
address,
ERC20JSON.abi,
this._provider
) as ERC20;
token1Contract
.connect(this._signer)
.approve(contractAddress, token1Amount)
logging token1Contract from blockchain.ts shows the desired functions.
Any help is much appreciated!
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|