pragma solidity ^0.8.0; abstract contract ExternalContract { function ownerOf(uint256 tokenId) public view virtual returns (address); function safeTransferFrom(address from, address to, uint256 tokenId) public virtual; function safeTransferFrom(address from, address to, uint256 tokenId, uint256 amount, bytes memory data) public virtual; function balanceOf(address owner, uint256) public virtual returns (uint256); } contract LazyMarketplace { address private _owner; uint256 private _lazyFee; mapping (bytes32 => uint) private _listPrices; address private immutable _lazyWallet = 0xa679c6154b8d4619Af9F83f0bF9a13A680e01eCf; event TokenPriceUpdated(address _contractAddress, uint256 _tokenId, uint _price); event TokenSold(address _contractAddress, uint256 _tokenId, uint _price, uint _fee); constructor(address _lazyWallet) { _owner = msg.sender; _lazyFee = 5; } // Allows a user to update the price (in WEI) of an ERC-721 token // To unlist a token, set price to 0 WEI function setPriceOf721(address _contractAddress, uint256 _tokenId, uint _newPrice) public { // make sure the caller is the owner of the token ExternalContract eContract = ExternalContract(_contractAddress); address owner = eContract.ownerOf(_tokenId); require(msg.sender == owner, "Only the owner of a token can update the list price."); bytes32 hash = generateHash(owner, _contractAddress, _tokenId); // update price _listPrices[hash] = _newPrice; emit TokenPriceUpdated(_contractAddress, _tokenId, _newPrice); } function setPriceOf1155(address _contractAddress, uint256 _tokenId, uint _newPrice) public { // make sure the caller is the owner of the token ExternalContract eContract = ExternalContract(_contractAddress); uint256 tokensHeld = eContract.balanceOf(msg.sender, _tokenId); require(tokensHeld > 0, "The caller does not hold enough tokens to sell."); bytes32 hash = generateHash(msg.sender, _contractAddress, _tokenId); // update price _listPrices[hash] = _newPrice; emit TokenPriceUpdated(_contractAddress, _tokenId, _newPrice); } // Retrieves the stored price (in WEI) of a specific NFT // If price is 0, then the token has not been listed function getPriceOf(address _walletAddress, address _contractAddress, uint256 _tokenId) public view returns (uint) { bytes32 hash = generateHash(_walletAddress, _contractAddress, _tokenId); return _listPrices[hash]; } // Allows a user to purchase an NFT in exchange for WEI function purchaseToken721(address _contractAddress, uint256 _tokenId) public payable { ExternalContract eContract = ExternalContract(_contractAddress); address tokenSeller = eContract.ownerOf(_tokenId); require(msg.sender != tokenSeller, "You already own this token."); uint listPrice = getPriceOf(tokenSeller, _contractAddress, _tokenId); require(listPrice != 0, "This token is not for sale."); require(msg.value == listPrice, "Not enough WEI sent to cover the cost of this purchase."); // pay Lazy uint lazyPayout = calculateFee(listPrice, _lazyFee); payable(_lazyWallet).transfer(lazyPayout); // pay seller uint sellerPayout = listPrice - lazyPayout; payable(tokenSeller).transfer(sellerPayout); // transfer token eContract.safeTransferFrom(tokenSeller, msg.sender, _tokenId); // reset listing price emit TokenSold(_contractAddress, _tokenId, listPrice, lazyPayout); } function purchaseToken1155(address _walletAddress, address _contractAddress, uint256 _tokenId, uint256 _amount) public payable { ExternalContract eContract = ExternalContract(_contractAddress); uint256 tokensHeld = eContract.balanceOf(_walletAddress, _tokenId); require(tokensHeld >= _amount, "The caller does not hold enough tokens to sell."); uint listPrice = getPriceOf(_walletAddress, _contractAddress, _tokenId); require(listPrice != 0, "This token is not for sale."); require(msg.value == listPrice, "Not enough WEI sent to cover the cost of this purchase."); // pay Lazy uint lazyPayout = calculateFee(listPrice, _lazyFee); payable(_lazyWallet).transfer(lazyPayout); // pay seller uint sellerPayout = listPrice - lazyPayout; payable(_walletAddress).transfer(sellerPayout); // transfer 1 token eContract.safeTransferFrom(_walletAddress, msg.sender, _tokenId, _amount, ""); emit TokenSold(_contractAddress, _tokenId, listPrice, lazyPayout); } function updateFee(uint256 _newFee) public { require(msg.sender == _owner); _lazyFee = _newFee; } function generateHash(address _walletAddress, address _contractAddress, uint256 _tokenId) public pure returns (bytes32) { return keccak256(abi.encodePacked(_walletAddress, _contractAddress, _tokenId)); } function calculateFee(uint _listPrice, uint _lazyFee) public pure returns (uint) { // assuming 5% fee return (_listPrice * _lazyFee) / 100; } }
0.4.18