Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Add EIP-6105: Marketplace extension for EIP-721 #6105

Merged
merged 17 commits into from
Feb 12, 2023

Conversation

lambdalf-dev
Copy link
Contributor

When opening a pull request to submit a new EIP, please use the suggested template: https://github.com/ethereum/EIPs/blob/master/eip-template.md

We have a GitHub bot that automatically merges some PRs. It will merge yours immediately if certain criteria are met:

  • The PR edits only existing draft PRs.
  • The build passes.
  • Your GitHub username or email address is listed in the 'author' header of all affected PRs, inside .
  • If matching on email address, the email address is the one publicly listed on your GitHub profile.

@github-actions github-actions bot added c-new Creates a brand new proposal e-number Waiting on EIP Number assignment s-draft This EIP is a Draft t-erc labels Dec 8, 2022
@eth-bot
Copy link
Collaborator

eth-bot commented Dec 8, 2022

All reviewers have approved. Auto merging...


// VIEW
function getAllListings() external view returns ( Listing[] memory ) {
uint256 arraylen = saleItems.length;
Copy link

@numtel numtel Dec 11, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it be better to have pagination? If the marketplace is very large or if accessing the data from another contract when gas cost would matter, it is very important to be able to limit the scope.

And change the salesItems contract property to be of Listing type so that the code is much simpler.

function getListings(uint startIndex, uint fetchCount) external view returns(Listing[] memory) {
  uint itemCount = salesItems.length;
  if(itemCount == 0) {
    return new Listing[](0);
  }
  // Error if starting after end
  require(startIndex < itemCount);
  // Trim if fetchCount goes beyond the upper bound
  if(startIndex + fetchCount >= itemCount) {
    fetchCount = itemCount - startIndex;
  }
  Listing[] memory out = new Listing[](fetchCount);
  for(uint i; i < fetchCount; i++) {
    out[i] = salesItems[startIndex + i];
  }
  return out;
}

Copy link

@offgridgecko offgridgecko Dec 12, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Except it's not accessing data from "another contract." That would defeat the entire purpose of the code. You might be right that putting some kind of index basis on it could be helpful, as could adding some kind of fetch or get that limits by the cost of the listings or any other criteria you see fit. So perhaps the better solution would be to remove getAllListings from the EIP and leave it up to the developer to create sorting algorithms.
The other way would be to include such searches in here to make it more universal for front-end searches so that aggregators will have a better interfact to gather data from a wide number of compliant collections.

I will look into salesItems again. There was some reason it was set up for tokenId rather than the actual struct and for brevity sake we wanted to provide a solution to customers immediately who did not wish to comply with OpenSeas blacklist functionality but still wanted to have control of their own nfts on their own marketplace. Will look into that more this morning to see about cleaning things up.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've updated salesItems array like you mentioned. There were some other conflicts when I initially wrote the code but they have resolved themselves now. There still exists two mappings to track indexes for individual tokens to avoid the need to loop through the whole array, and the return values are now much cleaner for the current two fetch functions.
Your method of fetching several at a time should also be feasible, but I have not implemented it yet.

I've tasked @lambdalf-dev with updating the code here on the EIP, it should be updated shortly. Also includes removal of a bug that I found while retesting the codebase.

@offgridgecko
Copy link

Just want to add this in here, I know there are links, but the purpose and intent of the EIP:

#1. Create and internal mechanism to list, delist, and purchase NFTs on a secondary marketplace that is built into the smart contract such that both the marketplace and royalties are on chain, transparent, and under the complete control of the artist/team releasing the NFT, so that even if every public aggregator or marketplace fails, or their policies are such that the creator wishes to disallow listing on their platforms, there will always be a built-in method for trading tokens built directly into the smart contract.

#2. Creators maintain the right (with additional code) to fully restrict access from not only public marketplaces, but potential scammers who are trying to fool unsuspecting holders into signing approveForAll(), because only a limited number of contracts or wallets would in that case have access to approve() and setApprovalForAll() functionality. In that case this EIP provides a standard marketplace that the original creator can maintain and ensure safe transactions for their user.

#3. By avoiding centralized marketplaces, there is no need for a separate approval() call before a transaction, therefore saving gas that would normally be associated with "handling" NFTs on behalf of the user.

#4. The code should be as open and non-restrictive as possible, allowing any aggregator who wishes to probe the contract for current listings while at the same time allowing the developer to tune the marketplace to whatever specific functionalities they would want to make their front-end code more responsive and in-line with their goals.

#5. The methods should be as separate from the traditional market functionality of ERC721 as possible so that the code in it's virgin form is 100% compliant with current ERC721 standard.

-- Side note: The question of HOW the methods of this EIP accomplish the given task is not as important as coming up with a standard interface to interact with several different types of code-specific implementations. The question was raised about pulling a portion of the data rather than one item or all items. My reasoning for setting up those two functions was to ensure that we could limit the number of calls required from the front-end to get a comprehensive list of tokenIds and prices, as calls from JavaScript code will likely be made through the injected wallet, and thus the process is slow and cumbersome with multiple calls.
For specific applications, the events included in the EIP would give APIs finer control over what they could be pulled from PHP or any other kind of back-end functionality using API calls.

@numtel
Copy link

numtel commented Dec 13, 2022

I think the most important point about this implementation is that it is an extension to the ERC721 standard.

What is the core goal though? To create an on-chain NFT marketplace.

I feel like increasing the size of the already lengthy ERC721 contract is not the best approach. You're also then limited to only new contracts, it doesn't pull in support for legacy ERC721 contracts.

Why not create an ERC721Marketplace instead of an ERC721MarketplaceExtension? This could allow tokens from multiple contracts. The way I see it, the only reason this EIP would make sense as a standard is if it was an extension to the token standard as you describe it, requiring each token contract to implement the feature. Specific applications could use an allow/deny list of token contracts.

You don't get the gas savings from not needing an approval but if it's really desired, EIP-4494 could be implemented on the contract.

interface ERC721Marketplace {
  struct Listing {
    address tokenContract;
    uint256 tokenId;
    uint256 tokenPrice;
    address to;
  }
  // perform transferFrom to this contract while tokens is for sale
  function listItem( Listing item ) external;
  // transfer token back to its original owner
  function delistItem( address tokenContract, uint256 tokenId ) external;

   ...
}

With this kind of system, any ERC721 token could be traded on the marketplace. Of course, a token contract could deny transfer to marketplaces it doesn't like so that point of control is still there.

Correct me if I'm missing something but there's no reason to make a ERC standard for a ERC721Marketplace like there is with ERC721MarketplaceExtension since it would support all token contracts. You can just build the application and try to attract users.

This is the same architectural distinction I realized with arbitrable-wrappers instead of going with something that updates the ERC20 standard like ERC20R

One more thought, another potential feature could be purchasing an NFT with another NFT, a kind of swap.

@lambdalf-dev
Copy link
Contributor Author

Why not create an ERC721Marketplace instead of an ERC721MarketplaceExtension? This could allow tokens from multiple contracts. The way I see it, the only reason this EIP would make sense as a standard is if it was an extension to the token standard as you describe it, requiring each token contract to implement the feature. Specific applications could use an allow/deny list of token contracts.

The real problem we're trying to solve with this proposal is putting projects at risk of finding themselves completely unable to have trades because of the Open Sea Filter Registry. Whether we accept it or not, this thing exists and needs to be dealt with. The way we view it, Open Sea is officially saying "We believe only us should be able to determine who can trade your tokens and how". It is in our opinion an attack to the concept of liberty. That's why we want to add this functionality to the ERC721 standard, therefore taking back that control from Open Sea and giving it back to the creators. If this functionality is given to a different contract, Open Sea still has the power to shut it down.

@numtel
Copy link

numtel commented Dec 13, 2022

The Open Sea filter is your inciting incident and that's totally fine. What I'm trying to say is that that you would have better UX and inclusivity by not making this an extension and instead making a fully on-chain marketplace that can support any ERC721 contract.

If the marketplace is an extension, that means it on works with token contracts that are new, aware of this EIP, and have enough space remaining in their 24kb bytecode limit to implement the features. It also means that the marketplace must be fully designed at time of token deployment. Anybody with existing NFTs would not be able to move away from Open Sea. There's no backwards compatibility.

This would be cumbersome and ignores the great composability of Ethereum contracts. Not every application has to be an ERC standard and that's fine.

@offgridgecko
Copy link

The point of this is not to create ANOTHER marketplace contract. There are several of those already in existence and as far as backwards compatibility, this code block still meets the requirements to satisfy those avenues.

The whole concept here is to do something new and different that allows for a simple trading mechanic built onto the contract.

You're basically saying, this is okay, but it would be better if it was <completely different thing that requires it's own setup/execution/resolve and associated codebase>

This was not designed to be a replacement for OpenSea, LooksRare, X2Y2, or any other existing marketplace. "Fully on-chain marketplaces" already exist and they cater to any ERC721. Why would we need to make a new version of that? What purpose would it serve? These are rhetorical questions btw and beyond the scope of this topic.

The purpose of this EIP is an on-contract secondary trade system that will continue to work and if the artist/team/community so chooses, they can build this out where their internal marketplace is the only functional sales avenue short of direct wallet-to-wallet transfers. Or it can play along with regular marketplaces.

To answer you about the "market system needing to be set up ahead of time," actually it doesn't. You can list and buy NFTs directly on the smart contract.

I understand your point, but you are trying to say that this code could be the seed for a full marketplace contract and that is simply not the case nor what this was designed to facilitate.

As far as the bytecode limit, take a look at the code OS is requiring to guarantee royalties for creators and tell me again how we're limited on bytecode with already bloated ERC721 contracts. There are a lot of people that refuse to comply and this gives them an option for secondary trading that cannot be revoked by any third party source, including the idea you are referencing of just building another centralized marketplace.

@lambdalf-dev
Copy link
Contributor Author

If the marketplace is an extension, that means it on works with token contracts that are new, aware of this EIP, and have enough space remaining in their 24kb bytecode limit to implement the features. It also means that the marketplace must be fully designed at time of token deployment. Anybody with existing NFTs would not be able to move away from Open Sea. There's no backwards compatibility.

Actually, I would argue that it is fully backwards compatible as implementation or not of this standard doesn't prevent normal behavior of other existing contracts that would not be aware of its existence. It is simply providing additional functionalities for contracts that implement it.

@numtel
Copy link

numtel commented Dec 14, 2022

Sorry if I'm missing the point. I'm not blocking it, just trying to understand the use case.

The purpose of this EIP is an on-contract secondary trade system that will continue to work and if the artist/team/community so chooses, they can build this out where their internal marketplace is the only functional sales avenue short of direct wallet-to-wallet transfers. Or it can play along with regular marketplaces.

By making this a marketplace extension, it would be like having a Uniswap liquidity pool as an ERC 20 extension so if you wanted to trade that token, you would interact with the token contract itself. There's nothing about that goal that necessitates having the internal marketplace being in the same contract as the base token.

What are the advantages to this model vs the dexes we see in production?

I don't think I explained well enough what I meant by backwards compatible. There are many ERC 721 contracts already deployed on public chains that would not be able to benefit from this extension because it's part of the token contract itself.

@lambdalf-dev
Copy link
Contributor Author

lambdalf-dev commented Dec 14, 2022

Well, of course... how could a contract deployed before it existed benefit from it? The goal is to protect newly deployed contracts from the Open Sea Filter Regisry.
The advantage to using this model rather than an external marketplace is to ensure that your project marketplace can't be shut down by the bigger actors. As of now, Open Sea reserves the ability to shut down any marketplace they deem unworthy, forcing creators to choose between using their blacklist or not earning any royalties.

Now here's a scenario for you to better understand:
John creates a collection and chooses to implement the Open Sea Filter Registry, his collection can only be traded on OpenSea and x2y2. Then Open Sea decides that x2y2 doesn't qualify for their take on royalties and blacklists x2y2, John's collection becomes tradable only on Open Sea. If for any reason Open Sea then decided to block access to John's collection, there would not be any way to trade it anymore. But if John implemented this EIP, his collection would still be able to be traded, all John needs to do is create that frontend to cover the basic usage and he is set.
An external marketplace would not be able to protect John because Open Sea would still have the ability to block it entirely.

@lambdalf-dev lambdalf-dev dismissed a stale review via e0eadc4 December 14, 2022 15:34
@offgridgecko
Copy link

Sorry if I'm missing the point. I'm not blocking it, just trying to understand the use case.

The purpose of this EIP is an on-contract secondary trade system that will continue to work and if the artist/team/community so chooses, they can build this out where their internal marketplace is the only functional sales avenue short of direct wallet-to-wallet transfers. Or it can play along with regular marketplaces.

By making this a marketplace extension, it would be like having a Uniswap liquidity pool as an ERC 20 extension so if you wanted to trade that token, you would interact with the token contract itself. There's nothing about that goal that necessitates having the internal marketplace being in the same contract as the base token.

What are the advantages to this model vs the dexes we see in production?

I don't think I explained well enough what I meant by backwards compatible. There are many ERC 721 contracts already deployed on public chains that would not be able to benefit from this extension because it's part of the token contract itself.

Thanks first of all for the continued follow-up and dialogue. I realize this is (or seems like) a niche application and it is one that I've already onboarded a few people with who don't care if it's accepted as a standard. They want the plugin, so it's important to be clear in these discussions on what it is and is not. I'm sorry if I haven't been able to fully demonstrate this purpose yet, so I'll attempt to hone in on these questions.

The main priority here is that any centralized exchange or NFT DEX is going to suffer from the same inherent problem that there is always some entity that is not the CREATOR (lets define as artist/team/whatever) who maintains direct control over the payment of royalties, and authority to manage those royalties.

This proposal outlines an alternative, a truly decentralized methodology that each CREATOR controls 100% through their own smart contract, and an internal mechanism to list/delist/trade NFTs within the scope of the contract itself, instead of relying on a third party that might have values that conflict with the CREATOR.

One CREATOR in particular that I've been talking to has decided directly that they don't want their NFT traded on OpenSea's platform at all, and will be using the Registry Filter to block OpenSea from trading their token. These disagreements may be over royalties, company transparency, or any other conflict of interest that might arise between the CREATOR and the Marketplace.

In the unfortunate event that the CREATOR cannot find common ground with existing marketplaces, it would fall on them to implement their own marketplace, which would require handling of tokens on the customer's behalf, and short of a community wallet to handle direct transfers, approvals would need to be set and that sets into motion this cat/mouse game of marketplaces blacklisting any handler of tokens when an even occurs through the use of approve() or approveAll() (assuming they utilize the Registry and then change their mind later).

I admit that this situation is probably an unlikely fringe case, but from a CREATOR perspective what this code does is give them an easy mechanism to host a marketplace for their own tokens regardless of whether they choose to invoke registry or not. And I've also provided broilerplate code that allows them to easily copy a simple HTML page and brand it to fit their project, which interacts with this smart contract code.

Another potential advantage here is the move away from defacto marketplaces and the introduction of aggregator websites which might act as both a marketplace for legacy ERC721 contracts that wish not to implement this while also allowing a simple interface for collections that do implement the code to showcase their work and even trade it without any approvals required, thus the "aggregator/marketplace" eliminates liability and security problems for themselves, though a new business model would obviously needed to round out such a niche.

All of this can be done completely trustlessly, without the need to set approvals and put trust in a marketplace that they will not mishandle the NFTs, they will not attempt to skirt the royalty scheme or other requirements imposed by the CREATOR, and they will have no functional control over the movement of NFTs from one wallet to another at all.

Every time approve() or setApprovalForAll() are invoked, there exists the potential for foul play. This contract update, especially if paired with another use case listed below, would ramp up security for both customers and CREATORs, as well as ensure that the CREATOR is in charge of their own collection forever, without having to worry about surprise mandates that we've seen over the last several months from companies like LooksRare, X2Y2, OpenSea, and others.

This is all part one

Part II involves the implementation if an internal registry filter of sorts, which is not part of this particular EIP but it is important to understand, whereby the CREATOR can whitelist on their own contract exactly which marketplaces and other contracts will have access to approval functions, and in such case also act as a security measure to protect against probably the most common scam of the day, which is tricking an end user into signing an ApproveAll function. Were such a whitelist implemented, and internal secondary marketplace might provide the ONLY source of trading the NFT on secondary, which seems against the current web3 ethos, but there are niche cases and we have seen them where this is desired for one reason or another to keep trades "inside the community" so to speak. I seem to remember TopShots or a related project doing something like this at the start of 2021.

This added security of allowing only authorized users to issue approvals is an accidental security fix that we found while testing this kind of implementation, and it immediately struck a chord with Chameleon Collective Team and other founders and something worth looking into for future contracts.

/// - Caller must own `tokenId`
/// - Must emit a {Listed} event.
///
function listItem( uint256 tokenId, uint256 price, address to ) external;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to see this feature support multiple currencies.

Existing marketplaces support creating a sale in ETH or a stablecoin. It's common for NFT ecosystems to create their own tokens that they would like to use for this purpose.

Adding a paymentTokenAddress would add arbitrary ERC20 support to the marketplace, allowing the seller to peg the price to any ERC20.
This would also support projects that want to allow only a subset of ERC20s for sale as they can whitelist ERC20 addresses in their implementation.
This doesn't preclude selling in ETH as address(0) can be used to indicate a sale price in ETH.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curious... I think it's a good idea in theory, but it would add some more to the codebase.

We intentionally left the feature-set a little light to leave expansion decisions on the Creator and they could add whatever they needed. Making it a requirement, if it could be done efficiently would be nice. I mean a simple check on the payment for eth sent with the transfer and if not then try to transferFrom with whatever contract information, sounds simple enough.

In that case, if the creator chose to implement those other tokens they could do so easily and if they decided not to then they could leave the base option out. ...

I see some promise in this idea and have been thinking about it since I saw the post earlier, I was away from my computer and busy with other things. Definitely something worth considering. Thank you for the comment and we'll spend some time discussing this.

My main worry would be small artist collections trying to build out a front end to accomodate, but hopefully we can just adapt the broiler code as well easily enough.

Thanks again, will give this some more thought.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good point, might be worth implementing...
Our initial thought was that the coin to pay with could be up to the project creator, but it would only allow for one type of payment to be used, whereas your idea allows for unlimited options, with more flexibility.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree. EIP should be as concise and general as possible.

@numtel
Copy link

numtel commented Dec 17, 2022

The advantage to using this model rather than an external marketplace is to ensure that your project marketplace can't be shut down by the bigger actors. As of now, Open Sea reserves the ability to shut down any marketplace they deem unworthy, forcing creators to choose between using their blacklist or not earning any royalties.

I understand these points completely. It makes good sense. The point I'm trying to express is that these marketplaces have no need to be on the same contract as the token.

The main priority here is that any centralized exchange or NFT DEX is going to suffer from the same inherent problem that there is always some entity that is not the CREATOR (lets define as artist/team/whatever) who maintains direct control over the payment of royalties, and authority to manage those royalties.

That's not true. And I think that assumption is why you're not understanding my point yet.

You could write an ownerless, unstoppable marketplace contract that respects EIP-2981 that would allow the creator to define their royalties and, if they trust this immutable contract, they can place it into their allow filter as an approved marketplace.

Or you could write a contract that accepts a token contract address in the constructor and use the token contract owner as the owner of the marketplace contract. This way they would be linked and the creator of the token would also have full control over any marketplace administrator functionality.

There are many ways to create a marketplace and these would all be useful templates for creators. Also, because there's so many ways to create these marketplaces, it's very helpful to be able to manage them separately from the tokens themselves.

Every time approve() or setApprovalForAll() are invoked, there exists the potential for foul play. This contract update, especially if paired with another use case listed below, would ramp up security for both customers and CREATORs, as well as ensure that the CREATOR is in charge of their own collection forever, without having to worry about surprise mandates that we've seen over the last several months from companies like LooksRare, X2Y2, OpenSea, and others.

This is really the only point that would necessitate putting the marketplace in the same contract as the token but you could have the token owner transfer the NFT directly to the marketplace themselves and use onERC721Received to record the original owner in the marketplace state, bypassing the need for an approval or a transferFrom. Also, there are things like Metamask Snaps that can give better messaging on the client for these kinds of safety issues.

I'm not trying to convince you to change the goal, I'm trying to increase the code quality.

@lambdalf-dev
Copy link
Contributor Author

You could write an ownerless, unstoppable marketplace contract that respects EIP-2981 that would allow the creator to define their royalties and, if they trust this immutable contract, they can place it into their allow filter as an approved marketplace.

Or you could write a contract that accepts a token contract address in the constructor and use the token contract owner as the owner of the marketplace contract. This way they would be linked and the creator of the token would also have full control over any marketplace administrator functionality.

Those suggestions both suffer from the same limitations though, they are subject to being blacklisted by OpenSea on a whim, which puts them at risk of being disabled if the contract implements the standard OpenSea filter registry, which by the way is very obscure to begin with.

@5660-eth
Copy link
Contributor

Amazing!It's so gratifying to have someone who thinks the same as us. We came up with the idea of No Intermediary NFT Trading Protocol a few months ago. However, since we were busy submitting EIP-6147 and hoped that No Intermediary NFT Trading Protocol can be compatible with EIP-6147, we have not yet submitted No Intermediary NFT Trading Protocol to eip. Here are some information for your reference.
https://ethereum-magicians.org/t/no-intermediary-nft-trading-protocol/12171
https://github.com/5660-eth/ERC721YY/tree/main

In the above code, we also consider implementing the makeoffer function. At the same time, it is recommended that we learn about the CryptoPunks market.
https://etherscan.io/address/0xb47e3cd837ddf8e4c57f05d70ab865de6e193bbb#code

I would like to ask if you would like us to be co-authors of EIP-6105, let us promote this eip together. We will be very happy if you agree.

@5660-eth
Copy link
Contributor

 > You could write an ownerless, unstoppable marketplace contract that respects EIP-2981 that would allow the creator to define their royalties and, if they trust this immutable contract, they can place it into their allow filter as an approved marketplace.

1.I understand that EIP6105 is to establish an intermediary-free NFT trading protocol to avoid a series of problems caused by possible evil in the intermediary trading market. Establishing another NFT intermediary trading market will not help solve the concerns of NFT creators. This approach only allows users to change from trusting one trading market to trusting another trading market, and does not fundamentally solve the problem. We recommend that you read this article to understand our point of view.
https://ethereum-magicians.org/t/no-intermediary-nft-trading-protocol/12171
2.In fact, I think the No Intermediary NFT Trading Protocol point of view is revolutionary. If creators can implement NFT trading functions in their own NFT contracts, then they have no intermediary, safer, 0 service fee, with network-wide liquidity and meet the project party of the copyright tax revenue, anti-censorship NFT trading protocol. So why do they need other NFT trading marketplaces?

@offgridgecko
Copy link

offgridgecko commented Dec 19, 2022

. At the same time, it is recommended that we learn about the CryptoPunks market. https://etherscan.io/address/0xb47e3cd837ddf8e4c57f05d70ab865de6e193bbb#code

I would like to ask if you would like us to be co-authors of EIP-6105, let us promote this eip together. We will be very happy if you agree.

Find me on twitter ;) @offgridgecko or @spottedgeckgo should work. send me a note about this so I know who you are. I'm also on discord @ OffGridGecko #9999

