I don't get why it doesn't work..... the logs show that the amount is approved.... yes it's easier to just use transfer() here, but shouldn't the aprove() + transferFrom() also work?
const usdc = (await getContractAt('@openzeppelin/contracts/token/ERC20/IERC20.sol:IERC20', USDC_ADDRESS)) as unknown as IERC20;
await usdc.connect(user).approve(flashLoanReceiver.target, FEE_AMOUNT);
console.log(await usdc.allowance(user.address, flashLoanReceiver.target));
console.log(FEE_AMOUNT);
await usdc.transferFrom(user.address, flashLoanReceiver.target, FEE_AMOUNT);
Don't really use javascript to interact with contracts but might be able to point you in the right direction.
await usdc.connect(user).approve(flashLoanReceiver.target, FEE_AMOUNT);
- this approves the flashLoanReceiver
as a spender on behalf of user
await usdc.transferFrom(user.address, flashLoanReceiver.target, FEE_AMOUNT);
- but then you are trying to transferFrom
from some random account, not flashLoanReceiver
.
probably should be something like: await usdc.connect(flashLoanReceiver).transferFrom(/*...*/)
You're missing the whole point in the approve
/transferFrom
scheme, which consists of the following two transactions:
-
entity
executes tokenContract.approve(someContract)
, in order to allow someContract
to transfer funds from entity
-
entity
executes someContract.someFunc
, which internally executes tokenContract.transferFrom(entity)
in order to transfer funds from entity
to somewhere (either to someContract
itself, or to some other account)
Note that entity
can be either an externally-owned account (aka wallet), or a smart-contract account.
In your case, since you're using the approve
/transferFrom
scheme from an off-chain script, entity
has to be an externally-owned account of course.