underlying.transferFrom in compound docs guide throws this error: ProviderError: Error: Transaction reverted without a reason string hardhat
underlying.transferFrom in compound docs guide throws this error: ProviderError: Error: Transaction reverted without a reason string hardhat
我正在尝试在我正在构建的应用程序中借用复合协议。
同时在此处遵循复合文档和指南:Compound Blog Post
在本地分叉主网并模拟一个有大量 USDT 的地址后,我现在正在尝试借给复合协议。
在我的测试中,这一行 underlying.transferFrom
总是失败并出现以下错误:ProviderError: Error: Transaction reverted without a reason string
对可能是什么原因有什么建议吗?我在 compound discord 上问过,没有得到回复。
也做了很多研究,找不到类似的问题...不知道还能做什么。
下面是我的代码示例
开发环境: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;
}
}
还有要求的测试文件:
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);
});
});
});
我认为在您尝试transferFrom
之前,用户需要批准合约地址才能代表他们转账。
这些是最终的问题:
- USDT合约似乎不符合eip20标准。它不是 return 布尔值,所以我所有 erc20 合约的接口都与其功能不匹配。
我立即使用符合 eip20 标准的 DAI 进行了测试,它有效。
- 同样在某个时候,在分叉主网时,我的签名者帐户(我正在测试的帐户)没有我试图提供给 compound 的令牌(足够的 USDT)。
我正在尝试在我正在构建的应用程序中借用复合协议。
同时在此处遵循复合文档和指南:Compound Blog Post
在本地分叉主网并模拟一个有大量 USDT 的地址后,我现在正在尝试借给复合协议。
在我的测试中,这一行 underlying.transferFrom
总是失败并出现以下错误:ProviderError: Error: Transaction reverted without a reason string
对可能是什么原因有什么建议吗?我在 compound discord 上问过,没有得到回复。
也做了很多研究,找不到类似的问题...不知道还能做什么。
下面是我的代码示例
开发环境: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;
}
}
还有要求的测试文件:
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);
});
});
});
我认为在您尝试transferFrom
之前,用户需要批准合约地址才能代表他们转账。
这些是最终的问题:
- USDT合约似乎不符合eip20标准。它不是 return 布尔值,所以我所有 erc20 合约的接口都与其功能不匹配。
我立即使用符合 eip20 标准的 DAI 进行了测试,它有效。
- 同样在某个时候,在分叉主网时,我的签名者帐户(我正在测试的帐户)没有我试图提供给 compound 的令牌(足够的 USDT)。