I have a multi contract dapp going with a few ERC-20 tokens.
My intermediary contract that the end user owns calls a function which mints new Tokens. The Token contract itself holds these. When some later condition is met, the user then completes their action and the Tokens should be send from the contract to the user. The last item here is failing with the error that
contract Generator {
constructor(address tokenAddress) {
token = Token(tokenAddress);
}
function createUser(string calldata name) public {
User user = new User(name, token)
}
}
contract User is Ownable {
Token token;
constructor(string memory name, Token _token) {
token = _token;
}
function startAction() public {
token.mintSelf(5);
// after mintSelf resolves, etherscan shows 5 TOKEN as expected
}
function completeAction() public {
// right here is where I get the error
transferFrom(address(token), owner(), 5);
}
}
contract Token is ERC20 {
constructor() ERC20("Token", "TOKEN") {
_mint(address(this), 0);
}
function mintSelf(uint256 qty) public {
_mint(address(this), qty);
}
}
Everything goes great and I confirm Token has 5 TKN on etherscan for the first part where it calls selfMint
When I can resolve()
is when I get the error
Error: cannot estimate gas; transaction may fail or may require manual gas limit (error={"code":-32603,"message": "execution reverted: ERC20: insufficient allowance","data":{"originalError":{" code":3,"data":"0x.....000000"," message":"execution reverted: ERC20: insufficient allowance"}}}, method="estimateGas", transaction={"from":"0x...","to":"0x...","data":"0x...","accessList":null}, code=UNPREDICTABLE_GAS_LIMIT, version=providers/5.5.3)
What am I missing what account isn't funded properly?
Is this because the calling contracts don't have proper permissions to send Tokens on the contracts behalf? If so how/where would I add that in?
Or is it that it wants some contract to have ETH for gas, but none of them hold it. I want the original msg.sender to pay for all the gas.
I added another call in between to ensure it was going right and now I'm not getting an error but I'm also not getting the appropriate behavior
Instead of User.completeAction calling transferFrom
, it's calling
token.sendTo(owner(), 5);
whose implementation looks like
function sendTo(address to, uint256 qty) public {
_transfer(address(this), to, qty);
}
I'm not getting any errors now, but the token is not moving back to the User's owner! I still see it in the Token's contract on etherscan, and I don't see any transactions out :-\