Few and Far NFT Specification

Hi NEAR Community,

We wanted to share some technical specifics on the Few and Far NFT Specification, a fully backwards-compatible extension of NEP-171. The below information can also be found on Medium here.

At Few and Far, we want to provide the best NFT experience possible for creators, collectors and traders. This means giving creators control over their NFT businesses , with the ability to enforce sale rules such as royalty payouts. For collectors and traders, this means creator transparency and fast NFT sales .

Currently, with NEAR’s NEP-199 Approvals standard, the NFT contract is responsible for transferring NFTs to a new owner, but the actual sale transaction — the flow of funds — is always processed via a 3rd party (e.g. a marketplace contract). On a sale, at a request from a 3rd party contract approved by the seller, the NFT contract transfers the NFT to the new owner, and specifies the royalty amounts that should be paid out.

However, the 3rd party contract has no obligation to pay out these royalties , and as we have seen recently on Solana, we cannot rely on marketplaces to “do the right thing” by paying out the royalty holders. Marketplaces are businesses, and once one marketplace stops paying out royalties thereby offering larger payouts to sellers, other marketplaces will start to lose market share, and it becomes a slippery slope and a race to the bottom.

The Few and Far NFT Specification (an extension of NEAR’s NEP-171 Standard) solves this problem as follows:

  1. The NFT contract can manage listings and sales itself (“native” listings), without the need for a trusted 3rd party
  2. If the creator (contract owner) chooses, legacy 3rd party approvals can be enabled, providing full compatibility with the existing NEP-199 Approvals standard.
  3. If the creator chooses to enable legacy approvals, they can further specify allowed &/or denied marketplace accounts that are permitted to process NFT sales, enabling them to allow specific marketplaces of their choosing or deny marketplaces that don’t play nice.

Importantly, NFT sales via the proposed “native” listings are at least 3x faster than the legacy equivalent, because they always complete in a single block. The legacy approvals standard takes a minimum of 3 blocks, and could take longer if block space is in high demand! Native listings and sales have important implications when it comes to high-speed use cases like gaming, but also will result in a noticeable performance improvement for regular collectors and traders.

Long story short: we believe this specification is a necessary and important step forward for the NFT community.

Let’s dig in and see how it works!


:moneybag: LISTING

pub struct Listing {
    pub amount: U128,
}

An NFT owner can list their NFT natively on the NFT contract by calling the list() method. This creates and stores a Listing for the specified amount, and broadcasts this listing via an nft_listing event. By natively listing their NFT, the seller is guaranteed that they will receive the amount specified in the listing, minus any royalties.

This standard supports one native listing per NFT. To update the native listing for their NFT, the owner calls the list() method; this will replace any existing listing with the updated listing.

To remove a native listing, the owner should call the remove_listing() method. This will remove an existing listing and broadcast this via an nft_remove_listing event.

NB: Support for non-NEAR tokens (e.g. an ft_token_id) will be added in a future version of this specification.

list():

fn list(
    &mut self,
    token_id: String,
    amount: U128,
) -> Listing;

The list() method acts as follows:

  • Can only be called by owner of specified NFT
  • Verifies that caller has attached exactly 1 yoctoNEAR for security purposes
  • Adds a Listing for this NFT (remember — only one listing is allowed per NFT, so this method will override any existing listing for this NFT. This means that it doubles as an “update” method!)
  • Emits nft_listing event (see below)
  • Returns new Listing
// nft_listing event
{
    "standard": “fnf007”,
    "version": "1.0.0",
    "event": "nft_listing",
    "data": { owner_id, token_id, amount }
}

remove_listing():

fn remove_listing(
    &mut self,
    token_id: TokenId,
) -> Listing;

The remove_listing() method acts as follows:

  • Can only be called by owner of specified NFT
  • Verifies that caller has attached exactly 1 yoctoNEAR for security purposes
  • If listing exists for this NFT, removes it and emits nft_listing_remove event (see below)
