Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

MultiSignerERC7913WeightedUpgradeable

Inherits: Initializable, MultiSignerERC7913Upgradeable

*Extension of {MultiSignerERC7913} that supports weighted signatures. This contract allows assigning different weights to each signer, enabling more flexible governance schemes. For example, some signers could have higher weight than others, allowing for weighted voting or prioritized authorization. Example of usage:

contract MyWeightedMultiSignerAccount is Account, MultiSignerERC7913Weighted, Initializable {
function initialize(bytes[] memory signers, uint64[] memory weights, uint64 threshold) public initializer {
_addSigners(signers);
_setSignerWeights(signers, weights);
_setThreshold(threshold);
}
function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {
_addSigners(signers);
}
function removeSigners(bytes[] memory signers) public onlyEntryPointOrSelf {
_removeSigners(signers);
}
function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {
_setThreshold(threshold);
}
function setSignerWeights(bytes[] memory signers, uint64[] memory weights) public onlyEntryPointOrSelf {
_setSignerWeights(signers, weights);
}
}

IMPORTANT: When setting a threshold value, ensure it matches the scale used for signer weights. For example, if signers have weights like 1, 2, or 3, then a threshold of 4 would require at least two signers (e.g., one with weight 1 and one with weight 3). See {signerWeight}.*

State Variables

MultiSignerERC7913WeightedStorageLocation

bytes32 private constant MultiSignerERC7913WeightedStorageLocation =
    0x5ec62f110612a7ff5e720b9a2f4970583e308ad11d9cde77cb7db3ea251b1f00;

Functions

_getMultiSignerERC7913WeightedStorage

function _getMultiSignerERC7913WeightedStorage() private pure returns (MultiSignerERC7913WeightedStorage storage $);

__MultiSignerERC7913Weighted_init

function __MultiSignerERC7913Weighted_init(bytes[] memory signers_, uint64[] memory weights_, uint64 threshold_)
    internal
    onlyInitializing;

__MultiSignerERC7913Weighted_init_unchained

function __MultiSignerERC7913Weighted_init_unchained(
    bytes[] memory signers_,
    uint64[] memory weights_,
    uint64 threshold_
) internal onlyInitializing;

signerWeight

Gets the weight of a signer. Returns 0 if the signer is not authorized.

function signerWeight(bytes memory signer) public view virtual returns (uint64);

totalWeight

Gets the total weight of all signers.

function totalWeight() public view virtual returns (uint64);

_setSignerWeights

Sets weights for multiple signers at once. Internal version without access control. Requirements: signers and weights arrays must have the same length. Reverts with MultiSignerERC7913WeightedMismatchedLength on mismatch. Each signer must exist in the set of authorized signers. Otherwise reverts with {MultiSignerERC7913NonexistentSigner} Each weight must be greater than 0. Otherwise reverts with {MultiSignerERC7913WeightedInvalidWeight} See {_validateReachableThreshold} for the threshold validation. Emits {ERC7913SignerWeightChanged} for each signer.

function _setSignerWeights(bytes[] memory signers, uint64[] memory weights) internal virtual;

_addSigners

See MultiSignerERC7913-_addSigners. In cases where {totalWeight} is almost type(uint64).max (due to a large _totalExtraWeight), adding new signers could cause the {totalWeight} computation to overflow. Adding a {totalWeight} calls after the new signers are added ensures no such overflow happens.

function _addSigners(bytes[] memory newSigners) internal virtual override;

_removeSigners

See MultiSignerERC7913-_removeSigners. Just like {_addSigners}, this function does not emit {ERC7913SignerWeightChanged} events. The {ERC7913SignerRemoved} event emitted by {MultiSignerERC7913-_removeSigners} is enough to track weights here.

function _removeSigners(bytes[] memory signers) internal virtual override;

_validateReachableThreshold

Sets the threshold for the multisignature operation. Internal version without access control. Requirements: The totalWeight must be >= the {threshold}. Otherwise reverts with {MultiSignerERC7913UnreachableThreshold} NOTE: This function intentionally does not call super._validateReachableThreshold because the base implementation assumes each signer has a weight of 1, which is a subset of this weighted implementation. Consider that multiple implementations of this function may exist in the contract, so important side effects may be missed depending on the linearization order.

function _validateReachableThreshold() internal view virtual override;

_validateThreshold

Validates that the total weight of signers meets the threshold requirement. NOTE: This function intentionally does not call super._validateThreshold because the base implementation assumes each signer has a weight of 1, which is a subset of this weighted implementation. Consider that multiple implementations of this function may exist in the contract, so important side effects may be missed depending on the linearization order.

function _validateThreshold(bytes[] memory signers) internal view virtual override returns (bool);

Events

ERC7913SignerWeightChanged

Emitted when a signer's weight is changed. NOTE: Not emitted in _addSigners or {_removeSigners}. Indexers must rely on {ERC7913SignerAdded} and {ERC7913SignerRemoved} to index a default weight of 1. See {signerWeight}.

event ERC7913SignerWeightChanged(bytes indexed signer, uint64 weight);

Errors

MultiSignerERC7913WeightedInvalidWeight

Thrown when a signer's weight is invalid.

error MultiSignerERC7913WeightedInvalidWeight(bytes signer, uint64 weight);

MultiSignerERC7913WeightedMismatchedLength

Thrown when the arrays lengths don't match. See _setSignerWeights.

error MultiSignerERC7913WeightedMismatchedLength();

Structs

MultiSignerERC7913WeightedStorage

Note: storage-location: erc7201:openzeppelin.storage.MultiSignerERC7913Weighted

struct MultiSignerERC7913WeightedStorage {
    uint64 _totalExtraWeight;
    mapping(bytes signer => uint64) _extraWeights;
}