I have been struggling to figure out this for a while and maybe someone can help? It is a bit lengthy to look through but if you have a good understanding of smart contracts and hardhat it may be easy for you. It may also be interesting if you are up for a challenge? Caveat... I don't want to use Remix to do this but rather hardhat, ethers.js, and deploy scripts.
Here is a contract (HoeToken) i already deployed and verified on etherscan. When i deployed it, i minted all the tokens to the deployer of the contract. So the tokens aren't held in the contract itself but rather the deployers address.... https://goerli.etherscan.io/address/0xA56AfB65Df413F36f9c753c2e8E56249a44AB812#code
Now here is this contract ("Bucket") that I want to interact with that was deployed by someone else. The ultimate goal is to call this "drop" function in the contract to win the challenge. But i have to transfer my ERC20 tokens on the contract above (HoeToken contact)to win the challenge... https://goerli.etherscan.io/address/0x873289a1aD6Cf024B927bd13bd183B264d274c68#code
So in order to call the "drop" function I created this contract....
pragma solidity 0.8.17;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
interface Bucket {
function drop(address erc20, uint256 amount) external;
}
contract EmitWinner {
constructor() payable {}
address hoetokenAddress = 0xA56AfB65Df413F36f9c753c2e8E56249a44AB812;
address bucketAddress = 0x873289a1aD6Cf024B927bd13bd183B264d274c68;
ERC20 erc20 = ERC20(hoetokenAddress);
mapping(address => uint) tokenOwnerBalance;
mapping (address => mapping (address => uint256)) allowed;
//Approve Emit Winner to spend hoetoken (Do this on etherscan "write" tab)
function approve(address spender, uint256 _amount) public {
erc20.approve(spender, _amount);
}
function drop(address tokenOwner, uint256 _amount) external {
bool success = ERC20(erc20).transferFrom(tokenOwner, bucketAddress, _amount);
require(success, "Transaction Failed");
Bucket(bucketAddress).drop(tokenOwner, _amount);
}
receive() external payable {}
}
So first thing I did was write deploy scripts to deploy this contract (EmitWinner) and verify it on etherscan which was done successfully.
Next i went on etherscan to the contract I just deployed above (Emit Winner), went to contract tab, then the write tab, then using metamask with the deployer address that holds the HoeTokens (initial contract at top), I called the approve function putting in the Emit Winner address and the "amount" of some HoeTokens. Works fine so far.
Now that those tokens have been approved all i need to do is call the drop function on the bucket address account to win this challenge right? And i figure i can do this inside the EmitWinner contract by writing a second script in my deploy folder. If i run this second script using hardhat (I say 2nd script because remember my first deploy script deployed the contract) it should get an instance of the Emitwinner Contract using getContractAt. Then if I use the same private key I initially deployed the contract with as the signer it should give me access to call the drop function right? So here is the second deploy scripts i am running in my terminal with hardhat....
const hre = require("hardhat");
async function main() {
const provider = await ethers.provider;
const privKey = process.env.PRIVATE_KEY;
const signer = await new ethers.Wallet(privKey, provider);
const emitwinnerInstance = await hre.ethers.getContractAt("EmitWinner", 0xcB1200d8Fe06cE2F77fb6567af2f57BB6053502D);
console.log("Invoking transferFrom and Drop Function via Drop...");
tx3 = await emitwinnerInstance.drop(signer, "1");
await tx3.wait();
console.log("Transaction:",tx3.hash);
console.log("Completed");
}
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});
This is where it fails... and says...
reason: 'invalid address or ENS name',
code: 'INVALID_ARGUMENT',
argument: 'name',
value: 1.1593266137294635e+48
Any idea what i am doing wrong and why this fails? My two guesses are... 1.)The way the deploy script is set up is not correct. Or even though the "signer" is the same address and private key as the "deployer", since i am running it off a 2nd script it won't work?
2.)Or maybe the actual drop function in my smart contract is written wrong? Is it possible it doesn't make sense the way i call transfeFrom and then.... Bucket(bucketAddress).drop(tokenOwner, _amount);
?
Can i call this by putting in the "tokenOwner" as the address after I called transferFrom?
Those are my guesses or maybe it something else? If you made this far thank you and would be eager to hear what you think the issue is? Thanks in advance for the help?