gpt4 book ai didi

solidity - 在 ERC20.transferFrom 上恢复

转载 作者:行者123 更新时间:2023-12-02 04:26:10 24 4
gpt4 key购买 nike

在测试包含 transferFrom 的函数时,我的代码正在恢复。还原被隔离到这一行,当被注释掉时,它运行正常。

到目前为止我的(错误的)假设:

  1. 发行批准代币(错误的from地址,或错误的Loan合约地址?)

  2. 将错误的 this.Token.address 传递给 createLoan

关于其他问题的任何想法?

这是我的契约(Contract) 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);

在您的情况下,贷款契约(Contract)应由消息发件人批准,金额与 _collat​​eralAmount 相同。

您还可以使用以下功能查看一个人有多少津贴:

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

在 createLoan() 的开头添加一个 require 来检查津贴是否足够是值得的。

关于solidity - 在 ERC20.transferFrom 上恢复,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54348232/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com