// nft_listing_remove event
{
    "standard": “fnf007”,
    "version": "1.0.0",
    "event": "nft_listing_remove",
    "data": { owner_id, token_id }
}

:money_with_wings: BUYING

Anyone can buy an NFT that has been listed natively by calling the buy() method.

In order to allow marketplaces to add a platform fee on top of an NFT’s listing price, an optional referrer parameter can be included that specifies an id of an account that facilitated the sale, and an amount that this account should receive. This amount is added on top of the listing price at the time of purchase , and the deposit sent with the transaction should cover the listing price plus any specified referrer amount.

pub struct Referrer {
    amount: U128,
    id: AccountId,
}

An optional receiver_id parameter can be included if the NFT should be transferred to a different account than the method caller.

buy():

fn buy(
    &mut self,
    token_id: TokenId,
    referrer: Option<Referrer>,
    receiver_id: Option<AccountId>,
);

The buy() method acts as follows:

  • Verifies that a Listing exists for this NFT, and that the attached deposit is greater than (or equal to) the listing amount
  • If no receiver_id is specified, receiver of NFT will be env::predecessor_account_id()
  • Transfers NFT to new owner
  • Sends payouts to royalty holders and seller (seller is guaranteed to receive listing amount minus royalties)
  • If referrer is specified and deposit includes funds for referrer, sends the referrer amount to the referrer id
  • Returns any remaining funds to method caller
  • Removes Listing
  • Emits nft_listing_remove event (see above)
  • Emits nft_transfer event (as per NEP-171’s NftTransferLog )
  • Emits nft_sale event (see below)
// nft_sale event
{
    "standard": “fnf007”,
    "version": "1.0.0",
    "event": "nft_sale",
    "data": { token_id, amount, seller_id, buyer_id }
}

And that’s it for the native listing functionality! The Few and Far NFT Specification contains other exciting updates, such as providing a utility promise directly on the NFT collection and allowing NFT holders to rate the collection on-chain, and we look forward to sharing these details in upcoming posts!

We look forward to hearing your feedback here. :blush: Additionally, our DMs are always open. Follow us on Twitter &/or jump into our Discord - we’d love to hear from you!

9 Likes

Thanks for sharing this Lachlan!

I’ve just forwarded it to a couple of technical friends who operate more closely to NFTs.

Would love to see more teams also sharing and engaging at a technical and product level on the governance forum.

4 Likes

Interesting proposal and I really appreciate this concept. I like that a user could directly list from a wallet or other dapp.

Can the user still trade OTC without triggering some buy/sell method? Also could any entity act as the referrer?

Also are there concerns with compatibility with cross-chain solutions like wormhole, layer zero, IBC, etc?

2 Likes

Hey there @joe-rlo, thanks for the comment!

Yes, regular transfers are still enabled so OTC is possible. However, we believe that for NFTs referencing important IP, provenance will be damaged by regular transfers and therefore the resale value of the asset will diminish with OTC trades like this. This should discourage OTC trades.

In case this mechanic doesn’t operate as we expect, we have provided an option for the contract owner to disable traditional transfers for a collection via nft_transfer(), thereby enforcing NFT transfers via the buy() method.

Yes, any valid NEAR account can act as the referrer.

We expect to build this into a cross-chain specification, so any mirroring NFT contracts that we deploy to other chains would implement this specification. As for which cross-chain solution we will implement (e.g. IBC vs. LayerZero), I think the jury is still out on the approach that will win out!

1 Like

Hey @lachlanglen love the innovation of token standards to try to solve this issue!

I’ll give this more thought but this wouldn’t apply to a NFT AMM I assume (ie. sudoswap)? It doesn’t really “list” the NFT.

Also, how much ownership of the token does the creator retain perpetually?

@starpause would be best to give opinions on this

1 Like

Hey @eviejugo I’m not too familiar with NFT AMMs, esp on NEAR, so can’t give too much guidance there.

how much ownership of the token does the creator retain perpetually

By “ownership” do you mean royalty percentage, or admin privileges for the contract? Royalty percentages are set and controlled only by the creator, and can be whatever the creator wishes. The creator also has admin privileges for collections within the contract and can add other owners (e.g. team members) that have admin roles.

