EIP-5289 Discussion: Notary Interface

NOTE: None of the authors is a lawyer. If you are a lawyer and would like to contribute to this EIP, please contact Pandapip1 on Discord (Pandapip1#8943).

I would strongly recommend against using a PDF for the document. They are insanely complex, and incorrectly implementing a renderer in the wallet could mean inconsistencies between what two users see and sign.

I’d suggest picking a very minimal markdown flavour and use that instead.

Hm, why create a registry contract for documents, instead of an interface implemented by, for example, the NFT contract itself?

Even more hm, what if I created a malicious smart contract that reused the same document ID as a target contract.

A user could agree to the document while interacting with the malicious smart contract, convincing the target contract I had signed for it.

How about markdown with a Jekyll header (à la EIP)?

EDIT: Regular markdown is probably better.

1 Like

One word: Gas.

It’s cheaper to have a registry for contracts that stores all the contracts and then have the function revert if necessary. I suggest that wallets simulate the transaction and if it would fail, prompt the user to sign the necessary documents before submitting the TX to the mempool.

Not possible. The revert reason references both the document ID and the library address so that there is no ambiguity as to what needs to be signed.

Not sure I follow. Here’s the scenario I was imagining:

  1. ValuableNftContract deployed, using a standard document registry.
  2. Document 0x01 is created on the same registry.
  3. Attacker deploys FunnyNftContract using the same document registry, and puts up a fancy web UI.
  4. Victim sees FunnyNftContract and goes to mint one.
  5. Attacker’s fancy web UI displays document 0x01 and requests a signature (possibly using eth_sign, which is still supported by MetaMask.) FunnyNftContract reverts with the magic message.
  6. User signs the document, expecting it to only apply to FunnyNftContract, and it is submitted on chain.
  7. Now if the user interacts with ValuableNftContract, it will believe the user has signed document 0x01, and will never revert to request the signature.

I think the easiest solution would be to include the requesting contract in the key, something like:

interface IContractLibrary is IERC165 {
    // ...
    event DocumentSigned(address indexed signer, address indexed counterparty, uint48 indexed documentId);
    function isDocumentSigned(address user, address counterparty, uint48 documentId) public view returns (boolean signed);
    function documentSignedAt(address user, address counterparty, uint48 documentId) public view returns (uint64 timestamp);
    function signDocument(address signer, address counterparty, uint48 documentId, bytes memory signature) public;

On another note, why have both isDocumentSigned and documentSignedAt? Couldn’t you just catch the revert in documentSignedAt to tell?

Is it? Don’t you have the overhead for a call into another contract for every operation?

You have a one-time overhead for checking if the user has signed. Then, once the user has, the value should be cached.

Also, there is no rule that says the library and the contract have to be different.

This is a feature, not a bug :slight_smile:. Always make sure you know what you are signing!

I’ll probably just add it as a second return value of isDocumentSigned

That’s the thing, you can know exactly what you’re signing (the document id), and it’ll apply to all contracts that use the same registry.

Again, I don’t see the issue here. If there is ever a “Universal NFT Contract” that could apply to all NFTs, then great! There’s no need to make the user re-sign.

I don’t have a good place to give feedback, hence adding here:

  1. I don’t think it’s a good practice to include a full copy of Base 64 in the specification
  • it may violate copyright laws because author is copying a piece of work that was originally granted with condition, but then release it in another place in-violation of the condition, such as per

subject only to the restriction that no Contributor has the right to represent any document as an RFC, or equivalent of an RFC, if it is not a full and complete copy or translation of the published RFC.

Because this piece of Base 64 spec was not a full copy

  1. It’s error prone for authors to make copy of references especially when it’s a code table. Such error if incurred can lead to significant backward difficulty.

  2. I suggest directly put the interface solidity code into the markdown file, as opposed to reference them in the asset file.

Very interesting, would be great to see this in use.

From the look of things the document set would be contract wide? Any thoughts on expanding this to allow token specific docs?

This is definitely the right place.

I’m working on another proposal that will supersede base64 for this.

Agreed. This will just be while this is in draft and while this is initially in review.

Not sure what you mean. Mind elaborating?

Hi @Pandapip1, I have an amazingly talented lawyer friend who also understands crypto. I’d like to introduce you. Have sent you a friend request on discord.