Created
May 27, 2021 13:38
-
-
Save mwaqasaslam/61601c40ac56ac01889b080a6b1e2c2f to your computer and use it in GitHub Desktop.
Created using remix-ide: Realtime Ethereum Contract Compiler and Runtime. Load this file by pasting this gists URL or ID at https://remix.ethereum.org/#version=soljson-v0.6.12+commit.27d51765.js&optimize=true&runs=200&gist=
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: MIT | |
pragma solidity 0.6.12; | |
import "https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/release-v3.3/contracts/token/ERC721/IERC721Upgradeable.sol"; | |
import 'https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/release-v3.3/contracts/math/SafeMathUpgradeable.sol'; | |
import 'https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/release-v3.3/contracts/access/OwnableUpgradeable.sol'; | |
import 'https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/release-v3.3/contracts/access/AccessControlUpgradeable.sol'; | |
import 'https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/release-v3.3/contracts/proxy/Initializable.sol'; | |
import "./IERC721CreatorRoyalty.sol"; | |
import "./IMarketplaceSettings.sol"; | |
import "./Payments.sol"; | |
contract ChimeraMarketAuctionV2 is Initializable, OwnableUpgradeable, AccessControlUpgradeable ,Payments { | |
using SafeMathUpgradeable for uint256; | |
///////////////////////////////////////////////////////////////////////// | |
// Structs | |
///////////////////////////////////////////////////////////////////////// | |
// The active bid for a given token, contains the bidder, the marketplace fee at the time of the bid, and the amount of wei placed on the token | |
struct ActiveBid { | |
address payable bidder; | |
uint8 marketplaceFee; | |
uint256 amount; | |
} | |
// The sale price for a given token containing the seller and the amount of wei to be sold for | |
struct SalePrice { | |
address payable seller; | |
uint256 amount; | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// Constants | |
///////////////////////////////////////////////////////////////////////// | |
bytes32 public constant TOKEN_COLLECTOR_ROLE = "TOKEN_COLLECTOR_ROLE"; | |
///////////////////////////////////////////////////////////////////////// | |
// State Variables | |
///////////////////////////////////////////////////////////////////////// | |
// Marketplace Settings Interface | |
IMarketplaceSettings public iMarketplaceSettings; | |
// Creator Royalty Interface | |
IERC721CreatorRoyalty public iERC721CreatorRoyalty; | |
// Mapping from ERC721 contract to mapping of tokenId to sale price. | |
mapping(address => mapping(uint256 => SalePrice)) private tokenPrices; | |
// Mapping of ERC721 contract to mapping of token ID to the current bid amount. | |
mapping(address => mapping(uint256 => ActiveBid)) private tokenCurrentBids; | |
// A minimum increase in bid amount when out bidding someone. | |
uint8 public minimumBidIncreasePercentage; // 10 = 10% | |
mapping(uint256 => bool) private TokenConfirmedByAdmin; | |
function confirmTokenByAdmin(uint256 _tokenId, address _originContract) onlyOwner external{ | |
IERC721Upgradeable erc721 = IERC721Upgradeable(_originContract); | |
address tokenOwner = erc721.ownerOf(_tokenId); | |
require(tokenOwner != address(0), "confirmTokenByAdmin: token not exists"); | |
TokenConfirmedByAdmin[_tokenId] = true; | |
} | |
function isTokenConfirmedByAdmin(uint256 _tokenId) public view returns(bool){ | |
return TokenConfirmedByAdmin[_tokenId]; | |
} | |
///////////////////////////////////////////////////////////////////////////// | |
// Events | |
///////////////////////////////////////////////////////////////////////////// | |
event Sold( | |
address indexed _originContract, | |
address indexed _buyer, | |
address indexed _seller, | |
uint256 _amount, | |
uint256 _tokenId | |
); | |
event SetSalePrice( | |
address indexed _originContract, | |
uint256 _amount, | |
uint256 _tokenId | |
); | |
event Bid( | |
address indexed _originContract, | |
address indexed _bidder, | |
uint256 _amount, | |
uint256 _tokenId | |
); | |
event AcceptBid( | |
address indexed _originContract, | |
address indexed _bidder, | |
address indexed _seller, | |
uint256 _amount, | |
uint256 _tokenId | |
); | |
event CancelBid( | |
address indexed _originContract, | |
address indexed _bidder, | |
uint256 _amount, | |
uint256 _tokenId | |
); | |
event collectorRoleGrantedTo( | |
address _collector | |
); | |
event collectorRoleRevokedTo( | |
address _collector | |
); | |
///////////////////////////////////////////////////////////////////////// | |
// initialize | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Initializes the contract setting the market settings and creator royalty interfaces. | |
* @param _iMarketSettings address to set as iMarketplaceSettings. | |
* @param _iERC721CreatorRoyalty address to set as iERC721CreatorRoyalty. | |
*/ | |
function initialize(address _iMarketSettings, address _iERC721CreatorRoyalty) public initializer { | |
require( | |
_iMarketSettings != address(0), | |
"constructor::Cannot have null address for _iMarketSettings" | |
); | |
require( | |
_iERC721CreatorRoyalty != address(0), | |
"constructor::Cannot have null address for _iERC721CreatorRoyalty" | |
); | |
__Ownable_init(); | |
__AccessControl_init(); | |
Payments.initializePayment(); | |
// Grant the contract deployer the default admin role: it will be able | |
// to grant and revoke any roles | |
_setupRole(AccessControlUpgradeable.DEFAULT_ADMIN_ROLE, owner()); | |
// Set iMarketSettings | |
iMarketplaceSettings = IMarketplaceSettings(_iMarketSettings); | |
// Set iERC721CreatorRoyalty | |
iERC721CreatorRoyalty = IERC721CreatorRoyalty(_iERC721CreatorRoyalty); | |
minimumBidIncreasePercentage = 10; | |
} | |
//Grant Role to Collectors | |
function grantCollectorRole(address _collector) onlyOwner private { | |
grantRole(TOKEN_COLLECTOR_ROLE, _collector); | |
emit collectorRoleGrantedTo(_collector); | |
} | |
//revoke roles | |
function revokeCollectorRole(address _collector) onlyOwner private{ | |
revokeRole(TOKEN_COLLECTOR_ROLE, _collector); | |
emit collectorRoleRevokedTo(_collector); | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// setIMarketplaceSettings | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Admin function to set the marketplace settings. | |
* Rules: | |
* - only owner | |
* - _address != address(0) | |
* @param _address address of the IMarketplaceSettings. | |
*/ | |
function setMarketplaceSettings(address _address) public onlyOwner { | |
require( | |
_address != address(0), | |
"setMarketplaceSettings::Cannot have null address for _iMarketSettings" | |
); | |
iMarketplaceSettings = IMarketplaceSettings(_address); | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// setIERC721CreatorRoyalty | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Admin function to set the IERC721CreatorRoyalty. | |
* Rules: | |
* - only owner | |
* - _address != address(0) | |
* @param _address address of the IERC721CreatorRoyalty. | |
*/ | |
function setIERC721CreatorRoyalty(address _address) public onlyOwner { | |
require( | |
_address != address(0), | |
"setIERC721CreatorRoyalty::Cannot have null address for _iERC721CreatorRoyalty" | |
); | |
iERC721CreatorRoyalty = IERC721CreatorRoyalty(_address); | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// setMinimumBidIncreasePercentage | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Admin function to set the minimum bid increase percentage. | |
* Rules: | |
* - only owner | |
* @param _percentage uint8 to set as the new percentage. | |
*/ | |
function setMinimumBidIncreasePercentage(uint8 _percentage) | |
public | |
onlyOwner | |
{ | |
minimumBidIncreasePercentage = _percentage; | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// Modifiers (as functions) | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Checks that the token owner is approved for the ERC721Market | |
* @param _originContract address of the contract storing the token. | |
* @param _tokenId uint256 ID of the token | |
*/ | |
function ownerMustHaveMarketplaceApproved( | |
address _originContract, | |
uint256 _tokenId | |
) internal view { | |
IERC721Upgradeable erc721 = IERC721Upgradeable(_originContract); | |
address owner = erc721.ownerOf(_tokenId); | |
require( | |
erc721.isApprovedForAll(owner, address(this)), | |
"owner must have approved contract" | |
); | |
} | |
/** | |
* @dev Checks that the token is owned by the sender | |
* @param _originContract address of the contract storing the token. | |
* @param _tokenId uint256 ID of the token | |
*/ | |
function senderMustBeTokenOwner(address _originContract, uint256 _tokenId) | |
internal | |
view | |
{ | |
IERC721Upgradeable erc721 = IERC721Upgradeable(_originContract); | |
require( | |
erc721.ownerOf(_tokenId) == msg.sender, | |
"sender must be the token owner" | |
); | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// setSalePrice | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Set the token for sale. The owner of the token must be the sender and have the marketplace approved. | |
* @param _originContract address of the contract storing the token. | |
* @param _tokenId uint256 ID of the token | |
* @param _amount uint256 wei value that the item is for sale | |
*/ | |
function setSalePrice( | |
address _originContract, | |
uint256 _tokenId, | |
uint256 _amount | |
) external { | |
// The owner of the token must have the marketplace approved | |
ownerMustHaveMarketplaceApproved(_originContract, _tokenId); | |
// The sender must be the token owner | |
senderMustBeTokenOwner(_originContract, _tokenId); | |
require(isTokenConfirmedByAdmin(_tokenId) == true, "Token not confirmed by admin to trade"); | |
if (_amount == 0) { | |
// Set not for sale and exit | |
_resetTokenPrice(_originContract, _tokenId); | |
emit SetSalePrice(_originContract, _amount, _tokenId); | |
return; | |
} | |
tokenPrices[_originContract][_tokenId] = SalePrice(msg.sender, _amount); | |
emit SetSalePrice(_originContract, _amount, _tokenId); | |
} | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Purchase the token with the expected amount. The current token owner must have the marketplace approved. | |
* @param _originContract address of the contract storing the token. | |
///////////////////////////////////////////////////////////////////////// | |
// safeBuy | |
* @param _tokenId uint256 ID of the token | |
* @param _amount uint256 wei amount expecting to purchase the token for. | |
*/ | |
function safeBuy( | |
address _originContract, | |
uint256 _tokenId, | |
uint256 _amount | |
) external payable { | |
// Make sure the tokenPrice is the expected amount | |
require( | |
tokenPrices[_originContract][_tokenId].amount == _amount, | |
"safeBuy::Purchase amount must equal expected amount" | |
); | |
buy(_originContract, _tokenId); | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// buy | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Purchases the token if it is for sale. | |
* @param _originContract address of the contract storing the token. | |
* @param _tokenId uint256 ID of the token. | |
*/ | |
function buy(address _originContract, uint256 _tokenId) public payable { | |
require(hasRole(TOKEN_COLLECTOR_ROLE, msg.sender), "You are not allowed to collect Art"); | |
// The owner of the token must have the marketplace approved | |
ownerMustHaveMarketplaceApproved(_originContract, _tokenId); | |
// Check that the person who set the price still owns the token. | |
require( | |
_priceSetterStillOwnsTheToken(_originContract, _tokenId), | |
"buy::Current token owner must be the person to have the latest price." | |
); | |
SalePrice memory sp = tokenPrices[_originContract][_tokenId]; | |
// Check that token is for sale. | |
require(sp.amount > 0, "buy::Tokens priced at 0 are not for sale."); | |
// Check that enough ether was sent. | |
require( | |
tokenPriceFeeIncluded(_originContract, _tokenId) == msg.value, | |
"buy::Must purchase the token for the correct price(buy)" | |
); | |
// Get token contract details. | |
IERC721Upgradeable erc721 = IERC721Upgradeable(_originContract); | |
address tokenOwner = erc721.ownerOf(_tokenId); | |
// Wipe the token price. | |
_resetTokenPrice(_originContract, _tokenId); | |
// Transfer token. | |
erc721.safeTransferFrom(tokenOwner, msg.sender, _tokenId); | |
// if the buyer had an existing bid, return it | |
if (_addressHasBidOnToken(msg.sender, _originContract, _tokenId)) { | |
_refundBid(_originContract, _tokenId); | |
} | |
//Made 2 types of Payments in Payments.sol Primary and secondary | |
// Payout all parties. | |
address payable owner = _makePayable(owner()); | |
if(!iMarketplaceSettings.hasERC721TokenSold(_originContract, _tokenId)){ | |
Payments.payoutPrimary( | |
sp.amount, | |
!iMarketplaceSettings.hasERC721TokenSold(_originContract, _tokenId), | |
iMarketplaceSettings.getMarketplaceFeePercentage(), | |
iERC721CreatorRoyalty.getERC721TokenRoyaltyPercentage( | |
_originContract, | |
_tokenId | |
), | |
iMarketplaceSettings.getERC721ContractPrimarySaleFeePercentage( | |
_originContract | |
), | |
_makePayable(tokenOwner), | |
owner, | |
iERC721CreatorRoyalty.tokenCreator(_originContract, _tokenId), | |
owner | |
); | |
// Set token as sold | |
iMarketplaceSettings.markERC721Token(_originContract, _tokenId, true); | |
emit Sold(_originContract, msg.sender, tokenOwner, sp.amount, _tokenId); | |
} | |
else{ | |
Payments.payoutSecondary( | |
sp.amount, | |
!iMarketplaceSettings.hasERC721TokenSold(_originContract, _tokenId), | |
iMarketplaceSettings.getMarketplaceFeePercentage(), | |
iERC721CreatorRoyalty.getERC721TokenRoyaltyPercentage( | |
_originContract, | |
_tokenId | |
), | |
iMarketplaceSettings.getERC721ContractSecondarySaleFeePercentage( | |
_originContract | |
), | |
_makePayable(tokenOwner), | |
owner, | |
iERC721CreatorRoyalty.tokenCreator(_originContract, _tokenId), | |
owner | |
); | |
// Set token as sold | |
iMarketplaceSettings.markERC721Token(_originContract, _tokenId, true); | |
emit Sold(_originContract, msg.sender, tokenOwner, sp.amount, _tokenId); | |
} | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// tokenPrice | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Gets the sale price of the token | |
* @param _originContract address of the contract storing the token. | |
* @param _tokenId uint256 ID of the token | |
* @return uint256 sale price of the token | |
*/ | |
function tokenPrice(address _originContract, uint256 _tokenId) | |
external | |
view | |
returns (uint256) | |
{ | |
// The owner of the token must have the marketplace approved | |
ownerMustHaveMarketplaceApproved(_originContract, _tokenId); // TODO: Make sure to write test to verify that this returns 0 when it fails | |
if (_priceSetterStillOwnsTheToken(_originContract, _tokenId)) { | |
return tokenPrices[_originContract][_tokenId].amount; | |
} | |
return 0; | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// tokenPriceFeeIncluded | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Gets the sale price of the token including the marketplace fee. | |
* @param _originContract address of the contract storing the token. | |
* @param _tokenId uint256 ID of the token | |
* @return uint256 sale price of the token including the fee. | |
*/ | |
function tokenPriceFeeIncluded(address _originContract, uint256 _tokenId) | |
public | |
view | |
returns (uint256) | |
{ | |
// The owner of the token must have the marketplace approved | |
ownerMustHaveMarketplaceApproved(_originContract, _tokenId); // TODO: Make sure to write test to verify that this returns 0 when it fails | |
if (_priceSetterStillOwnsTheToken(_originContract, _tokenId)) { | |
return | |
tokenPrices[_originContract][_tokenId].amount.add( | |
iMarketplaceSettings.calculateMarketplaceFee( | |
tokenPrices[_originContract][_tokenId].amount | |
) | |
); | |
} | |
return 0; | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// bid | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Bids on the token, replacing the bid if the bid is higher than the current bid. You cannot bid on a token you already own. | |
* @param _newBidAmount uint256 value in wei to bid. | |
* @param _originContract address of the contract storing the token. | |
* @param _tokenId uint256 ID of the token | |
*/ | |
function bid( | |
uint256 _newBidAmount, | |
address _originContract, | |
uint256 _tokenId | |
) external payable { | |
require(hasRole(TOKEN_COLLECTOR_ROLE, msg.sender), "You are not allowed to collect Art"); | |
// Check that bid is greater than 0. | |
require(_newBidAmount > 0, "bid::Cannot bid 0 Wei."); | |
// Check that bid is higher than previous bid | |
uint256 currentBidAmount = | |
tokenCurrentBids[_originContract][_tokenId].amount; | |
require( | |
_newBidAmount > currentBidAmount && | |
_newBidAmount >= | |
currentBidAmount.add( | |
currentBidAmount.mul(minimumBidIncreasePercentage).div(100) | |
), | |
"bid::Must place higher bid than existing bid + minimum percentage." | |
); | |
// Check that enough ether was sent. | |
uint256 requiredCost = | |
_newBidAmount.add( | |
iMarketplaceSettings.calculateMarketplaceFee(_newBidAmount) | |
); | |
require( | |
requiredCost == msg.value, | |
"bid::Must purchase the token for the correct price." | |
); | |
// Check that bidder is not owner. | |
IERC721Upgradeable erc721 = IERC721Upgradeable(_originContract); | |
address tokenOwner = erc721.ownerOf(_tokenId); | |
require(tokenOwner != msg.sender, "bid::Bidder cannot be owner."); | |
// Refund previous bidder. | |
_refundBid(_originContract, _tokenId); | |
// Set the new bid. | |
_setBid(_newBidAmount, msg.sender, _originContract, _tokenId); | |
emit Bid(_originContract, msg.sender, _newBidAmount, _tokenId); | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// safeAcceptBid | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Accept the bid on the token with the expected bid amount. | |
* @param _originContract address of the contract storing the token. | |
* @param _tokenId uint256 ID of the token | |
* @param _amount uint256 wei amount of the bid | |
*/ | |
function safeAcceptBid( | |
address _originContract, | |
uint256 _tokenId, | |
uint256 _amount | |
) external { | |
// Make sure accepting bid is the expected amount | |
require( | |
tokenCurrentBids[_originContract][_tokenId].amount == _amount, | |
"safeAcceptBid::Bid amount must equal expected amount" | |
); | |
acceptBid(_originContract, _tokenId); | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// acceptBid | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Accept the bid on the token. | |
* @param _originContract address of the contract storing the token. | |
* @param _tokenId uint256 ID of the token | |
*/ | |
function acceptBid(address _originContract, uint256 _tokenId) public { | |
// The owner of the token must have the marketplace approved | |
ownerMustHaveMarketplaceApproved(_originContract, _tokenId); | |
// The sender must be the token owner | |
senderMustBeTokenOwner(_originContract, _tokenId); | |
// Check that a bid exists. | |
require( | |
_tokenHasBid(_originContract, _tokenId), | |
"acceptBid::Cannot accept a bid when there is none." | |
); | |
// Get current bid on token | |
ActiveBid memory currentBid = | |
tokenCurrentBids[_originContract][_tokenId]; | |
// Wipe the token price and bid. | |
_resetTokenPrice(_originContract, _tokenId); | |
_resetBid(_originContract, _tokenId); | |
// Transfer token. | |
IERC721Upgradeable erc721 = IERC721Upgradeable(_originContract); | |
erc721.safeTransferFrom(msg.sender, currentBid.bidder, _tokenId); | |
// Payout all parties. | |
address payable owner = _makePayable(owner()); | |
if(!iMarketplaceSettings.hasERC721TokenSold(_originContract, _tokenId)){ | |
Payments.payoutPrimary( | |
currentBid.amount, | |
!iMarketplaceSettings.hasERC721TokenSold(_originContract, _tokenId), | |
iMarketplaceSettings.getMarketplaceFeePercentage(), | |
iERC721CreatorRoyalty.getERC721TokenRoyaltyPercentage( | |
_originContract, | |
_tokenId | |
), | |
iMarketplaceSettings.getERC721ContractPrimarySaleFeePercentage( | |
_originContract | |
), | |
msg.sender, | |
owner, | |
iERC721CreatorRoyalty.tokenCreator(_originContract, _tokenId), | |
owner | |
); | |
iMarketplaceSettings.markERC721Token(_originContract, _tokenId, true); | |
emit AcceptBid( | |
_originContract, | |
currentBid.bidder, | |
msg.sender, | |
currentBid.amount, | |
_tokenId | |
); | |
} | |
else{ | |
Payments.payoutSecondary( | |
currentBid.amount, | |
!iMarketplaceSettings.hasERC721TokenSold(_originContract, _tokenId), | |
iMarketplaceSettings.getMarketplaceFeePercentage(), | |
iERC721CreatorRoyalty.getERC721TokenRoyaltyPercentage( | |
_originContract, | |
_tokenId | |
), | |
iMarketplaceSettings.getERC721ContractSecondarySaleFeePercentage( | |
_originContract | |
), | |
msg.sender, | |
owner, | |
iERC721CreatorRoyalty.tokenCreator(_originContract, _tokenId), | |
owner | |
); | |
iMarketplaceSettings.markERC721Token(_originContract, _tokenId, true); | |
emit AcceptBid( | |
_originContract, | |
currentBid.bidder, | |
msg.sender, | |
currentBid.amount, | |
_tokenId | |
); | |
} | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// cancelBid | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Cancel the bid on the token. | |
* @param _originContract address of the contract storing the token. | |
* @param _tokenId uint256 ID of the token. | |
*/ | |
function cancelBid(address _originContract, uint256 _tokenId) external { | |
// Check that sender has a current bid. | |
require( | |
_addressHasBidOnToken(msg.sender, _originContract, _tokenId), | |
"cancelBid::Cannot cancel a bid if sender hasn't made one." | |
); | |
// Refund the bidder. | |
_refundBid(_originContract, _tokenId); | |
emit CancelBid( | |
_originContract, | |
msg.sender, | |
tokenCurrentBids[_originContract][_tokenId].amount, | |
_tokenId | |
); | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// currentBidDetailsOfToken | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Function to get current bid and bidder of a token. | |
* @param _originContract address of ERC721 contract. | |
* @param _tokenId uin256 id of the token. | |
*/ | |
function currentBidDetailsOfToken(address _originContract, uint256 _tokenId) | |
public | |
view | |
returns (uint256, address) | |
{ | |
return ( | |
tokenCurrentBids[_originContract][_tokenId].amount, | |
tokenCurrentBids[_originContract][_tokenId].bidder | |
); | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// _priceSetterStillOwnsTheToken | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Checks that the token is owned by the same person who set the sale price. | |
* @param _originContract address of the contract storing the token. | |
* @param _tokenId uint256 id of the. | |
*/ | |
function _priceSetterStillOwnsTheToken( | |
address _originContract, | |
uint256 _tokenId | |
) internal view returns (bool) { | |
IERC721Upgradeable erc721 = IERC721Upgradeable(_originContract); | |
return | |
erc721.ownerOf(_tokenId) == | |
tokenPrices[_originContract][_tokenId].seller; | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// _resetTokenPrice | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Internal function to set token price to 0 for a given contract. | |
* @param _originContract address of ERC721 contract. | |
* @param _tokenId uin256 id of the token. | |
*/ | |
function _resetTokenPrice(address _originContract, uint256 _tokenId) | |
internal | |
{ | |
tokenPrices[_originContract][_tokenId] = SalePrice(address(0), 0); | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// _addressHasBidOnToken | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Internal function see if the given address has an existing bid on a token. | |
* @param _bidder address that may have a current bid. | |
* @param _originContract address of ERC721 contract. | |
* @param _tokenId uin256 id of the token. | |
*/ | |
function _addressHasBidOnToken( | |
address _bidder, | |
address _originContract, | |
uint256 _tokenId | |
) internal view returns (bool) { | |
return tokenCurrentBids[_originContract][_tokenId].bidder == _bidder; | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// _tokenHasBid | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Internal function see if the token has an existing bid. | |
* @param _originContract address of ERC721 contract. | |
* @param _tokenId uin256 id of the token. | |
*/ | |
function _tokenHasBid(address _originContract, uint256 _tokenId) | |
internal | |
view | |
returns (bool) | |
{ | |
return tokenCurrentBids[_originContract][_tokenId].bidder != address(0); | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// _refundBid | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Internal function to return an existing bid on a token to the | |
* bidder and reset bid. | |
* @param _originContract address of ERC721 contract. | |
* @param _tokenId uin256 id of the token. | |
*/ | |
function _refundBid(address _originContract, uint256 _tokenId) internal { | |
ActiveBid memory currentBid = | |
tokenCurrentBids[_originContract][_tokenId]; | |
if (currentBid.bidder == address(0)) { | |
return; | |
} | |
_resetBid(_originContract, _tokenId); | |
Payments.refund( | |
currentBid.marketplaceFee, | |
currentBid.bidder, | |
currentBid.amount | |
); | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// _resetBid | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Internal function to reset bid by setting bidder and bid to 0. | |
* @param _originContract address of ERC721 contract. | |
* @param _tokenId uin256 id of the token. | |
*/ | |
function _resetBid(address _originContract, uint256 _tokenId) internal { | |
tokenCurrentBids[_originContract][_tokenId] = ActiveBid( | |
address(0), | |
0, | |
0 | |
); | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// _setBid | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Internal function to set a bid. | |
* @param _amount uint256 value in wei to bid. Does not include marketplace fee. | |
* @param _bidder address of the bidder. | |
* @param _originContract address of ERC721 contract. | |
* @param _tokenId uin256 id of the token. | |
*/ | |
function _setBid( | |
uint256 _amount, | |
address payable _bidder, | |
address _originContract, | |
uint256 _tokenId | |
) internal { | |
// Check bidder not 0 address. | |
require(_bidder != address(0), "Bidder cannot be 0 address."); | |
// Set bid. | |
tokenCurrentBids[_originContract][_tokenId] = ActiveBid( | |
_bidder, | |
iMarketplaceSettings.getMarketplaceFeePercentage(), | |
_amount | |
); | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// _makePayable | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Internal function to set a bid. | |
* @param _address non-payable address | |
* @return payable address | |
*/ | |
function _makePayable(address _address) | |
internal | |
pure | |
returns (address payable) | |
{ | |
return address(uint160(_address)); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: MIT | |
pragma solidity 0.6.12; | |
import 'https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/release-v3.3/contracts/math/SafeMathUpgradeable.sol'; | |
import 'https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/release-v3.3/contracts/access/OwnableUpgradeable.sol'; | |
import 'https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/release-v3.3/contracts/access/AccessControlUpgradeable.sol'; | |
import "./IERC721CreatorRoyalty.sol"; | |
/** | |
* @title IERC721 Non-Fungible Token Creator basic interface | |
*/ | |
contract ChimeraRoyaltyRegistry is OwnableUpgradeable, IERC721CreatorRoyalty { | |
using SafeMathUpgradeable for uint256; | |
///////////////////////////////////////////////////////////////////////// | |
// State Variables | |
///////////////////////////////////////////////////////////////////////// | |
// Mapping of ERC721 contract to royalty percentage for all NFTs, 3 == 3% | |
mapping(address => uint8) private contractRoyaltyPercentage; | |
// Mapping of ERC721 creator to royalty percentage for all NFTs. | |
mapping(address => uint8) private creatorRoyaltyPercentage; | |
// Mapping of ERC721 token to royalty percentage for all NFTs. | |
mapping(address => mapping(uint256 => uint8)) | |
private tokenRoyaltyPercentage; | |
IERC721TokenCreator public iERC721TokenCreator; | |
///////////////////////////////////////////////////////////////////////// | |
// Constructor | |
///////////////////////////////////////////////////////////////////////// | |
// constructor(address _iERC721TokenCreator) public { | |
// require( | |
// _iERC721TokenCreator != address(0), | |
// "constructor::Cannot set the null address as an _iERC721TokenCreator" | |
// ); | |
// iERC721TokenCreator = IERC721TokenCreator(_iERC721TokenCreator); | |
// } | |
///////////////////////////////////////////////////////////////////////// | |
// Constructor | |
///////////////////////////////////////////////////////////////////////// | |
function initialize(address _iERC721TokenCreator) public initializer | |
{ | |
require( | |
_iERC721TokenCreator != address(0), | |
"constructor::Cannot set the null address as an _iERC721TokenCreator" | |
); | |
__Ownable_init(); | |
iERC721TokenCreator = IERC721TokenCreator(_iERC721TokenCreator); | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// setIERC721TokenCreator | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Set an address as an IERC721TokenCreator | |
* @param _contractAddress address of the IERC721TokenCreator contract | |
*/ | |
function setIERC721TokenCreator(address _contractAddress) | |
external | |
onlyOwner | |
{ | |
require( | |
_contractAddress != address(0), | |
"setIERC721TokenCreator::_contractAddress cannot be null" | |
); | |
iERC721TokenCreator = IERC721TokenCreator(_contractAddress); | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// getERC721TokenRoyaltyPercentage | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Get the royalty fee percentage for a specific ERC721 contract. | |
* @param _contractAddress address ERC721Contract address. | |
* @param _tokenId uint256 token ID. | |
* @return uint8 wei royalty fee. | |
*/ | |
function getERC721TokenRoyaltyPercentage( | |
address _contractAddress, | |
uint256 _tokenId | |
) public override view returns (uint8) { | |
if (tokenRoyaltyPercentage[_contractAddress][_tokenId] > 0) { | |
return tokenRoyaltyPercentage[_contractAddress][_tokenId]; | |
} | |
address creator = iERC721TokenCreator.tokenCreator( | |
_contractAddress, | |
_tokenId | |
); | |
if (creatorRoyaltyPercentage[creator] > 0) { | |
return creatorRoyaltyPercentage[creator]; | |
} | |
return contractRoyaltyPercentage[_contractAddress]; | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// getPercentageForSetERC721TokenRoyalty | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Gets the royalty percentage set for an ERC721 token | |
* @param _contractAddress address ERC721Contract address. | |
* @param _tokenId uint256 token ID. | |
* @return uint8 wei royalty fee. | |
*/ | |
function getPercentageForSetERC721TokenRoyalty( | |
address _contractAddress, | |
uint256 _tokenId | |
) external view returns (uint8) { | |
return tokenRoyaltyPercentage[_contractAddress][_tokenId]; | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// setPercentageForSetERC721TokenRoyalty | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Sets the royalty percentage set for an ERC721 token | |
* Requirements: | |
* - `_percentage` must be <= 100. | |
* - only the owner of this contract or the creator can call this method. | |
* @param _contractAddress address ERC721Contract address. | |
* @param _tokenId uint256 token ID. | |
* @param _percentage uint8 wei royalty fee. | |
*/ | |
function setPercentageForSetERC721TokenRoyalty( | |
address _contractAddress, | |
uint256 _tokenId, | |
uint8 _percentage | |
) external returns (uint8) { | |
require( | |
msg.sender == | |
iERC721TokenCreator.tokenCreator(_contractAddress, _tokenId) || | |
msg.sender == owner(), | |
"setPercentageForSetERC721TokenRoyalty::Must be contract owner or creator " | |
); | |
require( | |
_percentage <= 100, | |
"setPercentageForSetERC721TokenRoyalty::_percentage must be <= 100" | |
); | |
tokenRoyaltyPercentage[_contractAddress][_tokenId] = _percentage; | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// getPercentageForSetERC721CreatorRoyalty | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Gets the royalty percentage set for an ERC721 creator | |
* @param _contractAddress address ERC721Contract address. | |
* @param _tokenId uint256 token ID. | |
* @return uint8 wei royalty fee. | |
*/ | |
function getPercentageForSetERC721CreatorRoyalty( | |
address _contractAddress, | |
uint256 _tokenId | |
) external view returns (uint8) { | |
address creator = iERC721TokenCreator.tokenCreator( | |
_contractAddress, | |
_tokenId | |
); | |
return creatorRoyaltyPercentage[creator]; | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// setPercentageForSetERC721CreatorRoyalty | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Sets the royalty percentage set for an ERC721 creator | |
* Requirements: | |
* - `_percentage` must be <= 100. | |
* - only the owner of this contract or the creator can call this method. | |
* @param _creatorAddress address token ID. | |
* @param _percentage uint8 wei royalty fee. | |
*/ | |
function setPercentageForSetERC721CreatorRoyalty( | |
address _creatorAddress, | |
uint8 _percentage | |
) external returns (uint8) { | |
require( | |
msg.sender == _creatorAddress || msg.sender == owner(), | |
"setPercentageForSetERC721CreatorRoyalty::Must be owner or creator" | |
); | |
require( | |
_percentage <= 100, | |
"setPercentageForSetERC721CreatorRoyalty::_percentage must be <= 100" | |
); | |
creatorRoyaltyPercentage[_creatorAddress] = _percentage; | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// getPercentageForSetERC721ContractRoyalty | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Gets the royalty percentage set for an ERC721 contract | |
* @param _contractAddress address ERC721Contract address. | |
* @return uint8 wei royalty fee. | |
*/ | |
function getPercentageForSetERC721ContractRoyalty(address _contractAddress) | |
external | |
view | |
returns (uint8) | |
{ | |
return contractRoyaltyPercentage[_contractAddress]; | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// setPercentageForSetERC721ContractRoyalty | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Sets the royalty percentage set for an ERC721 token | |
* Requirements: | |
* - `_percentage` must be <= 100. | |
* - only the owner of this contract. | |
* @param _contractAddress address ERC721Contract address. | |
* @param _percentage uint8 wei royalty fee. | |
*/ | |
function setPercentageForSetERC721ContractRoyalty( | |
address _contractAddress, | |
uint8 _percentage | |
) external onlyOwner returns (uint8) { | |
require( | |
_percentage <= 100, | |
"setPercentageForSetERC721ContractRoyalty::_percentage must be <= 100" | |
); | |
contractRoyaltyPercentage[_contractAddress] = _percentage; | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// calculateRoyaltyFee | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Utililty function to calculate the royalty fee for a token. | |
* @param _contractAddress address ERC721Contract address. | |
* @param _tokenId uint256 token ID. | |
* @param _amount uint256 wei amount. | |
* @return uint256 wei fee. | |
*/ | |
function calculateRoyaltyFee( | |
address _contractAddress, | |
uint256 _tokenId, | |
uint256 _amount | |
) external override view returns (uint256) { | |
return | |
_amount | |
.mul( | |
getERC721TokenRoyaltyPercentage(_contractAddress, _tokenId) | |
) | |
.div(100); | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// tokenCreator | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Gets the creator of the token | |
* @param _contractAddress address of the ERC721 contract | |
* @param _tokenId uint256 ID of the token | |
* @return address of the creator | |
*/ | |
function tokenCreator(address _contractAddress, uint256 _tokenId) | |
external | |
override | |
view | |
returns (address payable) | |
{ | |
return iERC721TokenCreator.tokenCreator(_contractAddress, _tokenId); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// contracts/MyContract.sol | |
// SPDX-License-Identifier: MIT | |
pragma solidity 0.6.12; | |
// import '@openzeppelin/contracts-upgradeable/proxy/Initializable.sol'; | |
// import '@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol'; | |
// import '@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol'; | |
// import '@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol'; | |
import "https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/release-v3.3/contracts/access/OwnableUpgradeable.sol"; | |
import "https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/release-v3.3/contracts/proxy/Initializable.sol"; | |
import "https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/release-v3.3/contracts/token/ERC721/ERC721Upgradeable.sol"; | |
import "https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/release-v3.3/contracts/math/SafeMathUpgradeable.sol"; | |
//last contract inheritance | |
//contract Chimera is Initializable, ERC721Upgradeable, IERC721Creator, Ownable, Whitelist | |
contract Whitelist is Initializable, OwnableUpgradeable { | |
function initialize() public initializer { | |
__Ownable_init(); | |
} | |
// Mapping of address to boolean indicating whether the address is whitelisted | |
mapping(address => bool) private whitelistMap; | |
// flag controlling whether whitelist is enabled. | |
bool private whitelistEnabled = true; | |
event AddToWhitelist(address indexed _newAddress); | |
event RemoveFromWhitelist(address indexed _removedAddress); | |
/** | |
* @dev Enable or disable the whitelist | |
* @param _enabled bool of whether to enable the whitelist. | |
*/ | |
function enableWhitelist(bool _enabled) public onlyOwner { | |
whitelistEnabled = _enabled; | |
} | |
/** | |
* @dev Adds the provided address to the whitelist | |
* @param _newAddress address to be added to the whitelist | |
*/ | |
function addToWhitelist(address _newAddress) public onlyOwner { | |
_whitelist(_newAddress); | |
emit AddToWhitelist(_newAddress); | |
} | |
/** | |
* @dev Removes the provided address to the whitelist | |
* @param _removedAddress address to be removed from the whitelist | |
*/ | |
function removeFromWhitelist(address _removedAddress) public onlyOwner { | |
_unWhitelist(_removedAddress); | |
emit RemoveFromWhitelist(_removedAddress); | |
} | |
/** | |
* @dev Returns whether the address is whitelisted | |
* @param _address address to check | |
* @return bool | |
*/ | |
function isWhitelisted(address _address) public view returns (bool) { | |
if (whitelistEnabled) { | |
return whitelistMap[_address]; | |
} else { | |
return true; | |
} | |
} | |
/** | |
* @dev Internal function for removing an address from the whitelist | |
* @param _removedAddress address to unwhitelisted | |
*/ | |
function _unWhitelist(address _removedAddress) internal { | |
whitelistMap[_removedAddress] = false; | |
} | |
/** | |
* @dev Internal function for adding the provided address to the whitelist | |
* @param _newAddress address to be added to the whitelist | |
*/ | |
function _whitelist(address _newAddress) internal { | |
whitelistMap[_newAddress] = true; | |
} | |
} | |
contract Chimera is Initializable, ERC721Upgradeable, OwnableUpgradeable, Whitelist { | |
using SafeMathUpgradeable for uint256; | |
string private _name; | |
string private _symbol; | |
uint8 private _decimals; | |
// Mapping from token ID to the creator's address. | |
mapping(uint256 => address) private tokenCreators; | |
//Enum for storing token type whether it is physical or Digital | |
enum TokenType {DIGITAL,PHYSICAL} | |
//Enum for storing token sale type PRIMARY or SECONDARY | |
enum TokenSaleType {PRIMARY,SECONDARY} | |
struct tokenTypeStruct{ | |
TokenType tokenType; | |
TokenSaleType tokensaleType; | |
} | |
//mapping to hold token Type | |
mapping(uint256 => tokenTypeStruct) private tokentypes; | |
// Counter for creating token IDs | |
uint256 private idCounter; | |
// Event indicating metadata was updated. | |
event TokenURIUpdated(uint256 indexed _tokenId, string _uri, TokenType _tokenType); | |
function initialize(string memory name, string memory symbol) public initializer { | |
//ERC721Upgradeable.__ERC721_init(name , symbol); | |
Whitelist.initialize(); | |
__Ownable_init(); | |
__ERC721_init(name , symbol); | |
} | |
/** | |
* @dev Whitelists a bunch of addresses. | |
* @param _whitelistees address[] of addresses to whitelist. | |
*/ | |
function initWhitelist(address[] memory _whitelistees) public onlyOwner { | |
// Add all whitelistees. | |
for (uint256 i = 0; i < _whitelistees.length; i++) { | |
address creator = _whitelistees[i]; | |
if (!isWhitelisted(creator)) { | |
_whitelist(creator); | |
} | |
} | |
} | |
/** | |
* @dev Checks that the token is owned by the sender. | |
* @param _tokenId uint256 ID of the token. | |
*/ | |
modifier onlyTokenOwner(uint256 _tokenId) { | |
address owner = ownerOf(_tokenId); | |
require(owner == msg.sender, "must be the owner of the token"); | |
_; | |
} | |
/** | |
* @dev Checks that the token was created by the sender. | |
* @param _tokenId uint256 ID of the token. | |
*/ | |
modifier onlyTokenCreator(uint256 _tokenId) { | |
address creator = tokenCreator(_tokenId); | |
require(creator == msg.sender, "must be the creator of the token"); | |
_; | |
} | |
/** | |
* @dev Adds a new unique token to the supply. | |
* @param _uri string metadata uri associated with the token. | |
* param _tokenType of the token to make it PHYSICAL or DIGITAL | |
*/ | |
function addNewToken(string memory _uri, TokenType _tokenType) public { | |
require(isWhitelisted(msg.sender), "must be whitelisted to create tokens"); | |
_createToken(_uri, msg.sender, _tokenType); | |
} | |
/** | |
* @dev Deletes the token with the provided ID. | |
* @param _tokenId uint256 ID of the token. | |
// */ | |
function deleteToken(uint256 _tokenId) public onlyTokenOwner(_tokenId) { | |
_burn( _tokenId); | |
} | |
/** | |
* @dev Updates the token metadata if the owner is also the | |
* creator. | |
* @param _tokenId uint256 ID of the token. | |
* @param _uri string metadata URI. | |
* param _tokenType of the token PHYSICAL or DIGITAL 0,1 | |
*/ | |
function updateTokenMetadata(uint256 _tokenId, string memory _uri,TokenType _tokenType ) | |
public | |
onlyTokenOwner(_tokenId) | |
onlyTokenCreator(_tokenId) | |
{ | |
_setTokenURI(_tokenId, _uri); | |
_setTokenType(_tokenId,_tokenType); | |
emit TokenURIUpdated(_tokenId, _uri, _tokenType); | |
} | |
/** | |
* @dev Gets the creator of the token. | |
* @param _tokenId uint256 ID of the token. | |
* @return address of the creator. | |
*/ | |
function tokenCreator(uint256 _tokenId) public view returns (address) { | |
return tokenCreators[_tokenId]; | |
} | |
/** | |
* @dev Gets the Type of the token. | |
* @param _tokenId uint256 ID of the token. | |
* @return _tokentype of the token PHYSICAL or DIGITAL. | |
*/ | |
function tokenType(uint256 _tokenId) public view returns (TokenType _tokentype) { | |
return tokentypes[_tokenId].tokenType; | |
} | |
/** | |
* @dev Gets the Sale Type of the token. | |
* @param _tokenId uint256 ID of the token. | |
* @return _tokensaleType of the token PHYSICAL or DIGITAL. | |
*/ | |
function getTokenSaleType(uint256 _tokenId) public view returns (TokenSaleType _tokensaleType) { | |
return tokentypes[_tokenId].tokensaleType; | |
} | |
/** | |
* @dev Internal function for setting the token's creator. | |
* @param _tokenId uint256 id of the token. | |
* @param _creator address of the creator of the token. | |
*/ | |
function _setTokenCreator(uint256 _tokenId, address _creator) internal { | |
tokenCreators[_tokenId] = _creator; | |
} | |
/** | |
* @dev Internal function for setting the token Type. | |
* @param _tokenId uint256 id of the token. | |
* @param _tokenType 0,1 DIGITAL,PHYSICAL of the creator of the token. | |
*/ | |
function _setTokenType(uint256 _tokenId, TokenType _tokenType ) internal{ | |
tokentypes[_tokenId].tokenType = _tokenType; | |
} | |
// function _setTokenSaleType(uint256 _tokenId ) internal returns(TokenSaleType _tokensaleType){ | |
// TokenSaleType tokensaleType = TokenSaleType.PRIMARY; | |
// tokentypes[_tokenId].tokensaleType = tokensaleType; | |
// return tokentypes[_tokenId].tokensaleType; | |
// } | |
/** | |
* @dev Internal function creating a new token. | |
* @param _uri string metadata uri associated with the token | |
* @param _creator address of the creator of the token. | |
* @param _tokenType of the token | |
*/ | |
function _createToken(string memory _uri, address _creator,TokenType _tokenType ) internal returns (uint256) { | |
uint256 newId = idCounter; | |
idCounter++; | |
_mint(_creator, newId); | |
_setTokenURI(newId, _uri); | |
_setTokenCreator(newId, _creator); | |
_setTokenType(newId,_tokenType); | |
return newId; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: MIT | |
pragma solidity 0.6.12; | |
import 'https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/release-v3.3/contracts/math/SafeMathUpgradeable.sol'; | |
import 'https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/release-v3.3/contracts/access/OwnableUpgradeable.sol'; | |
import 'https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/release-v3.3/contracts/proxy/Initializable.sol'; | |
// import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/solc-0.6/contracts/math/SafeMath.sol"; | |
// import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/solc-0.6/contracts/access/Ownable.sol"; | |
import "./IERC721CreatorRoyalty.sol"; | |
import "./IERC721Creator.sol"; | |
/** | |
* @title IERC721 Non-Fungible Token Creator basic interface | |
*/ | |
contract ChimeraTokenCreatorRegistry is Initializable, OwnableUpgradeable, IERC721TokenCreator { | |
using SafeMathUpgradeable for uint256; | |
///////////////////////////////////////////////////////////////////////// | |
// State Variables | |
///////////////////////////////////////////////////////////////////////// | |
// Mapping of ERC721 token to it's creator. | |
mapping(address => mapping(uint256 => address payable)) | |
private tokenCreators; | |
// Mapping of addresses that implement IERC721Creator. | |
mapping(address => bool) private iERC721Creators; | |
///////////////////////////////////////////////////////////////////////// | |
// Constructor | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Initializes the contract setting the iERC721Creators with the provided addresses. | |
* @param _iERC721Creators address[] to set as iERC721Creators. | |
*/ | |
// constructor(address[] memory _iERC721Creators) public { | |
// require( | |
// _iERC721Creators.length < 1000, | |
// "constructor::Cannot mark more than 1000 addresses as IERC721Creator" | |
// ); | |
// for (uint8 i = 0; i < _iERC721Creators.length; i++) { | |
// require( | |
// _iERC721Creators[i] != address(0), | |
// "constructor::Cannot set the null address as an IERC721Creator" | |
// ); | |
// iERC721Creators[_iERC721Creators[i]] = true; | |
// } | |
// } | |
///////////////////////////////////////////////////////////////////////// | |
// initializer | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Initializes the contract setting the iERC721Creators with the provided addresses. | |
* @param _iERC721Creators address[] to set as iERC721Creators. | |
*/ | |
function initialize(address[] memory _iERC721Creators) public initializer { | |
require( | |
_iERC721Creators.length < 1000, | |
"constructor::Cannot mark more than 1000 addresses as IERC721Creator" | |
); | |
__Ownable_init(); | |
for (uint8 i = 0; i < _iERC721Creators.length; i++) { | |
require( | |
_iERC721Creators[i] != address(0), | |
"constructor::Cannot set the null address as an IERC721Creator" | |
); | |
iERC721Creators[_iERC721Creators[i]] = true; | |
} | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// tokenCreator | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Gets the creator of the token | |
* @param _contractAddress address of the ERC721 contract | |
* @param _tokenId uint256 ID of the token | |
* @return address of the creator | |
*/ | |
function tokenCreator(address _contractAddress, uint256 _tokenId) | |
external | |
override | |
view | |
returns (address payable) | |
{ | |
if (tokenCreators[_contractAddress][_tokenId] != address(0)) { | |
return tokenCreators[_contractAddress][_tokenId]; | |
} | |
if (iERC721Creators[_contractAddress]) { | |
return IERC721Creator(_contractAddress).tokenCreator(_tokenId); | |
} | |
return address(0); | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// setTokenCreator | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Sets the creator of the token | |
* @param _contractAddress address of the ERC721 contract | |
* @param _tokenId uint256 ID of the token | |
* @param _creator address of the creator for the token | |
*/ | |
function setTokenCreator( | |
address _contractAddress, | |
uint256 _tokenId, | |
address payable _creator | |
) external onlyOwner { | |
require( | |
_creator != address(0), | |
"setTokenCreator::Cannot set null address as creator" | |
); | |
require( | |
_contractAddress != address(0), | |
"setTokenCreator::_contractAddress cannot be null" | |
); | |
tokenCreators[_contractAddress][_tokenId] = _creator; | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// setIERC721Creator | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Set an address as an IERC721Creator | |
* @param _contractAddress address of the IERC721Creator contract | |
*/ | |
function setIERC721Creator(address _contractAddress) external onlyOwner { | |
require( | |
_contractAddress != address(0), | |
"setIERC721Creator::_contractAddress cannot be null" | |
); | |
iERC721Creators[_contractAddress] = true; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: MIT | |
pragma solidity 0.6.12; | |
/** | |
* @title IERC721 Non-Fungible Token Creator basic interface | |
*/ | |
interface IERC721Creator { | |
/** | |
* @dev Gets the creator of the token | |
* @param _tokenId uint256 ID of the token | |
* @return address of the creator | |
*/ | |
function tokenCreator(uint256 _tokenId) | |
external | |
view | |
returns (address payable); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: MIT | |
pragma solidity 0.6.12; | |
import "./IERC721TokenCreator.sol"; | |
/** | |
* @title IERC721CreatorRoyalty Token level royalty interface. | |
*/ | |
interface IERC721CreatorRoyalty is IERC721TokenCreator { | |
/** | |
* @dev Get the royalty fee percentage for a specific ERC721 contract. | |
* @param _contractAddress address ERC721Contract address. | |
* @param _tokenId uint256 token ID. | |
* @return uint8 wei royalty fee. | |
*/ | |
function getERC721TokenRoyaltyPercentage( | |
address _contractAddress, | |
uint256 _tokenId | |
) external view returns (uint8); | |
/** | |
* @dev Utililty function to calculate the royalty fee for a token. | |
* @param _contractAddress address ERC721Contract address. | |
* @param _tokenId uint256 token ID. | |
* @param _amount uint256 wei amount. | |
* @return uint256 wei fee. | |
*/ | |
function calculateRoyaltyFee( | |
address _contractAddress, | |
uint256 _tokenId, | |
uint256 _amount | |
) external view returns (uint256); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: MIT | |
pragma solidity 0.6.12; | |
/** | |
* @title IERC721 Non-Fungible Token Creator basic interface | |
*/ | |
interface IERC721TokenCreator { | |
/** | |
* @dev Gets the creator of the token | |
* @param _contractAddress address of the ERC721 contract | |
* @param _tokenId uint256 ID of the token | |
* @return address of the creator | |
*/ | |
function tokenCreator(address _contractAddress, uint256 _tokenId) | |
external | |
view | |
returns (address payable); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: MIT | |
pragma solidity 0.6.12; | |
/** | |
* @title IMarketplaceSettings Settings governing a marketplace. | |
*/ | |
interface IMarketplaceSettings { | |
///////////////////////////////////////////////////////////////////////// | |
// Marketplace Min and Max Values | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Get the max value to be used with the marketplace. | |
* @return uint256 wei value. | |
*/ | |
function getMarketplaceMaxValue() external view returns (uint256); | |
/** | |
* @dev Get the max value to be used with the marketplace. | |
* @return uint256 wei value. | |
*/ | |
function getMarketplaceMinValue() external view returns (uint256); | |
///////////////////////////////////////////////////////////////////////// | |
// Marketplace Fee | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Get the marketplace fee percentage. | |
* @return uint8 wei fee. | |
*/ | |
function getMarketplaceFeePercentage() external view returns (uint8); | |
/** | |
* @dev Utility function for calculating the marketplace fee for given amount of wei. | |
* @param _amount uint256 wei amount. | |
* @return uint256 wei fee. | |
*/ | |
function calculateMarketplaceFee(uint256 _amount) | |
external | |
view | |
returns (uint256); | |
///////////////////////////////////////////////////////////////////////// | |
// Primary Sale Fee | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Get the primary sale fee percentage for a specific ERC721 contract. | |
* @param _contractAddress address ERC721Contract address. | |
* @return uint8 wei primary sale fee. | |
*/ | |
function getERC721ContractPrimarySaleFeePercentage(address _contractAddress) | |
external | |
view | |
returns (uint8); | |
/** | |
* @dev Utility function for calculating the primary sale fee for given amount of wei | |
* @param _contractAddress address ERC721Contract address. | |
* @param _amount uint256 wei amount. | |
* @return uint256 wei fee. | |
*/ | |
function calculatePrimarySaleFee(address _contractAddress, uint256 _amount) | |
external | |
view | |
returns (uint256); | |
//chimera | |
///////////////////////////////////////////////////////////////////////// | |
// secondary Sale Fee | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Get the secondary sale fee percentage for a specific ERC721 contract. | |
* @param _contractAddress address ERC721Contract address. | |
* @return uint8 wei secondary sale fee. | |
*/ | |
function getERC721ContractSecondarySaleFeePercentage(address _contractAddress) | |
external | |
view | |
returns (uint8); | |
/** | |
* @dev Utility function for calculating the secondary sale fee for given amount of wei | |
* @param _contractAddress address ERC721Contract address. | |
* @param _amount uint256 wei amount. | |
* @return uint256 wei fee. | |
*/ | |
function calculateSecondarySaleFee(address _contractAddress, uint256 _amount) | |
external | |
view | |
returns (uint256); | |
/** | |
* @dev Check whether the ERC721 token has sold at least once. | |
* @param _contractAddress address ERC721Contract address. | |
* @param _tokenId uint256 token ID. | |
* @return bool of whether the token has sold. | |
*/ | |
function hasERC721TokenSold(address _contractAddress, uint256 _tokenId) | |
external | |
view | |
returns (bool); | |
/** | |
* @dev Mark a token as sold. | |
* Requirements: | |
* | |
* - `_contractAddress` cannot be the zero address. | |
* @param _contractAddress address ERC721Contract address. | |
* @param _tokenId uint256 token ID. | |
* @param _hasSold bool of whether the token should be marked sold or not. | |
*/ | |
function markERC721Token( | |
address _contractAddress, | |
uint256 _tokenId, | |
bool _hasSold | |
) external; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: MIT | |
pragma solidity 0.6.12; | |
interface ISendValueProxy { | |
function sendValue(address payable _to) external payable; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: MIT | |
pragma solidity 0.6.12; | |
import "./IMarketplaceSettings.sol"; | |
import 'https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/release-v3.3/contracts/access/OwnableUpgradeable.sol'; | |
import 'https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/release-v3.3/contracts/access/AccessControlUpgradeable.sol'; | |
import 'https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/release-v3.3/contracts/math/SafeMathUpgradeable.sol'; | |
import 'https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/release-v3.3/contracts/proxy/Initializable.sol'; | |
// import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/solc-0.6/contracts/access/Ownable.sol"; | |
// import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/solc-0.6/contracts/access/AccessControl.sol"; | |
// import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/solc-0.6/contracts/math/SafeMath.sol"; | |
/** | |
* @title MarketplaceSettings Settings governing the marketplace fees. | |
*/ | |
contract MarketplaceSettings is Initializable, OwnableUpgradeable, AccessControlUpgradeable, IMarketplaceSettings { | |
using SafeMathUpgradeable for uint256; | |
///////////////////////////////////////////////////////////////////////// | |
// Constants | |
///////////////////////////////////////////////////////////////////////// | |
bytes32 public constant TOKEN_MARK_ROLE = "TOKEN_MARK_ROLE"; | |
///////////////////////////////////////////////////////////////////////// | |
// State Variables | |
///////////////////////////////////////////////////////////////////////// | |
// Max wei value within the marketplace | |
uint256 private maxValue; | |
// Min wei value within the marketplace | |
uint256 private minValue; | |
// Percentage fee for the marketplace, 3 == 3% | |
uint8 private marketplaceFeePercentage; | |
// Mapping of ERC721 contract to the primary sale fee. If primary sale fee is 0 for an origin contract then primary sale fee is ignored. 1 == 1% | |
mapping(address => uint8) private primarySaleFees; | |
//chimera | |
// Mapping of ERC721 contract to the secondary sale fee. If secondary sale fee is 0 for an origin contract then secondary sale fee is ignored. 1 == 1% | |
mapping(address => uint8) private secondarySaleFees; | |
// Mapping of ERC721 contract to mapping of token ID to whether the token has been sold before. | |
mapping(address => mapping(uint256 => bool)) private soldTokens; | |
///////////////////////////////////////////////////////////////////////// | |
// Constructor | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Initializes the contract maxValue, minValues, and marketplaceFeePercentage to default settings. | |
* Also, sets the roles for the contract to the owner. | |
*/ | |
// constructor() public { | |
// maxValue = 2**254; // 2 ^ 254 is max amount, prevents any overflow issues. | |
// minValue = 1000; // all amounts must be greater than 1000 Wei. | |
// marketplaceFeePercentage = 3; // 3% marketplace fee on all txs. | |
// _setupRole(AccessControl.DEFAULT_ADMIN_ROLE, owner()); | |
// grantRole(TOKEN_MARK_ROLE, owner()); | |
// } | |
///////////////////////////////////////////////////////////////////////// | |
// initializer | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Initializes the contract maxValue, minValues, and marketplaceFeePercentage to default settings. | |
* Also, sets the roles for the contract to the owner. | |
*/ | |
function initialize() public initializer { | |
__Ownable_init(); | |
__AccessControl_init(); | |
maxValue = 2**254; // 2 ^ 254 is max amount, prevents any overflow issues. | |
minValue = 1000; // all amounts must be greater than 1000 Wei. | |
marketplaceFeePercentage = 3; // 3% marketplace fee on all txs. | |
_setupRole(AccessControlUpgradeable.DEFAULT_ADMIN_ROLE, owner()); | |
grantRole(TOKEN_MARK_ROLE, owner()); | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// grantMarketplaceMarkTokenAccess | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Grants a marketplace contract access to marke | |
* @param _account address of the account that can perform the token mark role. | |
*/ | |
function grantMarketplaceAccess(address _account) external { | |
require( | |
hasRole(AccessControlUpgradeable.DEFAULT_ADMIN_ROLE, msg.sender), | |
"grantMarketplaceAccess::Must be admin to call method" | |
); | |
grantRole(TOKEN_MARK_ROLE, _account); | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// getMarketplaceMaxValue | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Get the max value to be used with the marketplace. | |
* @return uint256 wei value. | |
*/ | |
function getMarketplaceMaxValue() external override view returns (uint256) { | |
return maxValue; | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// setMarketplaceMaxValue | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Set the maximum value of the marketplace settings. | |
* @param _maxValue uint256 maximum wei value. | |
*/ | |
function setMarketplaceMaxValue(uint256 _maxValue) external onlyOwner { | |
maxValue = _maxValue; | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// getMarketplaceMinValue | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Get the max value to be used with the marketplace. | |
* @return uint256 wei value. | |
*/ | |
function getMarketplaceMinValue() external override view returns (uint256) { | |
return minValue; | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// setMarketplaceMinValue | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Set the minimum value of the marketplace settings. | |
* @param _minValue uint256 minimum wei value. | |
*/ | |
function setMarketplaceMinValue(uint256 _minValue) external onlyOwner { | |
minValue = _minValue; | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// getMarketplaceFeePercentage | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Get the marketplace fee percentage. | |
* @return uint8 wei fee. | |
*/ | |
function getMarketplaceFeePercentage() | |
external | |
override | |
view | |
returns (uint8) | |
{ | |
return marketplaceFeePercentage; | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// setMarketplaceFeePercentage | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Set the marketplace fee percentage. | |
* Requirements: | |
* - `_percentage` must be <= 100. | |
* @param _percentage uint8 percentage fee. | |
*/ | |
function setMarketplaceFeePercentage(uint8 _percentage) external onlyOwner { | |
require( | |
_percentage <= 100, | |
"setMarketplaceFeePercentage::_percentage must be <= 100" | |
); | |
marketplaceFeePercentage = _percentage; | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// calculateMarketplaceFee | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Utility function for calculating the marketplace fee for given amount of wei. | |
* @param _amount uint256 wei amount. | |
* @return uint256 wei fee. | |
*/ | |
function calculateMarketplaceFee(uint256 _amount) | |
external | |
override | |
view | |
returns (uint256) | |
{ | |
return _amount.mul(marketplaceFeePercentage).div(100); | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// getERC721ContractPrimarySaleFeePercentage | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Get the primary sale fee percentage for a specific ERC721 contract. | |
* @param _contractAddress address ERC721Contract address. | |
* @return uint8 wei primary sale fee. | |
*/ | |
function getERC721ContractPrimarySaleFeePercentage(address _contractAddress) | |
external | |
override | |
view | |
returns (uint8) | |
{ | |
return primarySaleFees[_contractAddress]; | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// setERC721ContractPrimarySaleFeePercentage | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Set the primary sale fee percentage for a specific ERC721 contract. | |
* Requirements: | |
* | |
* - `_contractAddress` cannot be the zero address. | |
* - `_percentage` must be <= 100. | |
* @param _contractAddress address ERC721Contract address. | |
* @param _percentage uint8 percentage fee for the ERC721 contract. | |
*/ | |
function setERC721ContractPrimarySaleFeePercentage( | |
address _contractAddress, | |
uint8 _percentage | |
) external onlyOwner { | |
require( | |
_percentage <= 100, | |
"setERC721ContractPrimarySaleFeePercentage::_percentage must be <= 100" | |
); | |
primarySaleFees[_contractAddress] = _percentage; | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// calculatePrimarySaleFee | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Utility function for calculating the primary sale fee for given amount of wei | |
* @param _contractAddress address ERC721Contract address. | |
* @param _amount uint256 wei amount. | |
* @return uint256 wei fee. | |
*/ | |
function calculatePrimarySaleFee(address _contractAddress, uint256 _amount) | |
external | |
override | |
view | |
returns (uint256) | |
{ | |
return _amount.mul(primarySaleFees[_contractAddress]).div(100); | |
} | |
//chimera | |
///////////////////////////////////////////////////////////////////////// | |
// getERC721ContractSecondarySaleFeePercentage | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Get the secondary sale fee percentage for a specific ERC721 contract. | |
* @param _contractAddress address ERC721Contract address. | |
* @return uint8 wei primary sale fee. | |
*/ | |
function getERC721ContractSecondarySaleFeePercentage(address _contractAddress) | |
external | |
override | |
view | |
returns (uint8) | |
{ | |
return secondarySaleFees[_contractAddress]; | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// setERC721ContractSecondarySaleFeePercentage | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Set the secondary sale fee percentage for a specific ERC721 contract. | |
* Requirements: | |
* | |
* - `_contractAddress` cannot be the zero address. | |
* - `_percentage` must be <= 100. | |
* @param _contractAddress address ERC721Contract address. | |
* @param _percentage uint8 percentage fee for the ERC721 contract. | |
*/ | |
function setERC721ContractSecondarySaleFeePercentage( | |
address _contractAddress, | |
uint8 _percentage | |
) external onlyOwner { | |
require( | |
_percentage <= 100, | |
"setERC721ContractSecondarySaleFeePercentage::_percentage must be <= 100" | |
); | |
secondarySaleFees[_contractAddress] = _percentage; | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// calculateSecondarySaleFee | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Utility function for calculating the secondary sale fee for given amount of wei | |
* @param _contractAddress address ERC721Contract address. | |
* @param _amount uint256 wei amount. | |
* @return uint256 wei fee. | |
*/ | |
function calculateSecondarySaleFee(address _contractAddress, uint256 _amount) | |
external | |
override | |
view | |
returns (uint256) | |
{ | |
return _amount.mul(secondarySaleFees[_contractAddress]).div(100); | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// hasERC721TokenSold | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Check whether the ERC721 token has sold at least once. | |
* @param _contractAddress address ERC721Contract address. | |
* @param _tokenId uint256 token ID. | |
* @return bool of whether the token has sold. | |
*/ | |
function hasERC721TokenSold(address _contractAddress, uint256 _tokenId) | |
external | |
override | |
view | |
returns (bool) | |
{ | |
return soldTokens[_contractAddress][_tokenId]; | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// markERC721TokenAsSold | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Mark a token as sold. | |
* Requirements: | |
* | |
* - `_contractAddress` cannot be the zero address. | |
* @param _contractAddress address ERC721Contract address. | |
* @param _tokenId uint256 token ID. | |
* @param _hasSold bool of whether the token should be marked sold or not. | |
*/ | |
function markERC721Token( | |
address _contractAddress, | |
uint256 _tokenId, | |
bool _hasSold | |
) external override { | |
require( | |
hasRole(TOKEN_MARK_ROLE, msg.sender), | |
"markERC721Token::Must have TOKEN_MARK_ROLE role to call method" | |
); | |
soldTokens[_contractAddress][_tokenId] = _hasSold; | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// markTokensAsSold | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Function to set an array of tokens for a contract as sold, thus not being subject to the primary sale fee, if one exists. | |
* @param _originContract address of ERC721 contract. | |
* @param _tokenIds uint256[] array of token ids. | |
*/ | |
function markTokensAsSold( | |
address _originContract, | |
uint256[] calldata _tokenIds | |
) external { | |
require( | |
hasRole(TOKEN_MARK_ROLE, msg.sender), | |
"markERC721Token::Must have TOKEN_MARK_ROLE role to call method" | |
); | |
// limit to batches of 2000 | |
require( | |
_tokenIds.length <= 2000, | |
"markTokensAsSold::Attempted to mark more than 2000 tokens as sold" | |
); | |
// Mark provided tokens as sold. | |
for (uint256 i = 0; i < _tokenIds.length; i++) { | |
soldTokens[_originContract][_tokenIds[i]] = true; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: MIT | |
pragma solidity 0.6.12; | |
import 'https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/release-v3.3/contracts/proxy/Initializable.sol'; | |
import "./SendValueProxy.sol"; | |
/** | |
* @dev Contract with a ISendValueProxy that will catch reverts when attempting to transfer funds. | |
*/ | |
contract MaybeSendValue is Initializable { | |
SendValueProxy proxy; | |
// constructor() internal { | |
// proxy = new SendValueProxy(); | |
// } | |
function SendValueProxyInitialize() public initializer { | |
proxy = new SendValueProxy(); | |
} | |
/** | |
* @dev Maybe send some wei to the address via a proxy. Returns true on success and false if transfer fails. | |
* @param _to address to send some value to. | |
* @param _value uint256 amount to send. | |
*/ | |
// function maybeSendValue(address payable _to, uint256 _value) | |
// internal | |
// returns (bool) | |
// { | |
// // Call sendValue on the proxy contract and forward the mesg.value. | |
// /* solium-disable-next-line */ | |
// // (bool success, bytes memory _) = address(proxy).call.value(_value)( | |
// // abi.encodeWithSignature("sendValue(address)", _to) | |
// // ); | |
// (bool success, bytes memory _) = address(proxy).call{value:(_value)}( | |
// abi.encodeWithSignature("sendValue(address)", _to) | |
// ); | |
// return success; | |
// } | |
/** | |
* @dev Maybe send some wei to the address via a proxy. Returns true on success and false if transfer fails. | |
* @param _to address to send some value to. | |
* @param _value uint256 amount to send. | |
*/ | |
function maybeSendValue(address payable _to, uint256 _value) | |
internal | |
returns (bool) | |
{ | |
_to.transfer(_value); | |
return true; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: MIT | |
pragma solidity 0.6.12; | |
import 'https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/release-v3.3/contracts/math/SafeMathUpgradeable.sol'; | |
import 'https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/release-v3.3/contracts/proxy/Initializable.sol'; | |
import "./SendValueOrEscrow.sol"; | |
/** | |
* @title Payments contract for Chimera Marketplaces. | |
*/ | |
contract Payments is Initializable ,SendValueOrEscrow { | |
using SafeMathUpgradeable for uint256; | |
using SafeMathUpgradeable for uint8; | |
//primaryEvents | |
event PrimarymarketplacePayment(address indexed _marketplacePayee,uint indexed _marketplacePayment); | |
event PrimarySalePayment(address indexed _primarySalePayee,uint primarySalePayment); | |
event PrimarypayeePayment(address indexed _payee,uint payeePayment); | |
//SecondaryEvents | |
event SecondarymarketplacePayment(address indexed _marketplacePayee,uint indexed _marketplacePayment); | |
event SecondarySalePayment(address indexed _secondarySalePayee,uint primarySalePayment); | |
event SecondarypayeePayment(address indexed _payee,uint payeePayment); | |
function initializePayment() public initializer { | |
SendValueOrEscrow.initialize(); | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// refund | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Internal function to refund an address. Typically for canceled bids or offers. | |
* Requirements: | |
* | |
* - _payee cannot be the zero address | |
* | |
* @param _marketplacePercentage uint8 percentage of the fee for the marketplace. | |
* @param _amount uint256 value to be split. | |
* @param _payee address seller of the token. | |
*/ | |
function refund( | |
uint8 _marketplacePercentage, | |
address payable _payee, | |
uint256 _amount | |
) internal { | |
require( | |
_payee != address(0), | |
"refund::no payees can be the zero address" | |
); | |
if (_amount > 0) { | |
SendValueOrEscrow.sendValueOrEscrow( | |
_payee, | |
_amount.add( | |
calcPercentagePayment(_amount, _marketplacePercentage) | |
) | |
); | |
} | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// payout Primay | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Internal function to pay the seller, creator, and maintainer. | |
* Requirements: | |
* | |
* - _marketplacePercentage + _royaltyPercentage + _primarySalePercentage <= 100 | |
* - no payees can be the zero address | |
* | |
* @param _amount uint256 value to be split. | |
* @param _isPrimarySale bool of whether this is a primary sale. | |
* @param _marketplacePercentage uint8 percentage of the fee for the marketplace. | |
* @param _royaltyPercentage uint8 percentage of the fee for the royalty. | |
* @param _primarySalePercentage uint8 percentage primary sale fee for the marketplace. | |
* @param _payee address seller of the token. | |
* @param _marketplacePayee address seller of the token. | |
* @param _royaltyPayee address seller of the token. | |
* @param _primarySalePayee address seller of the token. | |
*/ | |
function payoutPrimary( | |
uint256 _amount, | |
bool _isPrimarySale, | |
uint8 _marketplacePercentage, | |
uint8 _royaltyPercentage, | |
uint8 _primarySalePercentage, | |
address payable _payee, | |
address payable _marketplacePayee, | |
address payable _royaltyPayee, | |
address payable _primarySalePayee | |
) internal { | |
require( | |
_marketplacePercentage <= 100, | |
"payout::marketplace percentage cannot be above 100" | |
); | |
require( | |
_royaltyPercentage.add(_primarySalePercentage) <= 100, | |
"payout::percentages cannot go beyond 100" | |
); | |
require( | |
_payee != address(0) && | |
_primarySalePayee != address(0) && | |
_marketplacePayee != address(0) && | |
_royaltyPayee != address(0), | |
"payout::no payees can be the zero address" | |
); | |
// Note:: Solidity is kind of terrible in that there is a limit to local | |
// variables that can be put into the stack. The real pain is that | |
// one can put structs, arrays, or mappings into memory but not basic | |
// data types. Hence our payments array that stores these values. | |
uint256[4] memory payments; | |
// uint256 marketplacePayment | |
payments[0] = calcPercentagePayment(_amount, _marketplacePercentage); | |
// uint256 royaltyPayment | |
payments[1] = calcRoyaltyPayment( | |
_isPrimarySale, | |
_amount, | |
_royaltyPercentage | |
); | |
// uint256 primarySalePayment | |
payments[2] = calcPrimarySalePayment( | |
_isPrimarySale, | |
_amount, | |
_primarySalePercentage | |
); | |
// uint256 payeePayment | |
// payments[3] = _amount.sub(payments[2]); | |
payments[3] = _amount.sub(payments[1]).sub(payments[2]); | |
// marketplacePayment | |
if (payments[0] > 0) { | |
SendValueOrEscrow.sendValueOrEscrow(_marketplacePayee, payments[0]); | |
emit PrimarymarketplacePayment(_marketplacePayee,payments[0]); | |
} | |
// royaltyPayment | |
if (payments[1] > 0) { | |
SendValueOrEscrow.sendValueOrEscrow(_royaltyPayee, payments[1]); | |
} | |
// primarySalePayment | |
if (payments[2] > 0) { | |
SendValueOrEscrow.sendValueOrEscrow(_primarySalePayee, payments[2]); | |
emit PrimarySalePayment(_primarySalePayee, payments[2]); | |
} | |
// payeePayment | |
if (payments[3] > 0) { | |
SendValueOrEscrow.sendValueOrEscrow(_payee, payments[3]); | |
emit PrimarypayeePayment(_payee, payments[3]); | |
} | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// payout With Secondary Fee | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Internal function to pay the seller, creator, and maintainer. | |
* Requirements: | |
* | |
* - _marketplacePercentage + _royaltyPercentage + _secondarySalePercentage <= 100 | |
* - no payees can be the zero address | |
* | |
* @param _amount uint256 value to be split. | |
* @param _isPrimarySale bool of whether this is a primary sale. | |
* @param _marketplacePercentage uint8 percentage of the fee for the marketplace. | |
* @param _royaltyPercentage uint8 percentage of the fee for the royalty. | |
* @param _secondarySalePercentage uint8 percentage primary sale fee for the marketplace. | |
* @param _payee address seller of the token. | |
* @param _marketplacePayee address seller of the token. | |
* @param _royaltyPayee address seller of the token. | |
* @param _secondarySalePayee address seller of the token. | |
*/ | |
function payoutSecondary( | |
uint256 _amount, | |
bool _isPrimarySale, //false | |
uint8 _marketplacePercentage, | |
uint8 _royaltyPercentage, | |
uint8 _secondarySalePercentage, | |
address payable _payee, | |
address payable _marketplacePayee, | |
address payable _royaltyPayee, | |
address payable _secondarySalePayee | |
) internal { | |
require( | |
_marketplacePercentage <= 100, | |
"payout::marketplace percentage cannot be above 100" | |
); | |
require( | |
_royaltyPercentage.add(_secondarySalePercentage) <= 100, | |
"payout::percentages cannot go beyond 100" | |
); | |
require( | |
_payee != address(0) && | |
_secondarySalePayee != address(0) && | |
_marketplacePayee != address(0) && | |
_royaltyPayee != address(0), | |
"payout::no payees can be the zero address" | |
); | |
// Note:: Solidity is kind of terrible in that there is a limit to local | |
// variables that can be put into the stack. The real pain is that | |
// one can put structs, arrays, or mappings into memory but not basic | |
// data types. Hence our payments array that stores these values. | |
uint256[4] memory payments; | |
// uint256 marketplacePayment | |
payments[0] = calcPercentagePayment(_amount, _marketplacePercentage); | |
// uint256 royaltyPayment | |
payments[1] = calcRoyaltyPayment( | |
_isPrimarySale, | |
_amount, | |
_royaltyPercentage | |
); | |
// uint256 SecondarySalePayment | |
payments[2] = calcSecondarySalePayment( | |
_isPrimarySale, | |
_amount, | |
_secondarySalePercentage | |
); | |
// uint256 payeePayment | |
payments[3] = _amount.sub(payments[2]); | |
// marketplacePayment | |
if (payments[0] > 0) { | |
SendValueOrEscrow.sendValueOrEscrow(_marketplacePayee, payments[0]); | |
emit SecondarymarketplacePayment(_marketplacePayee,payments[0] ); | |
} | |
// // royaltyPayment | |
if (payments[1] > 0) { | |
SendValueOrEscrow.sendValueOrEscrow(_royaltyPayee, payments[1]); | |
} | |
// primarySalePayment | |
if (payments[2] > 0) { | |
SendValueOrEscrow.sendValueOrEscrow(_secondarySalePayee, payments[2]); | |
emit SecondarySalePayment(_secondarySalePayee, payments[2]); | |
} | |
// payeePayment | |
if (payments[3] > 0) { | |
SendValueOrEscrow.sendValueOrEscrow(_payee, payments[3]); | |
emit SecondarypayeePayment(_payee,payments[3]); | |
} | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// calcRoyaltyPayment | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Private function to calculate Royalty amount. | |
* If primary sale: 0 | |
* If no royalty percentage: 0 | |
* otherwise: royalty in wei | |
* @param _isPrimarySale bool of whether this is a primary sale | |
* @param _amount uint256 value to be split | |
* @param _percentage uint8 royalty percentage | |
* @return uint256 wei value owed for royalty | |
*/ | |
function calcRoyaltyPayment( | |
bool _isPrimarySale, | |
uint256 _amount, | |
uint8 _percentage | |
) private pure returns (uint256) { | |
if (_isPrimarySale) { | |
return 0; | |
} | |
return calcPercentagePayment(_amount, _percentage); | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// calcPrimarySalePayment | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Private function to calculate PrimarySale amount. | |
* If not primary sale: 0 | |
* otherwise: primary sale in wei | |
* @param _isPrimarySale bool of whether this is a primary sale | |
* @param _amount uint256 value to be split | |
* @param _percentage uint8 royalty percentage | |
* @return uint256 wei value owed for primary sale | |
*/ | |
function calcPrimarySalePayment( | |
bool _isPrimarySale, | |
uint256 _amount, | |
uint8 _percentage | |
) private pure returns (uint256) { | |
if (_isPrimarySale) { | |
return calcPercentagePayment(_amount, _percentage); | |
} | |
return 0; | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// calcSecondarySalePayment | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Private function to calculate PrimarySale amount. | |
* If not primary sale: 0 | |
* otherwise: primary sale in wei | |
* @param _isPrimarySale bool of whether this is a primary sale | |
* @param _amount uint256 value to be split | |
* @param _percentage uint8 royalty percentage | |
* @return uint256 wei value owed for primary sale | |
*/ | |
function calcSecondarySalePayment( | |
bool _isPrimarySale, | |
uint256 _amount, | |
uint8 _percentage | |
) private pure returns (uint256) { | |
if (!_isPrimarySale) { | |
return calcPercentagePayment(_amount, _percentage); | |
} | |
return 0; | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// calcPercentagePayment | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Internal function to calculate percentage value. | |
* @param _amount uint256 wei value | |
* @param _percentage uint8 percentage | |
* @return uint256 wei value based on percentage. | |
*/ | |
function calcPercentagePayment(uint256 _amount, uint8 _percentage) | |
internal | |
pure | |
returns (uint256) | |
{ | |
return _amount.mul(_percentage).div(100); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: MIT | |
pragma solidity 0.6.12; | |
import "https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/release-v3.3/contracts/payment/PullPaymentUpgradeable.sol"; | |
import 'https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/release-v3.3/contracts/proxy/Initializable.sol'; | |
import "./MaybeSendValue.sol"; | |
/** | |
* @dev Contract to make payments. If a direct transfer fails, it will store the payment in escrow until the address decides to pull the payment. | |
*/ | |
contract SendValueOrEscrow is MaybeSendValue, PullPaymentUpgradeable { | |
///////////////////////////////////////////////////////////////////////// | |
// Events | |
///////////////////////////////////////////////////////////////////////// | |
event SendValue(address indexed _payee, uint256 amount); | |
//initializer | |
function initialize() public initializer { | |
__PullPayment_init(); | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// sendValueOrEscrow | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Send some value to an address. | |
* @param _to address to send some value to. | |
* @param _value uint256 amount to send. | |
*/ | |
function sendValueOrEscrow(address payable _to, uint256 _value) internal { | |
// attempt to make the transfer | |
bool successfulTransfer = MaybeSendValue.maybeSendValue(_to, _value); | |
// if it fails, transfer it into escrow for them to redeem at their will. | |
if (!successfulTransfer) { | |
_asyncTransfer(_to, _value); | |
} | |
emit SendValue(_to, _value); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: MIT | |
pragma solidity 0.6.12; | |
import "./ISendValueProxy.sol"; | |
/** | |
* @dev Contract that attempts to send value to an address. | |
*/ | |
contract SendValueProxy is ISendValueProxy { | |
/** | |
* @dev Send some wei to the address. | |
* @param _to address to send some value to. | |
*/ | |
function sendValue(address payable _to) external override payable { | |
// Note that `<address>.transfer` limits gas sent to receiver. It may | |
// not support complex contract operations in the future. | |
_to.transfer(msg.value); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity 0.6.12; | |
import "./ChimeraMarketAuctionV2.sol"; | |
contract TestAssertFailOnPay { | |
/** | |
* @dev A payment method that will fail by an assertion | |
*/ | |
receive() external payable { | |
assert(false); | |
} | |
/** | |
* @dev Place a bid for the owner | |
* @param _newBidAmount uint256 value in wei to bid, plus marketplace fee. | |
* @param _originContract address of the contract storing the token. | |
* @param _tokenId uint256 ID of the token | |
* @param _market address of the marketplace to make the bid | |
*/ | |
function bid( | |
uint256 _newBidAmount, | |
address _originContract, | |
uint256 _tokenId, | |
address _market | |
) public payable { | |
ChimeraMarketAuctionV2(_market).bid{value: msg.value}( | |
_newBidAmount, | |
_originContract, | |
_tokenId | |
); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity 0.6.12; | |
import 'https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/release-v3.3/contracts/access/OwnableUpgradeable.sol'; | |
import 'https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/release-v3.3/contracts/proxy/Initializable.sol'; | |
import "./ChimeraMarketAuctionV2.sol"; | |
contract TestExpensiveWallet is OwnableUpgradeable { | |
function initialize() public initializer { | |
__Ownable_init(); | |
} | |
/** | |
* @dev A costly payment method. Should fail on `<address>.transfer` | |
*/ | |
receive() external payable { | |
uint256 a = 0; | |
while (a < 1500000) { | |
a = a + 1; | |
} | |
_makePayable(owner()).transfer(msg.value); | |
} | |
/** | |
* @dev Claim the money as the owner. | |
* @param _escrowAddress address of the contract escrowing the money to be claimed | |
*/ | |
function claimMoney(address _escrowAddress) external onlyOwner { | |
ChimeraMarketAuctionV2(_escrowAddress).withdrawPayments( | |
_makePayable(address(this)) | |
); | |
} | |
/** | |
* @dev Place a bid for the owner | |
* @param _newBidAmount uint256 value in wei to bid, plus marketplace fee. | |
* @param _originContract address of the contract storing the token. | |
* @param _tokenId uint256 ID of the token | |
* @param _market address of the marketplace to make the bid | |
*/ | |
function bid( | |
uint256 _newBidAmount, | |
address _originContract, | |
uint256 _tokenId, | |
address _market | |
) public payable { | |
ChimeraMarketAuctionV2(_market).bid{value: msg.value}( | |
_newBidAmount, | |
_originContract, | |
_tokenId | |
); | |
} | |
///////////////////////////////////////////////////////////////////////// | |
// _makePayable | |
///////////////////////////////////////////////////////////////////////// | |
/** | |
* @dev Internal function to set a bid. | |
* @param _address non-payable address | |
* @return payable address | |
*/ | |
function _makePayable(address _address) | |
internal | |
pure | |
returns (address payable) | |
{ | |
return address(uint160(_address)); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity 0.6.12; | |
import "./ChimeraMarketAuctionV2.sol"; | |
contract TestRequireFailOnPay { | |
/** | |
* @dev A payment method that will fail by a failed require | |
*/ | |
receive() external payable { | |
require(false, "ready to fail!!!"); | |
} | |
/** | |
* @dev Place a bid for the owner | |
* @param _newBidAmount uint256 value in wei to bid, plus marketplace fee. | |
* @param _originContract address of the contract storing the token. | |
* @param _tokenId uint256 ID of the token | |
* @param _market address of the marketplace to make the bid | |
*/ | |
function bid( | |
uint256 _newBidAmount, | |
address _originContract, | |
uint256 _tokenId, | |
address _market | |
) public payable { | |
ChimeraMarketAuctionV2(_market).bid{value: msg.value}( | |
_newBidAmount, | |
_originContract, | |
_tokenId | |
); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity 0.6.12; | |
import "./ChimeraMarketAuctionV2.sol"; | |
contract TestRevertOnPay { | |
/** | |
* @dev A payment method that will fail by a failed revert | |
*/ | |
receive() external payable { | |
revert("Will always"); | |
} | |
/** | |
* @dev Place a bid for the owner | |
* @param _newBidAmount uint256 value in wei to bid, plus marketplace fee. | |
* @param _originContract address of the contract storing the token. | |
* @param _tokenId uint256 ID of the token | |
* @param _market address of the marketplace to make the bid | |
*/ | |
function bid( | |
uint256 _newBidAmount, | |
address _originContract, | |
uint256 _tokenId, | |
address _market | |
) public payable { | |
ChimeraMarketAuctionV2(_market).bid{value: msg.value}( | |
_newBidAmount, | |
_originContract, | |
_tokenId | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment