测试包含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);
这将是值得投入所需的在创建()的开头检查津贴就足够了。