my intent is making ERC721 token can transfer by my ERC20 token only
the transfer flow is
- Buyer approve ERC20 to Seller.
- Seller transfer ERC721 to Buyer.
- My ERC721 Token's transfer function transfer ERC20 to Seller from Buyer first, and transfer ERC721 to Buyer from Seller.
revert error occur to ERC20 transfer step.
i try to every single line delete to find revert point. and i found that.
this is my test code
const token20 = artifacts.require("MyToken20");
const token721 = artifacts.require("MyToken721");
contract("Test", async()=>{
//...
// Buyer token20 approve to Seller
it("Token20 approve", async()=>{
var value = web3.toWei(token721Price, "ether");
await contract20.approve(seller, value, {from:buyer});
var allowed = await contract20.allowance(buyer, seller);
allowed = web3.fromWei(allowed, "ether");
assert.equal(allowed, token721Price);
});
// Seller transfer token721 to Buyer
// token20 transfer to Seller inside of function transferMy721
it("Token721 transfer", async()=>{
var allowed = await contract20.allowance(buyer, seller);
allowed = web3.fromWei(allowed, "ether");
assert.equal(allowed, token721Price);
await contract721.transferMy721(buyer, token721Id, {from:seller}); // <--- revert here
var newOwner = await contract721.ownerOf(token721Id);
assert.equal(newOwner, buyer);
});
});
and revert point in my contract is here
contract MyToken721 is ERC721Token{
string public name = "My ERC721 Token Product";
string public symbol = "MTP";
mapping(uint256 => uint256) my721TokenPrice;
MyToken20 token;
constructor(MyToken20 _token) public ERC721Token(name, symbol){
require(_token != address(0));
token = _token;
}
function mint(address _to, uint256 _tokenId, uint256 _price) public {
_mint(_to, _tokenId);
my721TokenPrice[_tokenId] = _price;
}
function transferMy721(address _to, uint256 _tokenId) public returns(bool){
require(msg.sender == ownerOf(_tokenId));
uint256 tokenPrice = my721TokenPrice[_tokenId];
if( token.transferFrom(_to, msg.sender, tokenPrice) == false ) // <--- revert here
return false;
super.approve(_to, _tokenId);
super.transferFrom(msg.sender, _to, _tokenId);
return true;
}
//...
}
and revert point in ERC20 StandardToken contract is here
contract StandardToken is ERC20, BasicToken {
mapping (address => mapping (address => uint256)) internal allowed;
function transferFrom(address _from, address _to, uint256 _value)
public returns (bool)
{
require(_value <= balances[_from]);
require(_value <= allowed[_from][msg.sender]); // <--- revert here
require(_to != address(0));
balances[_from] = balances[_from].sub(_value);
balances[_to] = balances[_to].add(_value);
allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value);
emit Transfer(_from, _to, _value);
return true;
}
//...
}
as you can see, in my test code, i double check
allowed[_from][msg.sender]
please check my full code here