@offgridgecko
Copy link

responding to @5660-eth :
Yes, reach out to me on twitter or discord first off. Will look into this.

On the point of "make offer," we actually went back and forth on this for a while, then I asked, who does it benefit? The answer is flippers and bots, which is not in the spirit of the original purpose of this EIP. We eventually agreed that offers could be added easily enough by the individual coder-project, but we didn't want to bulk up the code with methods for making standing offers that would be accepted/rejected/etc while the item is listed.

I designed this to help artists create their own internal marketplaces for their art that stood in the face of current marketplace options and manipulations, and obviously scammers love the offer option as well.

In the end, we dumped the idea and decided to keep things as simple as possible and just let the project decide on any upgrades while still making the options for selling on the contract available to 3rd party aggregator websites.

As you stated, the primary goal here is avoiding centralized marketplaces and specifically dodging OpenSea's little consortium from blocking sales on other marketplaces. "Not your marketplace, not your royalties" was pretty much my driving motivation from the start.

@5660-eth
Copy link
Contributor

5660-eth commented Dec 19, 2022

@offgridgecko I messaged you on twitter.
At first, for the sake of simplicity, we did not design the makeOffer function,too. But I think we'd better do some research to see if creators and users like this function.listing and makeOffer can improve NFT liquidity, and we don't need to be biased against this. One of my concerns about the makeOffer function is that it will store a lot of ETH for quotation in the NFT's own contract, which may not be safe.We can discuss further.

Comment on lines 248 to 253
function listItem( uint256 tokenId_, uint256 price_, address buyer_ ) external {
address _tokenOwner_ = ownerOf( tokenId_ );
require( _tokenOwner_ == ownerOf( tokenId_ ), "Not token owner" );

_createListing( tokenId_, price_, _tokenOwner_, buyer_ );
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
function listItem( uint256 tokenId_, uint256 price_, address buyer_ ) external {
address _tokenOwner_ = ownerOf( tokenId_ );
require( _tokenOwner_ == ownerOf( tokenId_ ), "Not token owner" );
_createListing( tokenId_, price_, _tokenOwner_, buyer_ );
}
function listItem( uint256 tokenId_, uint256 price_, address buyer_ ) external {
address _tokenOwner_ = ownerOf( tokenId_ );
require( _tokenOwner_ == ownerOf( tokenId_ ), "Not token owner" );
_createListing( tokenId_, price_, _tokenOwner_, buyer_ );
}

Designated buyer does not seem to be used very often. If a particular buyer and seller privately agree on a trading price, they have multiple ways to complete the trading

Comment on lines 296 to 304
// VIEW
/**
* @notice Returns the list of all existing listings.
*
* @return the list of all existing listings
*/
function getAllListings() external view returns ( Listing[] memory ) {
return _listings;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function doesn't seem to work. solidity doesn't seem to support returning arrays?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll have to check that, I haven't had the time to do unit tests on the code suggested yet. Thanks for pointing it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@offgridgecko
Copy link

it will store a lot of ETH for quotation in the NFT's own contract, which may not be safe.We can discuss further.

Yes that's another reason we didn't pursue it. In order to secure funds, they would need to be stored on the smart contract to ensure payment... I'm not sure anyone is keen on actually "putting their money up" but then again such a mechanic would make it less prone to botspam.

Basically, without adding a lot of code, I dunno if it should be included in this EIP, but the option is there for people to extend the EIP with that mechanic.

@github-actions github-actions bot added w-ci Waiting on CI to pass and removed e-number Waiting on EIP Number assignment labels Jan 16, 2023
@Pandapip1 Pandapip1 changed the title Proposal for ERC721 Marketplace extension Add EIP-6105: Marketplace extension for EIP-721 Jan 25, 2023
@github-actions
Copy link

The commit dd01c64 (as a parent of ba8c6fa) contains errors.
Please inspect the Run Summary for details.

EIPS/eip-6105.md Outdated Show resolved Hide resolved
EIPS/eip-6105.md Outdated Show resolved Hide resolved
EIPS/eip-6105.md Outdated Show resolved Hide resolved
EIPS/eip-6105.md Outdated Show resolved Hide resolved
EIPS/eip-6105.md Outdated Show resolved Hide resolved
EIPS/eip-6105.md Outdated Show resolved Hide resolved
EIPS/eip-6105.md Outdated Show resolved Hide resolved
EIPS/eip-6105.md Outdated Show resolved Hide resolved
EIPS/eip-6105.md Outdated Show resolved Hide resolved
EIPS/eip-6105.md Outdated Show resolved Hide resolved
@github-actions github-actions bot removed the w-ci Waiting on CI to pass label Jan 25, 2023
EIPS/eip-6105.md Outdated Show resolved Hide resolved
5660-eth and others added 7 commits January 25, 2023 23:38
Co-authored-by: Pandapip1 <45835846+Pandapip1@users.noreply.github.com>
The rationale can only be updated once the interface and reference implementation have been identified
Update Specification, Rationale and Reference Implementation.
@5660-eth
Copy link
Contributor

5660-eth commented Feb 9, 2023

Hi, @Pandapip1, @SamWilsn, @axic, @xinbenlv. Do you have time to review and merge this EIP? Previously reported issues have been resolved.Thanks

Copy link
Member

@Pandapip1 Pandapip1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The event names are a bit odd with the Log prefix, and I'm not a fan of referencing OZ. But apart from that, LGTM.

@eth-bot eth-bot enabled auto-merge (squash) February 12, 2023 18:18
@eth-bot eth-bot merged commit 2068244 into ethereum:master Feb 12, 2023
@5660-eth
Copy link
Contributor

The event names are a bit odd with the Log prefix, and I'm not a fan of referencing OZ. But apart from that, LGTM.

There is a viewpoint that adding Log in the event name makes it more clear, but perhaps Log is not important.

iseriohn pushed a commit to iseriohn/EIP-NFT-Rights-Management that referenced this pull request Feb 16, 2023
* Proposal for ERC721 Marketplace extension

* Update code examples, Fix some linting issues

* Update and rename eip-erc721-marketplace-extension.md to eip-6105.md

* Update eip-6105.md

* Update eip-6105.md

* Commit necessary changes

* Update eip-6105.md

* Apply suggestions from code review

Co-authored-by: Pandapip1 <45835846+Pandapip1@users.noreply.github.com>

* Update eip-6105.md

* Update interface and reference implementation

The rationale can only be updated once the interface and reference implementation have been identified

* Update eip-6105.md

* Update eip-6105.md

* Update eip-6105.md

Update Specification, Rationale and Reference Implementation.

* Update eip-6105.md

---------

Co-authored-by: 5660.eth <76733013+5660-eth@users.noreply.github.com>
Co-authored-by: Pandapip1 <45835846+Pandapip1@users.noreply.github.com>
@lambdalf-dev lambdalf-dev deleted the ERC721-marketplace-extension branch February 27, 2023 14:44
fulldecent pushed a commit to fulldecent/EIPs that referenced this pull request Mar 13, 2023
* Proposal for ERC721 Marketplace extension

* Update code examples, Fix some linting issues

* Update and rename eip-erc721-marketplace-extension.md to eip-6105.md

* Update eip-6105.md

* Update eip-6105.md

* Commit necessary changes

* Update eip-6105.md

* Apply suggestions from code review

Co-authored-by: Pandapip1 <45835846+Pandapip1@users.noreply.github.com>

* Update eip-6105.md

* Update interface and reference implementation

The rationale can only be updated once the interface and reference implementation have been identified

* Update eip-6105.md

* Update eip-6105.md

* Update eip-6105.md

Update Specification, Rationale and Reference Implementation.

* Update eip-6105.md

---------

Co-authored-by: 5660.eth <76733013+5660-eth@users.noreply.github.com>
Co-authored-by: Pandapip1 <45835846+Pandapip1@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c-new Creates a brand new proposal s-draft This EIP is a Draft t-erc
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants