还原上ERC20.transferFrom

问题描述 投票:3回答:1

测试包含transferFrom功能时,我的代码是恢复。该还原被隔离到这一行,当注释掉,它运行良好。

我的(错误的)假说至今:

  1. 发行审批令牌(错误from地址,或错误Loan合同地址?)
  2. 传递错误this.Token.addresscreateLoan

上还有什么任何想法可能是这个问题?

这里是我的合同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);
    }
}
solidity truffle
1个回答
0
投票

为了能够做一个transferFrom,你需要之前批准的用户。

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

在你的情况下,贷款合同应该由相同数量的_collat​​eralAmount消息发送者进行批准。

您还可以检查一个多少津贴有以下功能:

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

这将是值得投入所需的在创建()的开头检查津贴就足够了。

© www.soinside.com 2019 - 2024. All rights reserved.