Signatures

A Vault uses an off-chain signature system to approve the execution of a request transaction, by implementing EIP-712.

This differs from traditional multisigs, for which all transaction confirmations and rejections are stored on-chain.

The traditional way is not the best practice, because:

  • It is slow.

  • Every signature costs fees.

  • It undermines privacy; anyone can see the intent of a multisig transaction on-chain before it is executed.

Using the MultiSigOrganization contract, users can collect all required signatures for a new multisig transaction off-chain; once the minimum defined number of signatures is reached, they can use them to execute the transaction.

This brings many benefits to the user, such as:

  • Instant confirmations and rejections.

  • The owner wallet doesn't require ETH to sign transactions.

  • Improved privacy.

How It Works

An off-chain signature is specific to the address of its signer and the transaction for which it is used. For each transaction, an address must provide a unique signature.

EIP-721 is a secure and advanced method of signing a transaction. It allows not only for a transaction to be signed and a signature verified, but that data can be passed into a smart contract along with the signature, and that the signature can be verified vis-a-vis that data, verifying that the signer is indeed the one who sent the data for the transaction.

Data is the most crucial aspect of EIP-712. It must conform to a predefined format; it must have both an EIP712Domain and the data. Combined, these are signed and sent over to the smart contract for verification:

//domain and specific data. Example Coming soon

The EIP712Domain is a value with parameters that specify which contract on which network will be used to verify the signature. Any other contract with the same code will be unable to verify the signature.

Once the data as defined above has been signed using the eth_signTypedData_v4 method, the signature is obtained and split into its r, s and v components. We then send it over to to the smart contract that will then use the ercrecover method on these parameters, and the data hash method to recover the public key of the signer.

// r,s,v. Example coming soon

Next, the off-chain generated signatures are passed to the MultiSigOrganization contract. In the callRequest struct, the requestsSignatures parameter in bytes format must contain the encoded off-chain signature data previously generated for each signer address:

(address signer, uint8 v, bytes32 r, bytes32 s, uint256 deadline) = abi.decode(permitSignature, (address, uint8, bytes32, bytes32, uint256));

If the number of correct signatures passed into requestsSignatures is equal to or greater than the minimum number of signatures defined in the contract, the transaction can be approved, and the code thus executed.

//Example coming soon

Last updated