Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

updates the ERC20Service function to return rawbalance as a decimal string and adds nft market place #97

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions packages/sdk/contracts/nft/ILIQ_ERC721_Market_Place.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
//SPDX-License-Identifier: MIT
pragma solidity 0.8.19;

interface ILiqERC721MarketPlace {
struct TokenInfo {
bool sellable;
uint price;
}

error NotTokenOwner();
error NotSellable();
error InsufficientPayment();
error InsufficientBalance();

event TokenUpdated(uint indexed nftTokenId, uint indexed price, bool indexed sellable);

event TokenSold(
address indexed seller,
address indexed buyer,
uint indexed nftTokenId,
address paymentToken,
uint amount,
uint time
);

event TokenCreatorTipped(
address indexed seller,
address indexed tipper,
uint indexed nftTokenId,
address paymentToken,
uint amount,
uint time
);

function safeMint(string memory uri, uint price, bool sellable) external;

function setPrice(uint nftTokenId, uint price) external;

function setSellable(uint nftTokenId, bool sellable) external;

function buyNft(
uint nftTokenId,
uint newPrice,
bool sellable,
uint payment
) external;


function setTokenInfo(uint nftTokenId, uint price, bool sellable) external;
}
152 changes: 152 additions & 0 deletions packages/sdk/contracts/nft/LIQ_ERC721_Market_Place.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;

import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/interfaces/IERC20.sol";
import "@openzeppelin/contracts/interfaces/IERC20.sol";
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/security/Pausable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
import "./ILIQ_ERC721_Market_Place.sol";

contract LiqERC721MarketPlace is ILiqERC721MarketPlace, ERC721, ERC721URIStorage, Pausable, Ownable, ERC721Burnable {
using Counters for Counters.Counter;
uint platformFee; // 100 is same as 1%, 1000 is same as 0.1%
address feeCollector;
address public paymentToken;
mapping(uint => TokenInfo) public tokensInfo;

Counters.Counter private _tokenIdCounter;

modifier onlyTokenOwner(uint nftTokenId) {
if (ownerOf(nftTokenId) != msg.sender) revert NotTokenOwner();
_;
}
modifier onlySellableToken(uint nftTokenId) {
if (!tokensInfo[nftTokenId].sellable) revert NotSellable();
_;
}

mapping(uint => uint) totalTipsByTokenID;

constructor(string memory tokenName, string memory tokenSymbol, uint _platformFee, address _feeCollector, address _paymentToken) ERC721(tokenName, tokenSymbol) {
platformFee = _platformFee;
feeCollector = _feeCollector;
paymentToken = _paymentToken;
}

function pause() public onlyOwner {
_pause();
}

function unpause() public onlyOwner {
_unpause();
}

function safeMint(string memory uri, uint price, bool sellable) public {
uint256 tokenID = _tokenIdCounter.current();
_tokenIdCounter.increment();
_safeMint(_msgSender(), tokenID);
_setTokenURI(tokenID, uri);

// Approve this contract as an operator
approve(address(this), tokenID);

TokenInfo storage TokenInfo = tokensInfo[tokenID];
TokenInfo.sellable = sellable;
TokenInfo.price = price;
}

function _beforeTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize)
internal
whenNotPaused
override
{
super._beforeTokenTransfer(from, to, tokenId, batchSize);
}

// The following functions are overrides required by Solidity.

function _burn(uint256 tokenId) internal override(ERC721, ERC721URIStorage) {
super._burn(tokenId);
}

function tokenURI(uint256 tokenId)
public
view
override(ERC721, ERC721URIStorage)
returns (string memory)
{
return super.tokenURI(tokenId);
}

function tipCreator(uint tokenID, uint amount) public onlyOwner {
address seller = ownerOf(tokenID);

if (IERC20(paymentToken).balanceOf(_msgSender()) < amount) revert InsufficientBalance();

uint fee = amount / platformFee;
SafeERC20.safeTransferFrom(IERC20(paymentToken), _msgSender(), feeCollector, fee);
SafeERC20.safeTransferFrom(IERC20(paymentToken), _msgSender(), seller, amount - fee);


emit TokenCreatorTipped(seller, msg.sender, tokenID, paymentToken, amount, block.timestamp);
}

