celo-org / celo-proposals

Celo Improvement Proposals
Apache License 2.0
62 stars 38 forks source link

CIP 49 - Transaction Signature Safety - Discussion #293

Closed nambrot closed 1 year ago

nambrot commented 3 years ago

Replicated here:


lang: en cip: 0049 title: Transaction Signature Safety status: Idea type: Informational discussions-to: https://github.com/celo-org/celo-proposals/issues/293 author: Nam Chu Hoai (@nambrot) created: 2021-10-12 license: Apache 2.0

Abstract

This CIP outlines a roadmap for a collection of improvements aimed at making transaction signing more transparent and by extension hopefully safer for users, especially less technical ones. The proposed measures for the most part are fairly chain-agnostic (i.e. not specific to Celo) and could be ported over to other chains easily.

Motivation

One of the key characteristics of decentralized networks that have come since the Bitcoin whitepaper is the use of non-custodial cryptographic keys to authenticate user intent. Instead of a user telling a bank to initiate a transfer which makes them and their underlying infrastructure a gatekeeper, anyone is able to sign a transaction and submit it to the network (assuming it is credibly decentralized and neutral). With the creation of Ethereum, smart contract platforms have expanded to general purpose computation. However, as the complexity of transactions that can be signed have increased, the ability for users to understand the implications of what their keys are signing has not. Often, the only information available to the users are the to contract as well as the raw data bytes. As this space moves away from early adopters to "the mainstream", we can no longer rely on informed users who have build muscle memory for protective heurestics.

Specification

The roadmap is proposed as follows:

  1. Make contract verification and transaction decoding accessible to developers

The current state of contract verification is mostly manual in its consumption from hosted block explorers, some of which are proprietary and permissioned. We propose to leverage Sourcify.dev to faciliate access to verified source code and ABIs. This includes both tooling/documentation to make verifying on Sourcify easier, as well as fetching from it. It may even involve verifiying popular contracts by recompiling. Following/extracting from CeloTerminal would be the most likely avenue for this. This tooling can be written generally enough to ultimately fetch from other sources (Etherscan comes to mind.) As Celo Core contracts make significant use of proxies, support for them should be considered required for v1.

  1. Demo via a WalletConnect Proxy

Since existence of tooling and documentation does not guarantee actual implementation for users, we propose to build a WalletConnect proxy as a demonstration of the "state of the art" experience. On the proxy, users can connect their wallet via use-contractkit(Celo)/Onboard.js(Ethereum) and then the proxy itself can be connected to the dapp. Requests for transaction signature can be displayed on the proxy first for introspection before forwarded to the actual wallet for signature.

  1. Expand the experience

Up to this point, the experience is not actually state-of-the-art yet as some wallets do support selective transaction decoding. To improve upon the experience, it is necessary to provide judgement (read more why under Rationale). To quickly iterate upon which judgements (aka attestations) are actually valuable, we propose to use the proxy for that experimentation which effectively makes the hoster of it a trust-delegated party. The entity is encouraged to use an open-source repository of these attestations on Github to leave an audit trail and allow for discussion. When the value is validated, these attestations can be exposed via an API and further decentralized via Step 4.

The most impactful attestations we propose are:

  1. Decentralize and turn into a protocol

When the value of this approach is validated, the final part of this proposal is to turn it into an actual protocol by creating a "market" for these attestations that anyone can make and can subscribe to. For this, an established identity protocol is required, as well as a means of publishing and consuming these attestations.

Rationale

The philosphy behind this proposal is to help users navigate the risks of signing data and decrease the semantic gap. Wallets as the technical custodians of key are believed to be the primary responsible party to surface relevant data to the user in an accessible/understandable manner. Building tooling to lower the cost for wallets acting upon that responsability is a positive externality for the whole ecosystem. However, neutral verification is limited and ultimately judgements of various kinds have to be made. We shall call them attestations and below follows a treatment of relevant considerations/dimensions:

What can be attested?

Attestations exist on a spectrum, from a loose "I believe this contract was deployed with good intent by good people" to a stricter "I did a thorough audit of this contract". While attestations of the latter end of the spectrum are of course the strongest, the number of entities that will be comfortable making those attestations is likely very small if non-existent. The scope of attestation as in the literal expression of the attestation might be different from user interpretation. Even if someone like cLabs just attests "We superficially looked into the project and think its probably fine", it's unclear to me whether there is moral or legal liability in case of loss of funds. In that light, keeping the set of possible attestations small to set the right user expectations is critical.

Another relevant dimension of attestations are their domains, i.e. the underlying contract might be a valid one (i.e. the audited Multisig), but the wrong identity (i.e. a multisig controlled by an attacker vs. the governance approver multisig). Another example would be a token contract that pretends to be another legitimate one, and dupes you into providing liquidity for it.

With that being said, to prevent the most egregious instances of rug-pulls or phishing attacks, we propose the following set of attestations to consider:

Another class of attestations are quantitative in nature:

