Skip to content

Instantly share code, notes, and snippets.

@pagreczner
Created December 14, 2021 12:39
Show Gist options
  • Save pagreczner/2f3823d0059686d54a689500a2362dde to your computer and use it in GitHub Desktop.
Save pagreczner/2f3823d0059686d54a689500a2362dde to your computer and use it in GitHub Desktop.
NFT Proxy Idea

NFT Proxy

Overview / Goal

Proxy your NFT into a provable ERC-721 ownership format that can live in a different wallet from the proxied NFT. The proxied NFT can prove ownership while maintaining safety from the true asset by living in a different wallet. This proxied NFT can then be used safely for whitelists and other functions where signing a transaction may be connsidered "dangerous". This proxied NFT in theory could also be safely leased to other users in a way that NFTs can not be be done today.

Motivation

Many high end NFT collections that are have both significant underlying financial value and emotional value to users have become besieged by scammers and hackers. Part of the value in holding one of these NFTs is showing it off and being part of the community. However, in order to provably show it off you must expose your wallet to sign messages. Given the nascent UX in web3, it's not always easy to discern what is a trusted UX from an untrusted. And given that, there "should be a better way" to use your valuable NFT with additional safety built in. This is what NFT Proxy (NFTP) hopes to enhance.

Mechanics

Creation of the NFTP

  1. Mint / Buy NFT of value (whether financial or personal, ie BAYC, Punk ...)
  2. Issue a call to mint a NFTP proxy NFT of this original NFT.
  3. Move NFTP proxy to a new wallet that can be hot or cold and used to prove ownership of the original NFT.

Revoking

There is no strong ongoing link between the original NFT and the NFTP, and there are no mechanisms to prevent one from transferring an NFTP to another wallet. However, the original NFT can update or revoke the NFTP at any time as they are the true owner, and provably so, of the underlying asset.

New Owner Wants to Revoke

  1. Discover the BAYC you bought has a NFTP
  2. Issue call to NFTP contract to re-issue to you or revoke/burn the NFTP.
  3. NFTP is burned or re-issued to you.

Existing owner no longer wants NFTP to exist

  1. Issue call to NFTP contract to re-issue to you or revoke/burn the NFTP.

Additional NFTP Features

In addition to being a safe alternative to proving you own an NFT of interest, the NFTP contract also supports social and enhanced ownership metadata, such as:

  • Social Profile ID (ie @TwitterName, @InstagramName)
  • Social / Professional Website (ie https://mycoolproject.example.com)
  • Freeform Description Text (ie "Punking around since day 0")
  • Inherit TokenURI of underlying NFT
  • Inherent Leasing properties

Interface

Pseudo code:

# Minimum details to proxy and add enhanced functionality
struct ProxyIdentity {
  collection_address : address,
  token_id : number,
  social_meta : string,
  website_meta : string,
  description : string,
  originalTokenURI : string,
  nftp_id : number
}

# Mappings of a global registry
registryOfOriginals : mapping[collection_address][token_id] => ProxyIdentity
registryOfProxies : mapping[nftp_id] => ProxyIdentity

# Grants a new NFTP to the original NFT owner
grant(collection_address : address, token_id : number, social_meta : string, website_meta : string, description : string) {
  require(msg.sender === collection.at(collection_address).ownerOf(token_id), "Must be owner of the token at the collection address")
  pi : ProxyIdentity = { /* fill in details */ }
  registryOfOriginals[collection_address][token_id] = pi
  registryOfProxies[totalSupply() + 1] = pi
  _safeMint(totalSupply() + 1, /* details */)
}

# Burn the NFTP and remove registry information
revoke(collection_address : address, token_id : number, nftp_token_id : number) {
  require(msg.sender === collection.at(collection_address).ownerOf(token_id), "Must be owner of the token at the collection address")
  _burn(nftp_token_id)
  registryOfOriginals[collection_address][token_id] = null
  registryOfProxies[nftp_token_id] = null
}

# To return true/false if the challenger wallet is the owner of a specific nft. (Think there is a better way to do this proving idea).
# An application can use this for connected wallets to see that they own an NFTP and then check they own the specific token id of the desired collection. ie prove(0xBAYCContractAddress, 1234, 0xChallengerAddress) and they would do this after seeing that 0xChallengerAddress owns the specific NFTP
is_owner(collection_address : address, token_id : number, challenger_address : address) returns boolean {
  pi : ProxyIdentity = registryOfOriginals[collection_address][token_id]
  return this.ownerOf(pi.nftp_id) === challenger_address
}

# Other convinience methods around metadata and uris and such to be provided

Notes

As written this datastructure doesn't scale if it were to be a generalized solution for all NFT collections. Possibly there is a world where there is an NFTP for each individual collection if one became highly desirable or very valuable and then some of the scalability issues would go away, though some usability ones don't.

NFT Leasing(?)

This proxy pattern also allows the true owner to lease their NFTP to other people, and then revoke that lease at any time too. The person leasing doesn't actually own the underlying NFT but in a world where NFTP was pervasive, they could act like they did, and do so fully at the owners express permission.

  1. True owner grants NFTP
  2. Transfers NFTP to Leaser
  3. Leaser able to use is_owner methods from any applications that support NFTP
  4. True owner revokes NFTP access at any time and leaser can no longer use (possibly an advanced structure could put in a time limit where revoking was not possible for a true lease scenario that can't be abused)

What's wrong with this idea?

Maybe a lot! Woke up and had it so wanted to write down the notes and share.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment