I'm trying to lend to the compound protocol in an App I'm building.
Also following the compound doc & guide here: Compound Blog Post
After forking the mainnet locally and impersonating an address with large USDT, I'm now trying to lend to the compound protocol.
In my test, this line underlying.transferFrom
always fails with this error: ProviderError: Error: Transaction reverted without a reason string
Any suggestions on what could be the reason? I've asked on the compound discord, and gotten no reply.
Also done lots of research, couldn't find a similar issue... don't know what else to do.
Below is a sample of my code
Dev Environment: Hardhat
OS: Windows 10
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "hardhat/console.sol";
import "../interfaces/ICompound.sol";
contract CompoundController {
mapping(address => mapping(address => UserInvestedTokenDetails))
public UserInvestments;
struct UserInvestedTokenDetails {
uint256 tokenAmount;
bool isExists;
}
function _setUserInvestments(
address userAddress,
address tokenAddress,
uint256 tokenAmount
) internal {
if (UserInvestments[userAddress][tokenAddress].isExists) {
UserInvestments[userAddress][tokenAddress]
.tokenAmount += tokenAmount;
} else {
UserInvestments[userAddress][
tokenAddress
] = UserInvestedTokenDetails(tokenAmount, true);
}
}
function supplyErc20ToCompound(
address _erc20,
address _cErc20,
uint256 tokenAmount
) public returns (bool) {
console.log("contract!");
// Token being supplied to compound
Erc20 underlying = Erc20(_erc20);
// Token sent from compound in return
CErc20 cToken = CErc20(_cErc20);
require(
underlying.transferFrom(msg.sender, address(this), tokenAmount),
"compound: transferring tokens from user failed!"
);
underlying.approve(_cErc20, tokenAmount);
require(cToken.mint(tokenAmount) == 0, "compound: mint failed!");
_setUserInvestments(msg.sender, _erc20, tokenAmount);
return true;
}
}
Also the test file as requested:
const { expect } = require("chai");
const { BigNumber } = require("ethers");
const { ethers } = require("hardhat");
const DAI = process.env.DAI;
const USDT = process.env.USDT;
//
const cDAI = process.env.DAI;
const cUSDT = process.env.CUSDT;
const USDT_WHALE = process.env.USDT_WHALE;
describe("CompoundController", function () {
before(async () => {
[deployer, user1, user2] = await ethers.getSigners();
CompoundController = await ethers.getContractFactory("CompoundController");
compoundController = await CompoundController.deploy();
// FUND USERS ACCOUNT WITH PAYMENT OPTIONs TOKEN
Usdt = await ethers.getContractAt("IERC20", USDT);
Dai = await ethers.getContractAt("IERC20", DAI);
});
describe("sendErc20", function () {
it("should supply tokens to compound", async () => {
let depositAmount = BigNumber.from("100000000000000000000"); // 100
await hre.network.provider.request({
method: "hardhat_impersonateAccount",
params: [USDT_WHALE],
});
const signer = await ethers.getSigner(USDT_WHALE);
await Usdt.connect(signer).approve(
compoundController.address,
depositAmount
);
let tx = await compoundController
.connect(signer)
.supplyErc20ToCompound(USDT, cUSDT, depositAmount);
console.log(tx);
});
});
});
These were the issues, ultimately:
Immediately I tested with DAI which was eip20 compliant, it worked.