- Goal:
- An [[Ethereum]] smart account architecture composed from a very small and simple pattern of flexible delegation with maximally off-chain, low-state contracts.
- Axioms / Dependencies / Prior Art / Prerequisites & Tools
- [[gnosis-safe style module]]s
- Each module can call any function on the parent contract.
- [[create2]] deterministic addressing
- Account can delegate to unpublished contracts.
- [[Will-o-wisps]]
- Stateless delegations can clean themselves up, leaving no state-bloat on-chain.
- [[MetaTransactions]]
- The delegation to the unpublished contract can happen with a message that can be submitted by someone else).
- Assume all contracts here use [[the _msgSender() trick]]
- Assume these messages have custom replay logic that only allows them to be submitted at any time and only prevented by the same authority that granted.
- [[Recursion]]
- Delegating to an unpublished [[capped wisp]] also allows the creation of unpublished delegations from that contract.
- For this reason, arbitrarily long chains of delegation can happen entirely off-chain, while retaining their full meaning.
- [[Sub-classing]]
- Each [[capped wisp]] can have different behavior: Authorization, attenuation, & disruption.
- This allows the growth of arbitrarily nuanced authorization logic based on off-chain delegation and the power of the [[evm]].
- [[gnosis-safe style module]]s
- "
"
- Security Lemmas
- Since each child [[capped wisp]] can at most perform the operations of its parent:
- Longer chains cannot gain authority.
- Longer chains can only distribute control.
- Since each child [[capped wisp]] can at most perform the operations of its parent:
- High-level spec
- Inheritance opportunities
- [[gnosis safe]]: A list of
owner
addresses who can invoke the contract to emit an arbitrary message, [[gnosis-safe style module]]. - Support for [[MetaTransactions]] via [[the _msgSender() trick]]
- [[gnosis safe]]: A list of
- Needs custom
- A method to generate contracts with deterministic addresses that cannot be prevented except by the same authority that granted it.
- A method to allow blocking the future delegation to a particular address. (Could also block publication, just needs to cover revocation use case).
- Optional customization for [[Sub-classing]]
- Custom attenuation/disruption logic
- For limiting the set of possible messages that will be forwarded by this contract.
- Enables the composition of contracts that adhere to the [[principle of least authority]].
- Custom attenuation/disruption logic
- Inheritance opportunities
- [[Mushroom]] metaphor
- Apologies to [[Nick Johnson]] and his hate of architectural metaphor, but I'll be using the metaphor of a mushroom's lifecycle to describe this architecture, so let's take some time to learn it.
- Fun mushroom facts
- If fungus didn't exist, there would be no living process for breaking down the lichen fiber in wood.
- "
"
- Summary in metaphor
- This document is a spore: the kernel of potential hoping to gain a seat in a new person's mind.
- A [[capped wisp]] inoculation occurs as the initial contract is published to the chain.
- The base contract allows the user to share messages of delegation off-chain, which can grow to arbitrary length and only to increasing exclusivity, never to privilege escalation. This invisible network of capability resembles the mycelial growth of a fungal colony.
- Some of these messages are "
stateful bool
", and so require a new contract to be published that can also receive the same sorts of [[MetaTransactions]]. This is like a fruiting body: A visible extension of the mass, necessary to overcome the limits of off-chain/underground growth. - The fruitbody is a published gnostic cap in the hands of an agent who knows how to spread their spores.
- The initiated agent IS the [[capped wisp]], spreading their own spores where needed to [[facilitate]] the risks they choose to take for growth.
- The Body
- Properties
- owners
Set<address>
- A set of [[ethereum addresses]] that are permitted to call functions on this hyphae.
- revoked
- A set of [[ethereum addresses]] that will never again be permitted to call functions from this hyphae.
- owners
- Functions
execute(message bytes)
- Depending on the "Varieties & Subclasses", custom logic may be added to the "
execute(message bytes)
" function to limit the messages that it may relay, or even enforce some manipulation of the message. This reflects the terms of the "The Body"'s original formation.
- Depending on the "Varieties & Subclasses", custom logic may be added to the "
delegate(newOwner address, authProof)
assert(authorize(authProof))
- adds
newOwner
to the owner list
revoke(address)
- if in owner list, removes from the owner list.
- Adds to the revoked list.
redeemAndExecute(mycelialCellPacket, tx)
if (authorize(authProof) === true)
- Publish
mycelial cell packet
. - Assert primordiaAddress is not in revoked list.
- Store resulting contract address in owner list.
- execute tx on the newly published primordia
- if spore.stateless
- spore.selfdestruct()
- remove primordiaAddress from owner list.
- Publish
private authorize
- Since a "Varieties & Subclasses" is an expansion of the base safe, it can have different authority delegated to it. This can mean that a particular key is in control of these particular
- Variations
- A signature verifier
- a personal_sign one
- a signTypedData one
- a 2-factor one
- a token-weighted vote one
- an m-of-n one
- A signature verifier
- Varieties & Subclasses
- While a capwisp fundamentally could do anything if allowed to (because of the DPpgieaK2), in practice sub-classing is likely to be a field for standardization around well audited constraints on what a new delegate can do.
- Each of the type may have its own limitations: spending limit, contract whitelist, for security, it is advisable to confine this to the narrowest scope its author prefers, per the [[principle of least authority]]). It is only those initial capabilities that the capwisp can build on, then, ensuring that no additional authority can ever be derived from its delegation to new owners.
- Capabilities and Limitations
- What they have in common
- They all support forwarding a message, or broadcasting it as self.
- They may enforce some validation or mutation on messages they forward.
- Ways they can vary
- Properties
- Mycelial cell packet (binary data)
- The signed message of arbitrary delegation, the technical component that delegates authority.
- types
- parent: address
- bytesToPublish: bytes
- stateful: boolean
- authProof: bytes
- an off-chain message.
- Must have a deterministic address regardless of publication order, to enable:
- being assigned commitments/permissions without being published.
- revocation of those outstanding capabilities by the parent.
- properties
parent address?
- If there is no parent, then this is the root, and the
bytesToPublish
are executed as a transaction from this contract. - The address of the contract that granted this message, so that approved messages can be forwarded to it.
stateful bool
- if false, this spore will self destruct after each usage and self revoke from storage, to avoid chain bloat.
- If there is no parent, then this is the root, and the
authProof bytes
- A blob of data that proves authorization of this message to the cell's authorization logic.
- signed properties
message bytes
- The payload being published as a new contract, or sent as a transaction.
- can be submitted to its parent "The Body"."
redeemAndExecute(mycelialCellPacket, tx)
" to be published to the chain. - Could possibly include a gas limit for pre-enabling a user's gas without spending ether.
Last active
April 13, 2020 21:04
-
-
Save danfinlay/1bfebdcb95766eb55f674a3578b5e21d to your computer and use it in GitHub Desktop.
Capped Wisp Account
So i want to bring attention to what I've done here with my MultiSig design.
Awesome @SilentCicero, I only saw this now! Really excited to see you doing a multisig in YUL.
Two features I think my spec would need that would need to be accounted for, either within or as modules to this:
- An optional replay protection strategy that allows submission in any order (a two dimensional nonce could do): It's possible that simply integrating EIP-1776 compatibility (a single MetaTx method, and replacing
msg.sender
with_msgSender()
could achieve this goal). - A method for publishing new contracts with a deterministic address with
CREATE2
(this could be achieved with an additional module, so could live outside of this core lib).
Would probably be easy enough to do the first one, and make a module for the second one, does that sound about right?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Heyo!
So i want to bring attention to what I've done here with my MultiSig design.
https://github.com/SilentCicero/MultiSignatureWallet
My later version of the multisig has a lot of what you need:
Project details: