Мой код возвращается при тестировании функции, которая содержит 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);
}
}