# Extensible `Safe` Architecture
This document outlines an *extensible* `Safe` architecture, increasing the novel integrations / applications for `Safe`.
The following guiding principles have been **strictly** employed:
1. State for the `SafeProxy` **MUST** not be modified, ensuring maximum security.
2. No use of `delegatecall` within the architecture.
## Use cases
Currently, a `safe` may only be interacted with via either:
1. The `owners` via `execTransaction`; or
2. An authorised `module` via `execTransactionFromModule`; or
3. Third parties who wish to verify a `signature` (ERC-1271).
Use cases that this revised architecture seeks to enable include:
1. Arbitrary method invocation on the `SafeProxy`. As an example, this would make it theoretically possible to convert a `SafeProxy` into an ERC20 token by implementing ERC20 methods.
2. Authorise a 3rd party contract to verify EIP-712 signatures for a specific domain on behalf of the `Safe`. As an example, one could delegate the CoW Protocol EIP-712 domain to a contract that verified all signatures for selling any ERC20 token to ETH, ie. Max ETH :rocket:
## Current Architecture
The execution path of any method call that is _not_ implemented in the `Safe` singleton follows this path:
```mermaid
flowchart TD
A[SafeProxy] -->|delegatecall| B[Safe - `FallbackManager`]
B -->|call| C[CompatibilityFallbackHandler]
```
`CompatibilityFallbackHandler` provides:
1. ERC-1271 signing, using either approved hashes, or threshold signatures.
2. Miscellaneous token callbacks for ERC721 / ERC1155 etc.
If a developer wishes to extend the functionality of a `Safe`, they have to replace the `CompatibilityFallbackHandler`, requiring significant heavy lifting, being careful to not remove any existing functionality so as to not break `Safe` (some parts of existing infrastructure require the use of threshold signatures, and some apps are using approved hashes such as CoW Protocol dapp).
A developer may *extend* `CompatibilityFallbackHandler`, though it can be made much easier if one could simply specify a custom handler for arbitrary individual methods. This is where `ExtensibleFallbackHandler` comes in.
## `ExtensibleFallbackHandler`
This handler replaces `CompatibilityFallbackHandler`, but preserves backwards compatibility with:
1. ERC-1271 `Safe` approved hashes / threshold signatures.
2. Token callbacks.
3. ERC165.
In addition to the backwards compatibility, a user may:
1. Specify a handler for a custom method.
2. Specify a set of handlers for custom methods and indicate that the `Safe` now supports an interface.
3. Specify a custom verifier for an EIP-712 domain.
### Custom Methods
Security requirements:
* The `Safe` **SHALL** determine (based on the authorisation in the setter) whether a custom method is `view` or not (ie. whether or not the custom method can modify state on invocation).
Execution Path:
```mermaid
flowchart TD
A[SafeProxy] -->|delegatecall| B[Safe - `FallbackManager`]
B -->|call| C[ExtensibleFallbackHandler]
C -->|call| D[IFallbackMethod]
C -->|staticcall| E[IStaticFallbackMethod]
```
### Custom EIP-712 Verifiers
User requirements:
1. Custom verifiers **MUST** be able to accept an arbitrary, implementation specific `bytes` payload.
Security requirements:
* `EIP-712` domain separator **MUST** be checked against the `hash`, ensuring a 1:1 relationship between domain separator and `ISafeSignatureVerifier`.
Execution Path for `isValidSignature(bytes32,bytes)`:
```mermaid
flowchart TD
A[SafeProxy] -->|delegatecall| B[Safe - `FallbackManager`]
B -->|call| C[ExtensibleFallbackHandler - `SignatureVerifierMuxer`]
C --> D[Approved Hash]
C --> E[Threshold Signature]
C -->|call| F[ISafeSignatureVerifier]
```
#### Encoding of `signature`
* `approvedhash` - `signature` is set to zero-length `bytes`.
* `threshold` - `signature` is a multiple of 65 bytes (for `r`, `s`, `v`).
* `custom` (ie. `ISafeSignatureVerifier`) - `signature` is an ABI encoded function call `safeSignature(bytes32,bytes32,bytes32,bytes)` where the tuple equates to `(bytes32 domainSeparator, bytes32 typeHash, bytes32 encodeData, bytes payload)`. It is the `4bytes` selector in the ABI encoded function call that is used to trigger the custom signer.
#### Custom Verifier Validation
Before `SignatureVerifierMuxer` calls a custom verifier, it **MUST** match the `domainSeparator` to the `hash`. Therefore, this then means that `typeHash`, and `encodeData` can be trusted within `ISafeSignatureVerifier` if called from `SignatureVerifierMuxer`.
#### `ISafeSignatureVerifier`
Security requirements:
* An implementation **MAY** reassert `_hash = h(abi.encodePacked("\x19\x01", domainSeparator, h(typeHash || encodeData)))`.
### Storage
Storage of custom method handlers and custom domain verifiers is contained within the `ExtensibleFallbackhandler` deployment. Therefore, any update of the `fallbackHandler` for a `Safe` would in-effect "reset" the custom methods / domain verifiers for the `Safe.`