I have been trying to develop my own ERC20 token on Remix as a trial. I use tree accounts for the token. First one(0x5B38Da6a701c568545dCfcB03FcB875f56beddC4) is contract owner, second one (0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2) is approved account to send token from contract owner's account, third one (0x4B20993Bc481177ec7E8f571ceCaE8A9e22C02db) is receiver.
When i run transferfrom function i get "ERC20InsufficientAllowance" error. Allowance function works normally, it shows allowance amount.
approve function works. After i approve token delegation, i can verify it.
function approve(address spender, uint256 value) public checkPaused returns (bool) {
if (spender == address(0)) {
revert ERC20InvalidSender(address(0));
}
_approve(msg.sender, spender, value);
return true;
}
function _approve(address owner, address spender, uint256 value) internal {
_allowances[owner][spender] = value;
emit Approve(owner, spender, value);
}
getAllowance function works, too.
function getAllowance(address owner, address spender) public view returns (uint256) {
return _allowances[owner][spender];
}
When i run transferfrom function i get ERC20InsufficientAllowance error. I could not understand why.
function transferFrom(address from, address to, uint256 value) public checkPaused returns (bool) {
if (from == address(0) || to == address(0)) {
revert ERC20InvalidSender(address(0));
}
if (_balances[from] < value) {
revert ERC20InsufficientBalance(msg.sender, _balances[from], value);
}
if (_allowances[from][to] < value) {
revert ERC20InsufficientAllowance(to, _allowances[from][to], value); //error
}
_spendAllowance(from, to, value);
_transfer(from, to, value);
return true;
}
function _transfer(address from, address to, uint256 value) internal {
_balances[from] -= value;
_balances[to] += value;
emit Transfer(from, to, value);
}
function _spendAllowance(address owner, address spender, uint256 value) internal {
_allowances[owner][spender] -= value;
emit SpendAllowance(owner, spender, _allowances[owner][spender] - value);
}
ERC20InsufficientAllowance
[vm]from: 0xAb8...35cb2to: ShivaToken.transferFrom(address,address,uint256) 0x80d...4BB9Bvalue: 0 weidata: 0x23b...003e8logs: 0hash: 0xd05...7a5d7
status 0x0 Transaction mined but execution failed
transaction hash 0xd0561c9e4f2195c3ab545a29e02f747ad54e28aae092ddd92a6923d49107a5d7
block hash 0x57c90613d4e65424402b0f96f97d671783bf024333cf48315f0b7b9e66082dda
block number 586
from 0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2
to ShivaToken.transferFrom(address,address,uint256) 0x80d527dF27B22d91E1AC56868e7AA5e7Ebf4BB9B
gas 3000000 gas
transaction cost 30318 gas
execution cost 8366 gas
input 0x23b...003e8
output 0xfb8f41b20000000000000000000000004b20993bc481177ec7e8f571cecae8a9e22c02db000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003e8
decoded input {
"address from": "0x5B38Da6a701c568545dCfcB03FcB875f56beddC4",
"address to": "0x4B20993Bc481177ec7E8f571ceCaE8A9e22C02db",
"uint256 value": "1000"
}
decoded output {
"0": "bool: true"
}
logs []
raw logs []
transact to ShivaToken.transferFrom errored: Error occurred: revert.
revert
The transaction has been reverted to the initial state.
Error provided by the contract:
ERC20InsufficientAllowance
Parameters:
{
"spender": {
"value": "0x4B20993Bc481177ec7E8f571ceCaE8A9e22C02db",
"documentation": "Address that may be allowed to operate on tokens without being their owner."
},
"allowance": {
"value": "0",
"documentation": "Amount of tokens a `spender` is allowed to operate with."
},
"needed": {
"value": "1000",
"documentation": "Minimum amount required to perform a transfer."
}
}
If the transaction failed for not having enough gas, try increasing the gas limit gently.
if (_allowances[from][to] < value) {
revert ERC20InsufficientAllowance(to, _allowances[from][to], value); //error
}
_spendAllowance(from, to, value);
Here you are using to
as spender, but the spender is actually msg.sender
.