Возврат на ERC20.transferFrom - PullRequest
       13

Возврат на ERC20.transferFrom

0 голосов
/ 24 января 2019

Мой код возвращается при тестировании функции, которая содержит transferFrom.Возврат изолирован на эту строку, когда он закомментирован, он работает нормально.

Мои (пока) неверные гипотезы:

  1. Ошибка выдачи токенов (неверно from)адрес или неверный Loan адрес договора?)

  2. Передача неверного 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);
    }
}

1 Ответ

0 голосов
/ 30 января 2019

Чтобы иметь возможность сделать перевод от, вам нужно прежде чем утвердить пользователя.

  function approve(address spender, uint256 value) external returns (bool);

В вашем случае договор займа должен быть утвержден отправителем сообщения на ту же сумму, что и _colficialAmount.

Вы также можете проверить размер пособия с помощью следующей функции:

  function allowance(address owner, address spender) external view returns (uint256);

Было бы целесообразно добавить в начале createLoan () требование, чтобы проверить, достаточно ли допустимого.

...