Good question on the AMM. @lachlanglen To clarify this, can the NFT still go into escrow with the list function or does that need a new method to support?

I love the spirit of innovation. The F&F proposal is a great custom proposal for your own project and other partnering projects, but should not become a NEP standard as it will not scale and will add a boat-ton of complexity for dapps, wallets, and markets.

When I built Mintbase in 2018 on Ethereum, putting the buy function on the NFT contract itself is exactly the same path I went. I was able to deploy over 1,100 ETH NFT contracts totaling over 88k transactions using this system. Seemed like the right call, you could mint and list all in one operation. However, this only really works for isolated trusted systems as there is no way an interoperable market like OpenSea would just throw money into one of our 1,000 contracts and hope Mintbase handles all the payments correctly.

What F&F suggests leads to the following: You would have to white-list everything, and even then those white-listed contracts could just update and take the money and run or simply break from bad code, leaving a trusted market vulnerable at every payout (no market would actually do this at scale). Yes, Mintbase could build trust with OS, show them our audits and maybe get white-listed, but this sort of ruins the amazing world of interoperability.

The OpenSea model is revolutionary, not legacy. Anyone can deploy their own NFT contract using OpenZeppelin and get automatically listed on OpenSea as long as their NFT complies with the basic ERC-721 standard (balanceOf, ownerOf, transferFrom, approve… etc). OS’s payout contract is audited, battle tested, and can increase in complexity and innovation with bonding curves and so on over time vs trusting hundreds of thousands of contracts to handle payouts in their own way. IMO this is going back to the old “legacy” model of only trusting selected partners or risk just opening it up to chaos that would be a brittle transfer-transferless, approval, no-approval mess.

If NEAR really does this NFT thing right, it should not just be a few minting platforms that we have to whitelist (Paras, Apollo42, F&F, Mintbase), people should be firing up their own contracts like wildfire and this is what made the OpenSea ecosystem thrive.

There’s the idea that it’s backwards-compatible, but making a standard to disable standard functions approval or transfer is a direct conflict with NEP 171.

Lastly, I don’t think NEAR has a royalty issue. We might be trying to solve a problem to simply get some marketing efforts off the ground to pull Solana users over, which I am fine with, but at the cost of unnecessary complexity. If we make this a standard, it might get some giggles from other NFT communities as it sort of takes us backward. Mintbase pushed along with BlackBoxDotArt, to get the Payouts and Royalty NEP-199 standards in there and made it as simple as possible for markets to issue and comply, reducing excuses. If a market decides not to comply, then let the users vote with their time and money to go somewhere else.

On the transfer removal issue, if you are thinking of the soulbound argument, we are actually getting that back off the ground, making it its own new breed of token called the SBT so indexers can clearly distinguish the desired behavior. Excited for @JasperTimm to get that out the door.

We should also note that F&F are forking the NEP standard, see the “standard”: “fnf007” vs “nep007”. This can be pretty divisive and confusing in an already complex world, just need the community to be aware.

{
    "standard": “fnf007”,
    "version": "1.0.0",
    "event": "nft_sale",
    "data": { token_id, amount, seller_id, buyer_id }
}
1 Like

Hey @nategeier, thanks for the feedback!

“This only really works for isolated trusted systems as there is no way an interoperable market like OpenSea would just throw money into one of our 1,000 contracts and hope Mintbase handles all the payments correctly.”

I understand what you’re saying, but there is already trust being placed in the NFT contract (e.g. that the NFT will actually be transferred to the buyer), so I don’t really agree with your concern here. Parties that profit from or invest into NFT contracts either trust the NFT contract (made possible on Ethereum by tools like OpenZeppelin), or they don’t. I don’t think there’s a middle ground.

“What F&F suggests leads to the following: You would have to white-list everything, and even then those white-listed contracts could just update and take the money and run or simply break from bad code, leaving a trusted market vulnerable at every payout (no market would actually do this at scale).”

