'I wrote a solidity that pays ERC-20 tokens for ERC-721 NFT transaction, but it doesn't work
I wrote a solidity that pays ERC-20 tokens for ERC-721 NFT transactions, but it doesn't work. On purchase, you trigger the purchaseToken method. But I get an unknown error. I'm testing it on ropsten. Can you find the problem with my solidity file? I can't solve it and I'm on the verge of dying. Please advice from seniors. please.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
import "./saleNFT.sol";
contract MintNFT is ERC721Enumerable {
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;
address owner;
// constructor
constructor() ERC721("NAME", "SYMBOL") {
owner = msg.sender;
}
SaleNFT public saleNFT;
// struct
struct tokenData {
uint256 tokenId;
string tokenURI;
uint256 tokenPrice;
}
// modifier
modifier onlyOwner {
require(msg.sender == owner, "Caller not owner");
_;
}
// mapping
mapping(uint256 => string) private _tokenURIs;
// variable
uint256 balanceLength;
function mintNftToken(string memory _tokenURI) public onlyOwner returns (uint256) {
_tokenIds.increment();
uint256 nftTokenId = _tokenIds.current();
_mint(msg.sender, nftTokenId);
_setTokenURI(nftTokenId, _tokenURI);
return nftTokenId;
}
function _setTokenURI(uint256 _tokenId, string memory _tokenURI) internal {
require(_exists(_tokenId), "ERC721Metadata: URI set of nonexistent token");
_tokenURIs[_tokenId] = _tokenURI;
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "./mintNFT.sol";
contract SaleNFT {
MintNFT public mintNftTokenAddress;
IERC20 public currencyTokenAddress;
uint256 feePercent;
address payable feeAddress;
address owner;
// constructor
constructor(address _mintNftTokenAddress, IERC20 _currencyTokenAddress, address payable _feeAddress, uint256 _feePercent) {
mintNftTokenAddress = MintNFT(_mintNftTokenAddress);
currencyTokenAddress = _currencyTokenAddress;
feeAddress = _feeAddress;
feePercent = _feePercent;
owner = msg.sender;
}
// struct
struct Trade {
uint256 item;
uint256 price;
}
// modifier
modifier onlyOwner {
require(msg.sender == owner, "Caller not owner");
_;
}
// mapping
mapping(uint256 => Trade) public trades;
// array
uint256[] public onSaleTokenArray;
function changeFee(uint256 _feePercent , address payable _feeAddress) onlyOwner external returns (bool) {
feePercent = _feePercent;
feeAddress = _feeAddress;
return true;
}
function _pay(address from, address to, uint256 amount) internal returns (bool) {
return IERC20(currencyTokenAddress).transferFrom(from, to, amount);
}
function setForSaleNft(uint256 _tokenId, uint256 _price) public {
address tokenOwner = mintNftTokenAddress.ownerOf(_tokenId);
require(tokenOwner == msg.sender, "Caller is not token owner.");
require(_price > 0, "Price is zero or lower.");
require(trades[_tokenId].price == 0, "This token is already on sale.");
require(mintNftTokenAddress.isApprovedForAll(tokenOwner, address(this)), "token owner did not approve token.");
trades[_tokenId] = Trade({
item: _tokenId,
price: _price
});
onSaleTokenArray.push(_tokenId);
}
function purchaseToken(uint256 _tokenId) external {
uint256 price = trades[_tokenId].price;
address tokenOwner = mintNftTokenAddress.ownerOf(_tokenId);
uint256 balance = currencyTokenAddress.balanceOf(msg.sender);
uint256 premium = price * feePercent / 10000;
require(price > 0, "token not sale");
require(tokenOwner != msg.sender, "Caller is token owner.");
require((balance + premium) >= price, "Lack of balance");
require(balance >= (premium + price), "Caller sent lower than price.");
require(_pay(msg.sender, tokenOwner, price), "token transfer error for owner");
mintNftTokenAddress.safeTransferFrom(tokenOwner, msg.sender, _tokenId);
require(_pay(msg.sender, feeAddress, premium), "token transfer error for feeaddress");
trades[_tokenId].price = 0;
for(uint256 i = 0; i < onSaleTokenArray.length; i++) {
if (trades[onSaleTokenArray[i]].price == 0) {
if ((onSaleTokenArray.length - 1) != i) {
onSaleTokenArray[i] = onSaleTokenArray[onSaleTokenArray.length - 1];
}
onSaleTokenArray.pop();
}
}
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|