测试包含transferFrom
的函数时,我的代码正在还原。还原被隔离到此行,注释掉后,它运行良好。
到目前为止,我的(错误的)假设是:
from
地址或错误的Loan
合同地址?)this.Token.address
传递给createLoan
关于可能还有其他问题的任何想法?
这是我的合同
Loan.sol
pragma solidity ^0.5.0;
import "openzeppelin-solidity/contracts/math/SafeMath.sol";
import "openzeppelin-solidity/contracts/token/ERC20/ERC20.sol";
import "openzeppelin-solidity/contracts/ownership/Ownable.sol";
import "./DSmath.sol";
contract Loan is Ownable, DSMath {
...
function createLoan
(
uint _loanAmount,
uint _collateralAmount,
address _collateralAddress
)
external {
require(loaneeToDebt[msg.sender] == 0, "User already owes tokens");
require
(
isCollateralized(_loanAmount, _collateralAmount, _collateralAddress),
"Collateral posted is insufficient to receive a loan"
);
require(tokenPrices[_collateralAddress] != 0, "Collateral token not registered to system");
ERC20(_collateralAddress).transferFrom(msg.sender, address(this), _collateralAmount); //REVERTS HERE
loaneeToDebt[msg.sender] = _collateralAmount;
}
我正在
Loan.test.js
中像这样测试:// Loan.test.js
const {BN, expectEvent, shouldFail, constants} = require("openzeppelin-test-helpers");
const Loan = artifacts.require("Loan");
const ERC20Mock = artifacts.require("ERC20Mock")
contract("Loan", function ([_, contractOwner, user]) {
const initialSupply = new BN(1).mul(new BN(10).pow(new BN(28)))
beforeEach(async function () {
this.Loan = await Loan.new({from: contractOwner});
this.Token = await ERC20Mock.new(user, initialSupply)
});
describe("#createLoan", function () {
const collateralAmount = new BN(5).mul(new BN(10).pow(new BN(27)))
const loanAmount = new BN(1).mul(new BN(10).pow(new BN(24)))
const tokenPrice = new BN(1)
beforeEach(async function () {
await this.Loan.setTokenPrice(this.Token.address, tokenPrice, {from: contractOwner});
});
it("should revert if the user has an outstanding loan", async function () {
await this.Token.approve(this.Loan.address, collateralAmount, {from: user}); // APPROVAL
await this.Loan.createLoan(loanAmount, collateralAmount, this.Token.address, {from: user}) // REVERTS HERE
shouldFail.reverting(this.Loan.createLoan(loanAmount, collateralAmount, this.Token.address, {from: user});
});
});
});
用
ERC20Mock
:pragma solidity ^0.5.0;
import "openzeppelin-solidity/contracts/token/ERC20/ERC20.sol";
contract ERC20Mock is ERC20 {
constructor (address initialAccount, uint256 initialBalance) public {
_mint(initialAccount, initialBalance);
}
function mint(address account, uint256 amount) public {
_mint(account, amount);
}
function burn(address account, uint256 amount) public {
_burn(account, amount);
}
function burnFrom(address account, uint256 amount) public {
_burnFrom(account, amount);
}
}
最佳答案
为了能够进行transferFrom,需要在批准用户之前。
function approve(address spender, uint256 value) external returns (bool);
在您的情况下,消息发件人应批准与_collateralAmount相同金额的贷款合同。
您也可以使用以下功能检查一个人有多少津贴:
function allowance(address owner, address spender) external view returns (uint256);
值得在createLoan()的开头提出一个要求,以检查配额是否足够。
关于solidity - 在ERC20.transferFrom上还原,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54348232/