Are you saying that a marketplace would have to white-list every NFT contract? I disagree. It’s not in the interests of an NFT contract to “take the money and run” e.g. not pay out the seller, just like it’s not in the interests of a marketplace to do the same. And plenty of NFT contracts already “simply break from bad code” (especially without an OpenZeppelin equivalent), native listing and sale functionality aside.

What you can do as a marketplace is choose whether you support only legacy approvals-based listings, or native listings as well. I think creators and collectors will show us which format they prefer, and it may well vary by genre (e.g. I imagine the trading speed made possible by native listings will be very popular for gaming projects).

“IMO this is going back to the old “legacy” model of only trusting selected partners or risk just opening it up to chaos that would be a brittle transfer-transferless, approval, no-approval mess.”

If giving creators and collectors more options for enforced sale rules and faster trades creates a “brittle mess”, maybe that is a flaw in the designs that have brought us this far?

“If a market decides not to comply, then let the users vote with their time and money to go somewhere else.”

Let’s say the users that we choose to care about are the creators. How will they choose to “go somewhere else” without a change to the standard? The key difference with Few and Far is that we focus on the creators, and in doing so provide a better experience for both creators and traders. Other marketplaces risk focusing on the traders at the expense of the creators - and in my opinion, that destroys the promise of NFTs for creators in the first place.

“We should also note that F&F are forking the NEP standard, see the “standard”: “fnf007” vs “nep007”. This can be pretty divisive and confusing in an already complex world, just need the community to be aware.”

What do you propose that we do instead? You yourself noted that this “should not become a NEP standard” - and the awareness that this will not be immediately adopted across the ecosystem due to legacy marketplaces like yourselves, and that we are betting on a new and improved way of interacting with NFTs, is precisely the reason we aren’t trying to make it an NEP standard out of the gate.

“Lastly, I don’t think NEAR has a royalty issue.”

Agreed - but then again, NEAR barely has an NFT scene, and with unbalanced ratio of creators to traders it would be a death-warrant move for a marketplace to choose to stop honoring royalties. However, if the NEAR NFT scene goes where we think it is going (up), the time might come when one or more of our marketplaces does make royalties optional. And if it doesn’t, we’ll all be out of business anyway.

I want to stress as well that this is as much about time and complexity of NFT trades (reducing both by a large factor) as it is about giving creators the ability to enforce sale rules like royalties if they wish.

hey @joe-rlo & @eviejugo - it’s my understanding that NFT AMMs will utilize the nft_transfer method for an NFT owner to deposit their NFT into a pool contract. So assuming that the creator doesn’t disable transfers for a collection, this would still be possible.

As mentioned, I expect that traditional transfers will negatively affect the provenance of the NFT in the native listing paradigm; if this is the case, which disincentivizes NFT holders from trading OTC or via an AMM, I wouldn’t expect many creators to have the need to disable transfers.

Honestly, the jury is still out on this. Definitely keen to hear feedback, and we could save the optional transfer-disabling toggle for a later version of the spec if creators want it.

One of the examples @mattlockyer made on the call is the example of the same product (in this case an NFT), being sold at different storefronts and different rates. My main concern for this is overriding a listing. Is there a possible solution where a NFT can be listed to multiple marketplaces at once at different rates. Or is these rates simply going to be decided by the marketplace (referrer). As a NFT creator I would like to charge different marketplaces different ratings based on their revenue sharing model.

Hey @minorityprogrammers, thanks for the comment! What do you mean by “rates”? Like referrer/commission/platform fees?

pretend like i had blunt nfts i wanted to sell. I’d still want to list the blunt in the blunt dao store front, but also on few n far. I’d want to give a lower price for blunt store front over few n far, but i’d still want to list on both

Gotcha. Then what I’d say is, list via an approval on the blunt dao store for the lower price, and create a native listing for the higher price. Or, do approval listings on both the blunt dao store and the few&far market contract, as we will continue to support approval listings.

1 Like