These numers can theoretically be calculated independently, but practically require an indexer which in of itself is an attestation to running it correctly. Since some of these numbers can be gamed, an additional extension of these attestations is to calculate them relative to a users social graph, i.e. what number of my friends have used this contract.

Who provides attestations?

Attestations only provide value insofar that the consumer of the attestation values the judgement of the attester. That could be the following parties:

How to identify an attester?

While specifying the identity protocol this proposal would use is out of scope, it is worth noting which identity attributes are relevant for it. While entities such as cLabs or the foundation can probably publish their addresses easily, it becomes marginally more difficult for projects building on Celo. Currently, the strongest attributes users associate with projects are a their websites (i.e. domain name) and their twitter accounts, which would also be the proposed requirements for the identity protocol from this proposal.

How to communicate an attestation?

This is a minor point but and again slightly outside the scope of this proposal, but given the relative high cost of providing attestations, all measures should be token to make the conceptual and practical overhead of doing so minimal. In this context, both the signing and storage/publication of the attestation should be doable with already accessible tooling. For signing, EIP-712 seems the most accessible. For storage, a centralized approach could work but is not ideal to generalize further. CIP-8 with additional work like a centralized hosted version could get the same accessbility while providing the path for decentralization.

Security Considerations

While of course the goal of this proposal is to increase transparency and safety for users, it shall be noted that this proposal does increase the surface area of code, services and entities that are being trusted which could open more opportunities for phishing. It's important for the community but especially implementors to understand how to display the information to users so that phishing users doesn't become trivial.

nategraf commented 3 years ago

I think this is a good starting point for a discussion. I definitly think there is value in having a shared protocol for attestations from a variety of issuers. One benefit of this I can see is that wallets could mutually consume and utilize each others attestations as signal for their users. (e.g. Celo Wallet may surface that both Valora and KotaniPay attest to the good intent of a given lending pool that I am considering using)

In order to get there I imagine we will need some concrete specifications for a number of standard attestation types, and clear language about what they mean. (e.g. "A good_faith attestation implies the the contract at the given address A) was deployed by a developer who is known B) the developer is not known to be involved in scams C) the code does not have any known malicious behaviors. It does not imply any specific identity.")

On the question of identity, probably the main way users ensure they interact with the correct contract for the application they are looking for is to Google it, then A) use their dApp on the website or B) check their docs for an ENS name or contract address. (E.g. I want to use Loopring, so I Googled "LoopRing ENS name" and found it in their docs). Alternatively, their wallet (e.g. Argent) may natively provide a UI to interact, at which point you are trusting the wallet. In the "Google it" case, the user is implicitly using the DNS infrastructure and Google search rankings to find the global owner of the "Loopring" project and bootstrapping my trust from there. I'm curious on your thoughts of how this proposal compliments this existing procedure?

One of the classic challenges with a scheme like this where signed attestations or certificates are distributed is revocation. It would be good to have some kind of revocation mechanism, but it may be the case that we decide this is out of scope. In general, revocation is hard to solve effectively. Expiration is a good starting point.

nambrot commented 3 years ago

In order to get there I imagine we will need some concrete specifications

Absolutely agreed that eventually actual specifications are needed, even more so than other CIPs as they are less about technical descriptions, but about how we interpret them (the attestations). Since that set of attestations is not at all clear, I propose to iterate through various hypothetical attestations and add them to the specification as their value crystalizes

I'm curious on your thoughts of how this proposal compliments this existing procedure?

In some ways, this proposal is trying to specifically eliminate that procedure, or at the very least significantly change it (spoken as someone who also does this). It seems like a very poor user experience to have the user do this fetching of the address <> canonical identity mapping ad-hoc every time. I know some wallets let you effectively build an address-book of addresses in the wallet so that at least you only have to do it once.

I would imagine the use of the "canonical" attestation would be most relevant here. I.e. it allows anyone (i.e. user, wallet, or other trusted parties) to provide a set of these canonical attestations. The tooling can then merge all these "address books" and use that as a source for the decoding.

So users who do not want to do this work, can "subscribe" to the wallets/cLabs' address book, while more advanced users could decide to only rely on their own address book.

One of the classic challenges with a scheme like this where signed attestations or certificates are distributed is revocation.

Definitely good point on revocation, reminds me of the similar problem at CIP8 though more urgent here since there is no easy way to invalidate via roots like there is CIP8. That being said, would probably still consider it out of scope for now

nambrot commented 3 years ago

One thing that just popped into my mind is to standardize an address book standard that has both private and public parts to it, which effectively allows the building of a both private and public graph of addresses

nambrot commented 3 years ago

Another subjective, yet semantic judgement beyond just making function parameters more interpretable is to indicate which state variables are relevant to surface as well. I.e. in the case of a proxied contract, who the owner is. Related, like there can be standard set of proxies, there could be standard set of timelocks, multisigs, gnosis safes, for which then additional info could be surfaced such as delay, signers, etc.