EIP-5643 Subscription NFTs

That’s how I was approaching this problem, however if someone can provide a clean interface for auto-renewals I’d be happy to consider it

Someone may have a reason to make cancellations payable, I want this to be as open as possible. Take EIP721 for example, transfer and approve are both payable but it’s not used most of the time.

1 Like

First of all, thanks a lot for your patience here.

I would preface by saying that I am really happy that the space is thinking about recurring revenues. I deeply believe that the “sell once, provide value forever” model is not going to work for lots of creators… Additionally time limits on NFTs do bring lots of opportunities for artistic work even! You can make on NFT that render differently based on whether they are expired or, or how close to expiration they are… etc! (People have used Unlock for that and it’s pretty cool!).

Now, when it comes to feedback about the spec, I think it is a good start, but also falls short to be practically usable as is.

For example, and unless I missed something there is currently no way to start a subscription.

Well, first I think you would need to have a way for the user to “start” a subscription. Right now it is unclear how as a user, when I own an NFT, I can “start a subscription”.

Then, as I wrote earlier, I deeply believe that a prerequisite to this would be to allow users to pay for the NFT with an ERC20 (vs the native currency via the payable approach). The reason for this is that with ERC20 users can “approve” the contract to spend from them… rather than have them come back over and over to (re)purchase next month’s subscription. However, if ERC20 “approvals” are supported it is critical to make sure they are not abused by either making the price/duration “unchangeable”, or by keeping track in the contract of what each user has “allowed” in terms of pricing (combination of duration and amount).

2 Likes

Regarding the “no way to start a subscription”, I was imagining it would be part of the mint process for the token - when you mint a token to someone, the subscription would start. However, we could in theory change renewSubscription to updateSubscription like mentioned above and kick off the subscription then.

For autorenewals, I do agree that having this feature is nice to have, however if you look at ENS, they’ve been able to create a very successful subscription NFT without needing it. I can see a popular library having an autorenewal feature built-in (similar to how OpenZeppelin’s library has mint functions for 721), but I don’t think the standard requires it. At the end of the day, a subscription only really needs to be renewable and cancelable to be considered a “subscription”.

2 Likes

This has a great use case for e-commerce NFTs. I’d be down to do some hypothesis test with www.shopx.co → might be interesting to open up that subscriptions could be paid in erc-20s too.

1 Like

Happy to work with you on implementing this EIP!

Thanks @cygaar for the proposal, very good work :slightly_smiling_face:

To keep it simpler would it be beneficial to leave our the “renew” functions out of this EIP, and only keep the view functions (and maybe cancel) included?

Main reason for that is similar to mint function there would be various ways people want to implement a “start”/“renew” for example choosing a specific Plan, not just a direct payment, or being able to “upgrade”/“downgrade”, etc.

Since the signature for renew (and potentially upgrade/downgrade) cannot be generalized, the wallet implementations for example cannot create a “Generic Renewal” interface and take advantage of a standard.

Another way to generalize “renew” (or “update”) is to extend the EIP further (which I personally suggest to be a separate eip maybe), is to provide an additional “bytes data” argument. But still since there won’t be a generalized solution, and each dApp will end up creating their own renewal methods/interfaces.

People could still use same method name (e.g. updateSubscription) but the rest of signature might be different per use-case.

What are you thoughts?

@cygaar this is an awesome proposal that I’d love to contribute to. Timing works out as I am currently developing a subscription NFT :slight_smile:

@aram makes a good point on the update functions potentially being limiting based on the desired implementation. Limiting this standard to only view functions and the required events would greatly increase usability for various implementations. This would also help solve the questions about auto-renewals and how to start subscriptions.

I do have two additional comments as feedback.

  1. I think adding in a function called isCancelable would make a lot of sense, as there can definitely be implementations that don’t want to allow canceled subscriptions. It would operate similar to isRenewable.

  2. Typically subscriptions have tiers. The way you buy tiers is hard to generalize properly, but adding the idea of tiers should be easy to implement into this standard. Basically, the SubscriptionUpdate event would have to include a tier variable (maybe uint8 so enums can be used - 255 tiers should be plenty in basically all applications) and adding a getTier view function would be simple. It may also make sense to add view functions for seeing if a token is upgradeable/downgradeable – isUpgradeable and isDowngradeable.

edit: ahhh i see this has been implemented already, nice

i’m wondering if, rather than having to manually set the expiration for renewSubscription, it might be better to have that function take a duration instead that would then be added to the existing _subscription.

like “renew for 30 days” and it would check if 30 days * cost was paid then add time.~

Yes, I actually made that change in the EIP as well as the implementation: ERC5643/src/IERC5643.sol at main · cygaar/ERC5643 · GitHub. Thanks for the callout!

1 Like

Let me think on the renew function - I think it makes sense to require a function of this nature since it’s a core part of being a subscription. I would be open to having a second renew function that takes in a data bytes parameter (similar to 721 having multiple safeTransferFrom functions).

  1. This is a bit tricky because if a user doesn’t pay for their subscription then it’s by definition canceled. Even if you say a subscription can’t be canceled, you can’t force a user to pay.
  2. I think this would be a good idea for an implementation, but I don’t think it’s necessary for a standard interface. I’ll think about it some more.

Thanks for the response, I addressed these concerns in the response above this. Let me know what you think!

I really like this idea. This is my first time looking at contracts outside of tutorials so I will explore the repo and help where I can. :sweat_smile:

Hi everyone! Thanks for sharing this brilliant idea ! I am Wen, I based in Paris and I am building an NFT-based subscription/ NFT gated e-commerce platform using Unlock @julien51 for the creators, e-commerce and the local business.

1 Like

I really do like the idea, what about considering a pause state, as sometimes you may want to take a holiday from a sub but not cancel, there might be a limit for how long you can pause but may encourage them to remain subscribed.

That’s a great idea @cygaar. What happens to the token ownership when the subscription has expired? What will ownerOf() return in this case for example?

1 Like

I believe that it is important to describe what users should expect from tokens implementing this.

For example, ERC721 implies that I have ownership over a token. (Of course there’s nothing preventing contracts from doing all types of things, including implementing backdoors that allow someone else to transfer my tokens, but there is an expected behaviour and anyone not following is considered shady.)

So, regarding subscriptions, what should users expect? That they loose ownership? That the token is destroyed? That some of the token utility is limited?

If it was up to me, I would propose that when a subscription expires, all approvals are canceled. What this means in practice is that I can no longer trade the token (make profit, which is exactly the occasion when a creator would collect royalties normally). It is still owned by me, I can transfer it to my vault, or an other wallet, but I can’t trade it until I renew my subscription.

1 Like

Thanks @cygaar, I was recently developping a similar subscription NFT.
I think manual is right as we should renew when we need to.
Having an NFT means you have ownership. The decision should be left to each project to decide about ownership.
It is very simple and we already think it is a good idea. What is the main problem with this EIP?

good proposal. For subscription-based NFT, I feel the auto-renew is an important feature, which is not defined in the interface. You have an interface of “isRenewable” , why not add an “isAutoRenewable” interface?

It’s really a good idea. I think it can be applied to many scenarios