Thinking about this more, perhaps a better solution would be to allow the creator to specify accounts that the NFT cannot be transferred to (e.g. escrow marketplaces / AMMs that don’t honor royalties), rather than disallowing transfers altogether.

Hello, think it gets hard to have productive conversations via long text threads. Created this visual guide to express my complexity concerns and at the end made possible alternative to solving the forced royalties without needing to change standards Loom | Free Screen & Video Recording Software | Loom

I share the sentiment. If speed and enforcement for high value IP are the priorities then it should be a closed system. That closed system could even live off chain (as I believe NBA Top Shot and Chiko&Roko are doing). The performance games demand are a prime example. Even the fastest chains can’t store all game state to provide trustless anti-cheat. It’s necessary to keep most things off chain until there’s a need for transferability. Then interoperability becomes the priority and you can mint the asset in a standard way on chain.

Definitely interesting to hear you’ve been down this road already and dealt with the repercussions of Mintbase stores not appearing on OpenSea. I keep meaning to look into more prior art around this topic. For example, ZORA is regarded as being radically artist-first and they are using the ERC-721 standard. Their NFT Marketplace Protocol Hyperstructure sounds alluring… need to dig in.

Centralized marketplaces do play a role of flagging collections as verified or scams. Even with those protections in place we see lots of scam collections on Paras. So today, we have a relevant benefit for marketplaces to allowlist smart contracts. That’s before considering contracts that can run with money.

Another promise we need to acknowledge one of ownership to the collectors. In my experience it’s much harder to woo collectors than creators.

Things are so early we have chains like Sui focusing on assets holding the power. It may sound goofy but it’s a closer analogy to analog ownership than NFT contracts provide. As an example, if I buy a hair dryer I can do whatever I want with it. It’s my asset. I don’t need to go ask the manufacturer if I can sell it. I can even replace the power cord on it (composability)! That’s the Sui asset focused model.

The Sui asset model is outside of the set of problems FNF is tackling, but provides some perspective. Collectors will want the promise of ownership. Without collectors, NFT creators can’t make primary sales, let alone hope for royalties.

We have a lot to consider. Striving for simplicity now means we’ll have less baggage when we get there. Several existing marketplaces are insisting the FNF spec will introduce greater complexity if it becomes a standard.

How do standard transfers impact provenance? There’s still the record of owners. There are also legitimate reasons to do an OTC trade or list an NFT with an AMM/pool like nftx.io. Today’s collectors don’t have any qualms giving creators the finger and going OTC. I don’t see why tomorrows collectors would care more about provenance than profit.

Without addressing OTC it’s hard to say any spec or standard has “fixed” royalties for creators. One approach would be a transfer tax that kicks in if royalties are too low. Not perfect, it will anger collectors to pay for sending assets between their own wallets. A compromise would be waiving the tax if sending to a sub-wallet of the current owner.

Wrapping up…

Happy to see the healthy discussion here and in the NFT Builders group. Standards are messy and are rarely the best tech (VHS vs Beta). Instead it’s the best compromise all stakeholders can concede to (IEEE/ICANN process). It’s evident competing standards can co-exist (721/1155). Hopefully we can avoid those kind of fractures until NEAR has the volume to support even more approaches.

1 Like

Thanks for this feedback, @starpause. I don’t think we’re going to come to an agreement on these points right now, especially since we’re working with hypotheticals on both sides of the conversation (e.g. what “ownership” means to collectors) and so it comes down to perspective and priorities.

We’re introducing features to provide a differentiated, optimized experience for all parties on Few and Far. This is why we are calling it the “Few and Far NFT Specification.” With this in mind, while I appreciate the concerns raised and feedback provided, we’re going to keep down this path of experimentation and iteration. We might not get it right the first time, but we will work towards continual improvement and will do our best to make it as backwards-compatible as possible, keep the ecosystem informed of updates, and provide the resources needed for those who want to support this specification to do so.

1 Like

Interested read in response to OpenSea Ethereum NFT Marketplace X2Y2 Will Enforce Royalties Following OpenSea’s 'Brave Move' - Decrypt