function setPrice(uint nftTokenId, uint price) external onlyTokenOwner(nftTokenId) {
TokenInfo storage tokenInfo = tokensInfo[nftTokenId];
tokenInfo.price = price;

emit TokenUpdated(nftTokenId, price, tokenInfo.sellable);
}

function setSellable(uint nftTokenId, bool sellable) external onlyTokenOwner(nftTokenId) {
TokenInfo storage tokenInfo = tokensInfo[nftTokenId];
tokenInfo.sellable = sellable;

emit TokenUpdated(nftTokenId, tokenInfo.price, sellable);
}

function setTokenInfo(uint nftTokenId, uint price, bool sellable) public onlyTokenOwner(nftTokenId) {
TokenInfo storage tokenInfo = tokensInfo[nftTokenId];
tokenInfo.price = price;
tokenInfo.sellable = sellable;

emit TokenUpdated(nftTokenId, price, tokenInfo.sellable);
}

function buyNft(
uint nftTokenId,
uint newPrice,
bool sellable,
uint payment
) external onlySellableToken(nftTokenId) {
address seller = ownerOf(nftTokenId);

uint tokenPrice = tokensInfo[nftTokenId].price;
if (IERC20(paymentToken).balanceOf(_msgSender()) < tokenPrice) revert InsufficientBalance();
if(payment < tokenPrice) revert InsufficientPayment();

this.safeTransferFrom(seller, _msgSender(), nftTokenId);

setTokenInfo(nftTokenId, newPrice, sellable);

uint fee = tokenPrice / platformFee;
SafeERC20.safeTransferFrom(IERC20(paymentToken), _msgSender(), feeCollector, fee);
SafeERC20.safeTransferFrom(IERC20(paymentToken), _msgSender(), seller, payment - fee);


emit TokenSold(seller, msg.sender, nftTokenId, paymentToken, tokenPrice, block.timestamp);
}

function setFeeCollector(address _feeCollector) public onlyOwner {
feeCollector = _feeCollector;
}

function setPlatformFee(uint _platformFee) public onlyOwner {
platformFee = _platformFee;
}
}
168 changes: 168 additions & 0 deletions packages/sdk/contracts/nft/LIQ_ERC721_Market_Place_Meta.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;

import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/interfaces/IERC20.sol";
import "@openzeppelin/contracts/interfaces/IERC20.sol";
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/security/Pausable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
import "@opengsn/contracts/src/ERC2771Recipient.sol";
import "./ILIQ_ERC721_Market_Place.sol";

contract LiqERC721MarketPlaceMeta is ILiqERC721MarketPlace, ERC2771Recipient, ERC721, ERC721URIStorage, Pausable, Ownable, ERC721Burnable {
using Counters for Counters.Counter;
uint platformFee; // 100 is same as 1%, 1000 is same as 0.1%
address feeCollector;
address public paymentToken;
mapping(uint => TokenInfo) public tokensInfo;

Counters.Counter private _tokenIdCounter;

modifier onlyTokenOwner(uint nftTokenId) {
if (ownerOf(nftTokenId) != msg.sender) revert NotTokenOwner();
_;
}
modifier onlySellableToken(uint nftTokenId) {
if (!tokensInfo[nftTokenId].sellable) revert NotSellable();
_;
}

mapping(uint => uint) totalTipsByTokenID;

constructor(string memory tokenName, string memory tokenSymbol, uint _platformFee, address _feeCollector, address _paymentToken, address _trustedForwarder) ERC721(tokenName, tokenSymbol) {
platformFee = _platformFee;
feeCollector = _feeCollector;
paymentToken = _paymentToken;

_setTrustedForwarder(_trustedForwarder);
}

function pause() public onlyOwner {
_pause();
}

function unpause() public onlyOwner {
_unpause();
}

function safeMint(string memory uri, uint price, bool sellable) public {
uint256 tokenID = _tokenIdCounter.current();
_tokenIdCounter.increment();
_safeMint(_msgSender(), tokenID);
_setTokenURI(tokenID, uri);

// Approve this contract as an operator
approve(address(this), tokenID);

TokenInfo storage TokenInfo = tokensInfo[tokenID];
TokenInfo.sellable = sellable;
TokenInfo.price = price;
}

function _beforeTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize)
internal
whenNotPaused
override
{
super._beforeTokenTransfer(from, to, tokenId, batchSize);
}

// The following functions are overrides required by Solidity.

