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.
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:
ValuableNftContract
deployed, using a standard document registry.- Document
0x01
is created on the same registry. - Attacker deploys
FunnyNftContract
using the same document registry, and puts up a fancy web UI. - Victim sees
FunnyNftContract
and goes to mint one. Attackerās fancy web UI displays document0x01
and requests a signature (possibly usingeth_sign
, which is still supported by MetaMask.)FunnyNftContract
reverts with the magic message.- User signs the document, expecting it to only apply to
FunnyNftContract
, and it is submitted on chain. - Now if the user interacts with
ValuableNftContract
, it will believe the user has signed document0x01
, 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 . 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:
- 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
-
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.
-
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.