AvocadoMultisig
AvocadoMultisig_V1
Smart wallet enabling meta transactions through multiple EIP712 signatures (Multisig n out of m).
Supports:
- Executing arbitrary actions
- Receiving NFTs (ERC721)
- Receiving ERC1155 tokens
- ERC1271 smart contract signatures
- Instadapp Flashloan callbacks
- chain-agnostic signatures, user can sign once for execution of actions on different chains.
The cast
method allows the AvoForwarder (relayer) to execute multiple arbitrary actions authorized by signature.
Broadcasters are expected to call the AvoForwarder contract execute()
method, which also automatically
deploys an AvocadoMultisig if necessary first.
Upgradeable by calling upgradeTo
through a cast
/ castAuthorized
call.
The castAuthorized
method allows the signers of the wallet to execute multiple arbitrary actions with signatures
without the AvoForwarder in between, to guarantee the smart wallet is truly non-custodial.
@dev Notes:
- This contract implements parts of EIP-2770 in a minimized form. E.g. domainSeparator is immutable etc.
- This contract does not implement ERC2771, because trusting an upgradeable "forwarder" bears a security risk for this non-custodial wallet.
- Signature related logic is based off of OpenZeppelin EIP712Upgradeable.
- All signatures are validated for defaultChainId of
634
instead ofblock.chainid
from opcode (EIP-1344). - For replay protection, the current
block.chainid
instead is used in the EIP-712 salt.
AvocadoMultisigErrors
AvocadoMultisig__InvalidParams
error AvocadoMultisig__InvalidParams()
thrown when a method is called with invalid params (e.g. a zero address as input param)
AvocadoMultisig__InvalidSignature
error AvocadoMultisig__InvalidSignature()
thrown when a signature is not valid (e.g. not signed by enough allowed signers)
AvocadoMultisig__Unauthorized
error AvocadoMultisig__Unauthorized()
thrown when someone is trying to execute a in some way auth protected logic
AvocadoMultisig__InsufficientGasSent
error AvocadoMultisig__InsufficientGasSent()
thrown when forwarder/relayer does not send enough gas as the user has defined. this error should not be blamed on the user but rather on the relayer
AvocadoMultisig__InvalidTiming
error AvocadoMultisig__InvalidTiming()
thrown when a signature has expired or when a request isn't valid yet
AvocadoMultisig__ToHexDigit
error AvocadoMultisig__ToHexDigit()
thrown when _toHexDigit() fails
AvocadoMultisig__InvalidEIP1271Signature
error AvocadoMultisig__InvalidEIP1271Signature()
thrown when an EIP1271 signature is invalid
AvocadoMultisig__MaxFee
error AvocadoMultisig__MaxFee(uint256 fee, uint256 maxFee)
thrown when a castAuthorized()
fee
is bigger than the maxFee
given through the input param
AvocadoMultisig__InsufficientBalance
error AvocadoMultisig__InsufficientBalance(uint256 fee)
thrown when castAuthorized()
fee can not be covered by available contract funds
AvocadoMultisigEvents
Upgraded
event Upgraded(address newImplementation)
Emitted when the implementation is upgraded to a new logic contract
SignedMessage
event SignedMessage(bytes32 messageHash)
Emitted when a message is marked as allowed smart contract signature
RemoveSignedMessage
event RemoveSignedMessage(bytes32 messageHash)
Emitted when a previously allowed signed message is removed
AvoNonceOccupied
event AvoNonceOccupied(uint256 occupiedAvoNonce)
emitted when the avoNonce in storage is increased through an authorized call to
occupyAvoNonces()
, which can be used to cancel a previously signed request
NonSequentialNonceOccupied
event NonSequentialNonceOccupied(bytes32 occupiedNonSequentialNonce)
emitted when a non-sequential nonce is occupied in storage through an authorized call to
useNonSequentialNonces()
, which can be used to cancel a previously signed request
FeePaid
event FeePaid(uint256 fee)
Emitted when a fee is paid through use of the castAuthorized()
method
FeePayFailed
event FeePayFailed(uint256 fee)
Emitted when paying a fee reverts at the recipient
ListSyncFailed
event ListSyncFailed()
emitted when syncing to the AvoSignersList fails
CastExecuted
event CastExecuted(address source, address caller, address[] signers, bytes metadata)
emitted when all actions are executed successfully. caller = owner / AvoForwarder address. signers = addresses that triggered this execution
CastFailed
event CastFailed(address source, address caller, address[] signers, string reason, bytes metadata)
emitted if one of the executed actions fails. The reason will be prefixed with the index of the action.
e.g. if action 1 fails, then the reason will be 1_reason
if an action in the flashloan callback fails, it will be prefixed with with two numbers:
e.g. if action 1 is the flashloan, and action 2 of flashloan actions fails, the reason will be 1_2_reason.
caller = owner / AvoForwarder address. signers = addresses that triggered this execution
Note If the signature was invalid, the signers
array last set element is the signer that caused the revert
SignerAdded
event SignerAdded(address signer)
emitted when a signer is added as Multisig signer
SignerRemoved
event SignerRemoved(address signer)
emitted when a signer is removed as Multisig signer
RequiredSignersSet
event RequiredSignersSet(uint8 requiredSigners)
emitted when the required signers count is updated
AvocadoMultisigStructs
SignatureParams
struct SignatureParams {
bytes signature;
address signer;
}
Action
struct Action {
address target;
bytes data;
uint256 value;
uint256 operation;
}
CastParams
struct CastParams {
struct AvocadoMultisigStructs.Action[] actions;
uint256 id;
int256 avoNonce;
bytes32 salt;
address source;
bytes metadata;
}
CastForwardParams
struct CastForwardParams {
uint256 gas;
uint256 gasPrice;
uint256 validAfter;
uint256 validUntil;
uint256 value;
}
CastAuthorizedParams
struct CastAuthorizedParams {
uint256 maxFee;
uint256 gasPrice;
uint256 validAfter;
uint256 validUntil;
}
CastChainAgnosticParams
struct CastChainAgnosticParams {
struct AvocadoMultisigStructs.CastParams params;
struct AvocadoMultisigStructs.CastForwardParams forwardParams;
uint256 chainId;
}
ChainAgnosticHash
struct ChainAgnosticHash {
bytes32 hash;
uint256 chainId;
}
AvocadoMultisigConstants
DEFAULT_CHAIN_ID
uint256 DEFAULT_CHAIN_ID
overwrite chain id for EIP712 is always set to 634 for the Avocado RPC / network
DOMAIN_SEPARATOR_NAME
string DOMAIN_SEPARATOR_NAME
DOMAIN_SEPARATOR_VERSION
string DOMAIN_SEPARATOR_VERSION
TYPE_HASH
bytes32 TYPE_HASH
_TYPE_HASH is copied from OpenZeppelin EIP712 but with added salt as last param (we use it for block.chainid
)
CAST_TYPE_HASH
bytes32 CAST_TYPE_HASH
EIP712 typehash for cast()
calls, including structs
ACTION_TYPE_HASH
bytes32 ACTION_TYPE_HASH
EIP712 typehash for Action struct
CAST_PARAMS_TYPE_HASH
bytes32 CAST_PARAMS_TYPE_HASH
EIP712 typehash for CastParams struct
CAST_FORWARD_PARAMS_TYPE_HASH
bytes32 CAST_FORWARD_PARAMS_TYPE_HASH
EIP712 typehash for CastForwardParams struct
CAST_AUTHORIZED_TYPE_HASH
bytes32 CAST_AUTHORIZED_TYPE_HASH
EIP712 typehash for castAuthorized()
calls, including structs
CAST_AUTHORIZED_PARAMS_TYPE_HASH
bytes32 CAST_AUTHORIZED_PARAMS_TYPE_HASH
EIP712 typehash for CastAuthorizedParams struct
CAST_CHAIN_AGNOSTIC_TYPE_HASH
bytes32 CAST_CHAIN_AGNOSTIC_TYPE_HASH
EIP712 typehash for castChainAgnostic()
calls, bytes32 hashes array + chainId, made up of getSigDigest()
for
action on the respective chain.
CAST_CHAIN_AGNOSTIC_PARAMS_TYPE_HASH
bytes32 CAST_CHAIN_AGNOSTIC_PARAMS_TYPE_HASH
EIP712 typehash for CastChainAgnosticParams struct
EIP1271_TYPE_HASH
bytes32 EIP1271_TYPE_HASH
EIP712 typehash for signed hashes used for EIP1271 (isValidSignature()
)
MAX_SIGNERS_COUNT
uint256 MAX_SIGNERS_COUNT
defines the max signers count for the Multisig. This is chosen deliberately very high, as there shouldn't really be a limit on signers count in practice. It is extremely unlikely that anyone runs into this very high limit but it helps to implement test coverage within this given limit
avoRegistry
contract IAvoRegistry avoRegistry
registry holding the valid versions (addresses) for Avocado smart wallet implementation contracts
The registry is used to verify a valid version before upgrading & to pay fees for castAuthorized()
avoForwarder
address avoForwarder
address of the AvoForwarder (proxy) that is allowed to forward tx with valid signatures
avoSignersList
contract IAvoSignersList avoSignersList
Signers <> Avocados mapping list contract for easy on-chain tracking
AUTHORIZED_MIN_FEE
uint256 AUTHORIZED_MIN_FEE
minimum fee for fee charged via castAuthorized()
to charge if AvoRegistry.calcFee()
would fail
AUTHORIZED_MAX_FEE
uint256 AUTHORIZED_MAX_FEE
global maximum for fee charged via castAuthorized()
. If AvoRegistry returns a fee higher than this,
then MAX_AUTHORIZED_FEE is charged as fee instead (capping)
AUTHORIZED_FEE_COLLECTOR
address payable AUTHORIZED_FEE_COLLECTOR
address that the fee charged via castAuthorized()
is sent to in the fallback case
AvocadoMultisigVariables
Defines storage variables for AvocadoMultisig
nonSequentialNonces
mapping(bytes32 => uint256) nonSequentialNonces
occupied non-sequential nonces (which can not be used again)
AvocadoMultisigSelfUpgradeable
Simple contract to upgrade the implementation address stored at storage slot 0x0. Mostly based on OpenZeppelin ERC1967Upgrade contract, adapted with onlySelf etc. IMPORTANT: For any new implementation, the upgrade method MUST be in the implementation itself, otherwise it can not be upgraded anymore!
upgradeTo
function upgradeTo(address avoImplementation_, bytes afterUpgradeHookData_) public
upgrade the contract to a new implementation address. - Must be a valid version at the AvoRegistry. - Can only be self-called (authorization same as for cast
methods).
Parameters
Name | Type | Description |
---|---|---|
avoImplementation_ | address | New contract address |
afterUpgradeHookData_ | bytes | flexible bytes for custom usage in after upgrade hook logic |
_afterUpgradeHook
function _afterUpgradeHook(address fromImplementation_, bytes data_) public virtual
hook called after executing an upgrade from previous fromImplementation_
, with flexible bytes data_
AvocadoMultisigProtected
occupyAvoNonces
function occupyAvoNonces(uint88[] avoNonces_) external
occupies the sequential avoNonces_
in storage. This can be used to cancel / invalidate
a previously signed request(s) because the nonce will be "used" up. - Can only be self-called (authorization same as for cast
methods).
Parameters
Name | Type | Description |
---|---|---|
avoNonces_ | uint88 | sequential ascending ordered nonces to be occupied in storage. E.g. if current AvoNonce is 77 and txs are queued with avoNonces 77, 78 and 79, then you would submit 78, 79 here because 77 will be occupied by the tx executing occupyAvoNonces() as an action itself. If executing via non-sequential nonces, you would submit 77, 78, 79. - Maximum array length is 5. - gap from the current avoNonce will revert (e.g. 79, 80 if current one is 77) |
occupyNonSequentialNonces
function occupyNonSequentialNonces(bytes32[] nonSequentialNonces_) external
occupies the nonSequentialNonces_
in storage. This can be used to cancel / invalidate
previously signed request(s) because the nonce will be "used" up. - Can only be self-called (authorization same as for cast
methods).
Parameters
Name | Type | Description |
---|---|---|
nonSequentialNonces_ | bytes32 | the non-sequential nonces to occupy |
executeOperation
function executeOperation(address[], uint256[], uint256[], address initiator_, bytes data_) external returns (bool)
Parameters
Name | Type | Description |
---|---|---|
address | ||
uint256 | ||
uint256 | ||
initiator_ | address | flashloan initiator -> must be this contract |
data_ | bytes | data bytes containing the abi.encoded() actions that are executed like in CastParams.actions |
_callTargets
function _callTargets(struct AvocadoMultisigStructs.Action[] actions_, uint256 id_) external payable
_executes a low-level .call or .delegateCall on all actions_
.
Can only be self-called by this contract under certain conditions, essentially internal method.
This is called like an external call to create a separate execution frame.
This way we can revert all the actions*
if one fails without reverting the whole transaction.*
Parameters
Name | Type | Description |
---|---|---|
actions_ | struct AvocadoMultisigStructs.Action | the actions to execute (target, data, value, operation) |
id_ | uint256 | id for actions_ , see CastParams.id |
AvocadoMultisigEIP1271
isValidSignature
function isValidSignature(bytes32 hash, bytes signature) external view returns (bytes4 magicValue)
_reverts with AvocadoMultisig__InvalidEIP1271Signature
or AvocadoMultisig__InvalidParams
if signature is invalid.
input message_
is hashed withdomainSeparatorV4()
according to EIP712 typed data (EIP1271*TYPE_HASH
)*
Parameters
Name | Type | Description |
---|---|---|
hash | bytes32 | |
signature | bytes | This can be one of the following: - empty: hash must be a previously signed message in storage then. - 65 bytes: owner signature for a Multisig with only owner as signer (requiredSigners = 1, signers=owner). - a multiple of 85 bytes, through grouping of 65 bytes signature + 20 bytes signer address each. To signal decoding this way, the signature bytes must be prefixed with 0xDEC0DE6520 . - the abi.encode result for SignatureParams struct array. |
signMessage
function signMessage(bytes32 message_) external
Marks a bytes32 message_
(signature digest) as signed, making it verifiable by EIP-1271 isValidSignature()
. - Can only be self-called (authorization same as for cast
methods).
_input message_
is hashed withdomainSeparatorV4()
according to EIP712 typed data (EIP1271*TYPE_HASH
)*
Parameters
Name | Type | Description |
---|---|---|
message_ | bytes32 | data hash to be allow-listed as signed |
removeSignedMessage
function removeSignedMessage(bytes32 message_) external
Removes a previously signMessage()
signed bytes32 message_
(signature digest). - Can only be self-called (authorization same as for cast
methods).
Parameters
Name | Type | Description |
---|---|---|
message_ | bytes32 | data hash to be removed from allow-listed signatures |
AvocadoMultisigSigners
addSigners
function addSigners(address[] addSigners_, uint8 requiredSigners_) external
adds addSigners_
to allowed signers and sets required signers count to requiredSigners_
Note the addSigners_
to be added must: - NOT be duplicates (already present in current allowed signers) - NOT be the zero address - be sorted ascending
removeSigners
function removeSigners(address[] removeSigners_, uint8 requiredSigners_) external
removes removeSigners_
from allowed signers and sets required signers count to requiredSigners_
Note the removeSigners_
to be removed must: - NOT be the owner - be sorted ascending - be present in current allowed signers
setRequiredSigners
function setRequiredSigners(uint8 requiredSigners_) external
sets number of required signers for a valid request to requiredSigners_
AvocadoMultisigCast
getSigDigest
function getSigDigest(struct AvocadoMultisigStructs.CastParams params_, struct AvocadoMultisigStructs.CastForwardParams forwardParams_) public view returns (bytes32)
gets the digest (hash) used to verify an EIP712 signature for cast()
.
This is also used as the non-sequential nonce that will be marked as used when the
request with the matching `params_` and `forwardParams_` is executed via `cast()`.
Parameters
Name | Type | Description |
---|---|---|
params_ | struct AvocadoMultisigStructs.CastParams | Cast params such as id, avoNonce and actions to execute |
forwardParams_ | struct AvocadoMultisigStructs.CastForwardParams | Cast params related to validity of forwarding as instructed and signed |
Return Values
Name | Type | Description |
---|---|---|
0 | bytes32 | bytes32 digest to verify signature (or used as non-sequential nonce) |
verify
function verify(struct AvocadoMultisigStructs.CastParams params_, struct AvocadoMultisigStructs.CastForwardParams forwardParams_, struct AvocadoMultisigStructs.SignatureParams[] signaturesParams_) external view returns (bool)
Verify the signatures for a `cast()' call are valid and can be executed. This does not guarantuee that the tx will not revert, simply that the params are valid. Does not revert and returns successfully if the input is valid. Reverts if input params, signature or avoNonce etc. are invalid.
Parameters
Name | Type | Description |
---|---|---|
params_ | struct AvocadoMultisigStructs.CastParams | Cast params such as id, avoNonce and actions to execute |
forwardParams_ | struct AvocadoMultisigStructs.CastForwardParams | Cast params related to validity of forwarding as instructed and signed |
signaturesParams_ | struct AvocadoMultisigStructs.SignatureParams | SignatureParams structs array for signature and signer: - signature: the EIP712 signature, 65 bytes ECDSA signature for a default EOA. For smart contract signatures it must fulfill the requirements for the relevant smart contract .isValidSignature() EIP1271 logic - signer: address of the signature signer. Must match the actual signature signer or refer to the smart contract that must be an allowed signer and validates signature via EIP1271 |
Return Values
Name | Type | Description |
---|---|---|
0 | bool | returns true if everything is valid, otherwise reverts |
cast
function cast(struct AvocadoMultisigStructs.CastParams params_, struct AvocadoMultisigStructs.CastForwardParams forwardParams_, struct AvocadoMultisigStructs.SignatureParams[] signaturesParams_) external payable returns (bool success_, string revertReason_)
Executes arbitrary actions with valid signatures. Only executable by AvoForwarder.
If one action fails, the transaction doesn't revert, instead emits the CastFailed
event.
In that case, all previous actions are reverted.
On success, emits CastExecuted event.
validates EIP712 signature then executes each action via .call or .delegatecall
Parameters
Name | Type | Description |
---|---|---|
params_ | struct AvocadoMultisigStructs.CastParams | Cast params such as id, avoNonce and actions to execute |
forwardParams_ | struct AvocadoMultisigStructs.CastForwardParams | Cast params related to validity of forwarding as instructed and signed |
signaturesParams_ | struct AvocadoMultisigStructs.SignatureParams | SignatureParams structs array for signature and signer: - signature: the EIP712 signature, 65 bytes ECDSA signature for a default EOA. For smart contract signatures it must fulfill the requirements for the relevant smart contract .isValidSignature() EIP1271 logic - signer: address of the signature signer. Must match the actual signature signer or refer to the smart contract that must be an allowed signer and validates signature via EIP1271 |
Return Values
Name | Type | Description |
---|---|---|
success_ | bool | |
revertReason_ | string |
simulateCast
function simulateCast(struct AvocadoMultisigStructs.CastParams params_, struct AvocadoMultisigStructs.CastForwardParams forwardParams_, struct AvocadoMultisigStructs.SignatureParams[] signaturesParams_) external payable returns (bool success_, string revertReason_)
Simulates a cast()
call with exact same params and execution logic except for: - any gasleft()
use removed to remove potential problems when estimating gas. - reverts on param validations removed (verify validity with verify
instead). - signature validation is skipped (must be manually added to gas estimations).
_tx.origin must be dead address, msg.sender must be AvoForwarder. - set signaturesParams_
to empty to automatically simulate with required signers length.
- ifsignaturesParams*
first element signature is not set, or if first signer is set to
0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF, then gas usage burn is simulated
for verify signature functionality. DO NOT set signature to non-empty for subsequent
elements then; set all signatures to empty!
- ifsignaturesParams*
is set normally, signatures are verified as in actual execute - buffer amounts for mock smart contract signers signature verification must be added
off-chain as this varies on a case per case basis._
estimateCast
function estimateCast(struct AvocadoMultisigStructs.CastParams params_, struct AvocadoMultisigStructs.CastForwardParams forwardParams_, struct AvocadoMultisigStructs.SignatureParams[] signaturesParams_) external payable returns (bool success_, string revertReason_)
Exact same as simulateCast
, just reverts in case of success_
= false to optimize
for use with .estimateGas().
AvocadoMultisigCastAuthorized
getSigDigestAuthorized
function getSigDigestAuthorized(struct AvocadoMultisigStructs.CastParams params_, struct AvocadoMultisigStructs.CastAuthorizedParams authorizedParams_) public view returns (bytes32)
gets the digest (hash) used to verify an EIP712 signature for castAuthorized()
.
This is also the non-sequential nonce that will be marked as used when the request
with the matching `params_` and `authorizedParams_` is executed via `castAuthorized()`.
Parameters
Name | Type | Description |
---|---|---|
params_ | struct AvocadoMultisigStructs.CastParams | Cast params such as id, avoNonce and actions to execute |
authorizedParams_ | struct AvocadoMultisigStructs.CastAuthorizedParams | Cast params related to authorized execution such as maxFee, as signed |
Return Values
Name | Type | Description |
---|---|---|
0 | bytes32 | bytes32 digest to verify signature (or used as non-sequential nonce) |
verifyAuthorized
function verifyAuthorized(struct AvocadoMultisigStructs.CastParams params_, struct AvocadoMultisigStructs.CastAuthorizedParams authorizedParams_, struct AvocadoMultisigStructs.SignatureParams[] signaturesParams_) external view returns (bool)
Verify the signatures for a `castAuthorized()' call are valid and can be executed. This does not guarantuee that the tx will not revert, simply that the params are valid. Does not revert and returns successfully if the input is valid. Reverts if input params, signature or avoNonce etc. are invalid.
Parameters
Name | Type | Description |
---|---|---|
params_ | struct AvocadoMultisigStructs.CastParams | Cast params such as id, avoNonce and actions to execute |
authorizedParams_ | struct AvocadoMultisigStructs.CastAuthorizedParams | Cast params related to authorized execution such as maxFee, as signed |
signaturesParams_ | struct AvocadoMultisigStructs.SignatureParams | SignatureParams structs array for signature and signer: - signature: the EIP712 signature, 65 bytes ECDSA signature for a default EOA. For smart contract signatures it must fulfill the requirements for the relevant smart contract .isValidSignature() EIP1271 logic - signer: address of the signature signer. Must match the actual signature signer or refer to the smart contract that must be an allowed signer and validates signature via EIP1271 |
Return Values
Name | Type | Description |
---|---|---|
0 | bool | returns true if everything is valid, otherwise reverts |
castAuthorized
function castAuthorized(struct AvocadoMultisigStructs.CastParams params_, struct AvocadoMultisigStructs.CastAuthorizedParams authorizedParams_, struct AvocadoMultisigStructs.SignatureParams[] signaturesParams_) external payable returns (bool success_, string revertReason_)
Executes arbitrary actions through authorized transaction sent with valid signatures.
Includes a fee in native network gas token, amount depends on registry calcFee()
.
If one action fails, the transaction doesn't revert, instead emits the CastFailed
event.
In that case, all previous actions are reverted.
On success, emits CastExecuted event.
executes a .call or .delegateCall for every action (depending on params)
Parameters
Name | Type | Description |
---|---|---|
params_ | struct AvocadoMultisigStructs.CastParams | Cast params such as id, avoNonce and actions to execute |
authorizedParams_ | struct AvocadoMultisigStructs.CastAuthorizedParams | Cast params related to authorized execution such as maxFee, as signed |
signaturesParams_ | struct AvocadoMultisigStructs.SignatureParams | SignatureParams structs array for signature and signer: - signature: the EIP712 signature, 65 bytes ECDSA signature for a default EOA. For smart contract signatures it must fulfill the requirements for the relevant smart contract .isValidSignature() EIP1271 logic - signer: address of the signature signer. Must match the actual signature signer or refer to the smart contract that must be an allowed signer and validates signature via EIP1271 |
Return Values
Name | Type | Description |
---|---|---|
success_ | bool | |
revertReason_ | string |
AvocadoMultisigCastChainAgnostic
castChainAgnostic
function castChainAgnostic(struct AvocadoMultisigStructs.CastChainAgnosticParams params_, struct AvocadoMultisigStructs.SignatureParams[] signaturesParams_, struct AvocadoMultisigStructs.ChainAgnosticHash[] chainAgnosticHashes_) external payable returns (bool success_, string revertReason_)
Executes arbitrary actions with valid signatures. Only executable by AvoForwarder.
If one action fails, the transaction doesn't revert, instead emits the CastFailed
event.
In that case, all previous actions are reverted.
On success, emits CastExecuted event.
validates EIP712 signature then executes each action via .call or .delegatecall
Parameters
Name | Type | Description |
---|---|---|
params_ | struct AvocadoMultisigStructs.CastChainAgnosticParams | params containing info and intents regarding actions to be executed. Made up of same params as for cast() plus chain id. |
signaturesParams_ | struct AvocadoMultisigStructs.SignatureParams | SignatureParams structs array for signature and signer: - signature: the EIP712 signature, 65 bytes ECDSA signature for a default EOA. For smart contract signatures it must fulfill the requirements for the relevant smart contract .isValidSignature() EIP1271 logic - signer: address of the signature signer. Must match the actual signature signer or refer to the smart contract that must be an allowed signer and validates signature via EIP1271 |
chainAgnosticHashes_ | struct AvocadoMultisigStructs.ChainAgnosticHash | EIP712 type hashes of CAST_CHAIN_AGNOSTIC_PARAMS_TYPE_HASH for all CastChainAgnosticParams struct array elements as used when creating the signature. Result of getChainAgnosticHashes() . must be set in the same order as when creating the signature. |
Return Values
Name | Type | Description |
---|---|---|
success_ | bool | |
revertReason_ | string |
getChainAgnosticHashes
function getChainAgnosticHashes(struct AvocadoMultisigStructs.CastChainAgnosticParams[] params_) public pure returns (struct AvocadoMultisigStructs.ChainAgnosticHash[] chainAgnosticHashes_)
returns the hashes struct for each CastChainAgnosticParams
element of params_
. The returned array must be
passed into castChainAgnostic()
as the param chainAgnosticHashes_
there (order must be the same).
The returned hash for each element is the EIP712 type hash for CAST_CHAIN_AGNOSTIC_PARAMS_TYPE_HASH
,
as used when the signature digest is built.
getSigDigestChainAgnostic
function getSigDigestChainAgnostic(struct AvocadoMultisigStructs.CastChainAgnosticParams[] params_) public view returns (bytes32)
gets the digest (hash) used to verify an EIP712 signature for castChainAgnostic()
,
built from the CastChainAgnosticParams
.
This is also the non-sequential nonce that will be marked as used when the request
with the matching `params_` is executed via `castChainAgnostic()`.
Parameters
Name | Type | Description |
---|---|---|
params_ | struct AvocadoMultisigStructs.CastChainAgnosticParams | Cast params such as id, avoNonce and actions to execute |
Return Values
Name | Type | Description |
---|---|---|
0 | bytes32 | bytes32 digest to verify signature (or used as non-sequential nonce) |
getSigDigestChainAgnosticFromHashes
function getSigDigestChainAgnosticFromHashes(struct AvocadoMultisigStructs.ChainAgnosticHash[] chainAgnosticHashes_) public view returns (bytes32)
gets the digest (hash) used to verify an EIP712 signature for castChainAgnostic()
,
built from the chain agnostic hashes (result of getChainAgnosticHashes()
).
This is also the non-sequential nonce that will be marked as used when the request
with the matching `params_` is executed via `castChainAgnostic()`.
Parameters
Name | Type | Description |
---|---|---|
chainAgnosticHashes_ | struct AvocadoMultisigStructs.ChainAgnosticHash | EIP712 type hashes of CAST_CHAIN_AGNOSTIC_PARAMS_TYPE_HASH for all CastChainAgnosticParams struct array elements as used when creating the signature. Result of getChainAgnosticHashes() . must be set in the same order as when creating the signature. |
Return Values
Name | Type | Description |
---|---|---|
0 | bytes32 | bytes32 digest to verify signature (or used as non-sequential nonce) |
verifyChainAgnostic
function verifyChainAgnostic(struct AvocadoMultisigStructs.CastChainAgnosticParams params_, struct AvocadoMultisigStructs.SignatureParams[] signaturesParams_, struct AvocadoMultisigStructs.ChainAgnosticHash[] chainAgnosticHashes_) public view returns (bool)
Verify the signatures for a `castChainAgnostic()' call are valid and can be executed. This does not guarantuee that the tx will not revert, simply that the params are valid. Does not revert and returns successfully if the input is valid. Reverts if input params, signature or avoNonce etc. are invalid.
Parameters
Name | Type | Description |
---|---|---|
params_ | struct AvocadoMultisigStructs.CastChainAgnosticParams | params containing info and intents regarding actions to be executed. Made up of same params as for cast() plus chain id. |
signaturesParams_ | struct AvocadoMultisigStructs.SignatureParams | SignatureParams structs array for signature and signer: - signature: the EIP712 signature, 65 bytes ECDSA signature for a default EOA. For smart contract signatures it must fulfill the requirements for the relevant smart contract .isValidSignature() EIP1271 logic - signer: address of the signature signer. Must match the actual signature signer or refer to the smart contract that must be an allowed signer and validates signature via EIP1271 |
chainAgnosticHashes_ | struct AvocadoMultisigStructs.ChainAgnosticHash | EIP712 type hashes of CAST_CHAIN_AGNOSTIC_PARAMS_TYPE_HASH for all CastChainAgnosticParams struct array elements as used when creating the signature. Result of getChainAgnosticHashes() . must be set in the same order as when creating the signature. |
Return Values
Name | Type | Description |
---|---|---|
0 | bool | returns true if everything is valid, otherwise reverts |
simulateCastChainAgnostic
function simulateCastChainAgnostic(struct AvocadoMultisigStructs.CastChainAgnosticParams params_, struct AvocadoMultisigStructs.SignatureParams[] signaturesParams_, struct AvocadoMultisigStructs.ChainAgnosticHash[] chainAgnosticHashes_) external payable returns (bool success_, string revertReason_)
Simulates a castChainAgnostic()
call with exact same params and execution logic except for: - any gasleft()
use removed to remove potential problems when estimating gas. - reverts on param validations removed (verify validity with verify
instead). - signature validation is skipped (must be manually added to gas estimations).
_tx.origin must be dead address, msg.sender must be AvoForwarder. - set signaturesParams_
to empty to automatically simulate with required signers length.
- ifsignaturesParams*
first element signature is not set, or if first signer is set to
0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF, then gas usage burn is simulated
for verify signature functionality. DO NOT set signature to non-empty for subsequent
elements then; set all signatures to empty!
- ifsignaturesParams*
is set normally, signatures are verified as in actual execute - buffer amounts for mock smart contract signers signature verification must be added
off-chain as this varies on a case per case basis._
estimateCastChainAgnostic
function estimateCastChainAgnostic(struct AvocadoMultisigStructs.CastChainAgnosticParams params_, struct AvocadoMultisigStructs.SignatureParams[] signaturesParams_, struct AvocadoMultisigStructs.ChainAgnosticHash[] chainAgnosticHashes_) external payable returns (bool success_, string revertReason_)
Exact same as simulateCastChainAgnostic
, just reverts in case of success_
= false to
optimize for use with .estimateGas().
AvocadoMultisig
constructor
constructor(contract IAvoRegistry avoRegistry_, address avoForwarder_, contract IAvoSignersList avoSignersList_, contract IAvoConfigV1 avoConfigV1_, contract IAvocadoMultisigV1Secondary secondary_) public
constructor sets multiple immutable values for contracts and payFee fallback logic.
Parameters
Name | Type | Description |
---|---|---|
avoRegistry_ | contract IAvoRegistry | address of the avoRegistry (proxy) contract |
avoForwarder_ | address | address of the avoForwarder (proxy) contract to forward tx with valid signatures. must be valid version in AvoRegistry. |
avoSignersList_ | contract IAvoSignersList | address of the AvoSignersList (proxy) contract |
avoConfigV1_ | contract IAvoConfigV1 | AvoConfigV1 contract holding values for authorizedFee values |
secondary_ | contract IAvocadoMultisigV1Secondary | AvocadoMultisigSecondary contract for extended logic |
initialize
function initialize() public
initializer called by AvoFactory after deployment, sets the owner_
as the only signer
receive
receive() external payable
domainSeparatorV4
function domainSeparatorV4() public view returns (bytes32)
returns the domainSeparator for EIP712 signature
domainSeparatorV4ChainAgnostic
function domainSeparatorV4ChainAgnostic() public view returns (bytes32)
returns the domainSeparator for EIP712 signature for castChainAgnostic
isSigner
function isSigner(address signer_) public view returns (bool)
checks if an address signer_
is an allowed signer (returns true if allowed)
signers
function signers() public view returns (address[] signers_)
returns allowed signers on Avocado wich can trigger actions if reaching quorum requiredSigners
.
signers automatically include owner.
requiredSigners
function requiredSigners() public view returns (uint8)
returns the number of required signers
signersCount
function signersCount() public view returns (uint8)
returns the number of allowed signers
owner
function owner() public view returns (address)
Avocado owner
index
function index() public view returns (uint32)
Avocado index (number of Avocado for EOA owner)
avoNonce
function avoNonce() public view returns (uint256)
incrementing nonce for each valid tx executed (to ensure uniqueness)
- AvocadoMultisig_V1
- AvocadoMultisigErrors
- AvocadoMultisigEvents
- AvocadoMultisigStructs
- AvocadoMultisigConstants
- DEFAULT_CHAIN_ID
- DOMAIN_SEPARATOR_NAME
- DOMAIN_SEPARATOR_VERSION
- TYPE_HASH
- CAST_TYPE_HASH
- ACTION_TYPE_HASH
- CAST_PARAMS_TYPE_HASH
- CAST_FORWARD_PARAMS_TYPE_HASH
- CAST_AUTHORIZED_TYPE_HASH
- CAST_AUTHORIZED_PARAMS_TYPE_HASH
- CAST_CHAIN_AGNOSTIC_TYPE_HASH
- CAST_CHAIN_AGNOSTIC_PARAMS_TYPE_HASH
- EIP1271_TYPE_HASH
- MAX_SIGNERS_COUNT
- avoRegistry
- avoForwarder
- avoSignersList
- AUTHORIZED_MIN_FEE
- AUTHORIZED_MAX_FEE
- AUTHORIZED_FEE_COLLECTOR
- AvocadoMultisigVariables
- AvocadoMultisigSelfUpgradeable
- AvocadoMultisigProtected
- AvocadoMultisigEIP1271
- AvocadoMultisigSigners
- AvocadoMultisigCast
- AvocadoMultisigCastAuthorized
- AvocadoMultisigCastChainAgnostic
- AvocadoMultisig