function _burn(uint256 tokenId) internal override(ERC721, ERC721URIStorage) {
super._burn(tokenId);
}

function tokenURI(uint256 tokenId)
public
view
override(ERC721, ERC721URIStorage)
returns (string memory)
{
return super.tokenURI(tokenId);
}

function tipCreator(uint tokenID, uint amount) public onlyOwner {
address seller = ownerOf(tokenID);

if (IERC20(paymentToken).balanceOf(_msgSender()) < amount) revert InsufficientBalance();

uint fee = amount / platformFee;
SafeERC20.safeTransferFrom(IERC20(paymentToken), _msgSender(), feeCollector, fee);
SafeERC20.safeTransferFrom(IERC20(paymentToken), _msgSender(), seller, amount - fee);


emit TokenCreatorTipped(seller, msg.sender, tokenID, paymentToken, amount, block.timestamp);
}

function setPrice(uint nftTokenId, uint price) external onlyTokenOwner(nftTokenId) {
TokenInfo storage tokenInfo = tokensInfo[nftTokenId];
tokenInfo.price = price;

emit TokenUpdated(nftTokenId, price, tokenInfo.sellable);
}

function setSellable(uint nftTokenId, bool sellable) external onlyTokenOwner(nftTokenId) {
TokenInfo storage tokenInfo = tokensInfo[nftTokenId];
tokenInfo.sellable = sellable;

emit TokenUpdated(nftTokenId, tokenInfo.price, sellable);
}

function setTokenInfo(uint nftTokenId, uint price, bool sellable) public onlyTokenOwner(nftTokenId) {
TokenInfo storage tokenInfo = tokensInfo[nftTokenId];
tokenInfo.price = price;
tokenInfo.sellable = sellable;

emit TokenUpdated(nftTokenId, price, tokenInfo.sellable);
}

function buyNft(
uint nftTokenId,
uint newPrice,
bool sellable,
uint payment
) external onlySellableToken(nftTokenId) {
address seller = ownerOf(nftTokenId);

uint tokenPrice = tokensInfo[nftTokenId].price;
if (IERC20(paymentToken).balanceOf(_msgSender()) < tokenPrice) revert InsufficientBalance();
if(payment < tokenPrice) revert InsufficientPayment();

this.safeTransferFrom(seller, _msgSender(), nftTokenId);

setTokenInfo(nftTokenId, newPrice, sellable);

uint fee = tokenPrice / platformFee;
SafeERC20.safeTransferFrom(IERC20(paymentToken), _msgSender(), feeCollector, fee);
SafeERC20.safeTransferFrom(IERC20(paymentToken), _msgSender(), seller, payment - fee);


emit TokenSold(seller, msg.sender, nftTokenId, paymentToken, tokenPrice, block.timestamp);
}

function setTrustedForwarder(address _trustedForwarder) public onlyOwner {
_setTrustedForwarder(_trustedForwarder);
}

function setFeeCollector(address _feeCollector) public onlyOwner {
feeCollector = _feeCollector;
}

function setPlatformFee(uint _platformFee) public onlyOwner {
platformFee = _platformFee;
}


function _msgSender() internal view virtual override(Context, ERC2771Recipient) returns (address sender) {
return ERC2771Recipient._msgSender();
}

function _msgData() internal view virtual override(Context, ERC2771Recipient) returns (bytes calldata) {
return ERC2771Recipient._msgData();
}
}
2 changes: 1 addition & 1 deletion packages/sdk/src/erc20/erc.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ export abstract class ERC20Service {
return {
tokenName: metadata.name,
tokenSymbol: metadata.symbol,
rawBalance: balance,
rawBalance: new BigNumber(balance!).toString(10),
formattedBalance,
};
}
Expand Down
2 changes: 1 addition & 1 deletion packages/sdk/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ export { ERC20Service } from "./erc20/erc.service"
import { TransactionService } from "./transaction/transaction.service";
import { Config } from "./common/config";
import { ERC20Service } from "./erc20/erc.service";
export { Nft721MarketPlace } from "./nft/ERC721-market-place.service";
export { NftService } from "./nft/nft.service";
export { AuthService } from "./auth/auth.service";
export { tryRegisterSW } from "./auth/tryRegisterSW";


//export * from "./auth"
export type { Nft } from "./nft/types";

Expand Down
Loading