Address Contract Partially Verified
Address
0xFbcA8B5f5794456B59aD4177E5b212d0Db600BB6
Balance
0 ETH
Nonce
1
Code Size
4889 bytes
Creator
0x3BAf6263...e6ab at tx 0x78b917c1...9117a2
Indexed Transactions
0
Contract Bytecode
4889 bytes
0x608060405234801561000f575f80fd5b50600436106100a6575f3560e01c80635b61be2b1161006e5780635b61be2b146101535780637460837f1461017a5780639e4e73181461018d578063affed0e0146101b4578063ba9a91a5146101bd578063c49f91d3146101e4575f80fd5b806304622c2e146100aa57806311858c7a146100e45780631703a018146100f95780632a9a3cca1461010157806346f0975a1461013e575b5f80fd5b6100d17fa2743967920baf970a18574423a5e903484167f01ff6c1b931ebc9e87d7792b981565b6040519081526020015b60405180910390f35b6100f76100f2366004610fa6565b61020b565b005b6100d15f5481565b61012c61010f36600461108e565b6001600160a01b03165f9081526004602052604090205460ff1690565b60405160ff90911681526020016100db565b610146610731565b6040516100db91906110f1565b6100d17fb8dc02dde922989f2f9c331431088d8b7e24696ed816c001c5b82192a1c91a8f81565b6100f7610188366004611103565b610791565b6100d17fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc681565b6100d160015481565b6100d17f55c2a1c584c6a7013cb797a4622f427c630274bf9e8d9ec26ab9015ddaabcb3381565b6100d17fd87cd6ef79d4e2b95e15ce8abf732db51ec771f1ca2edccf22a46c729ac5647281565b8551875114801561021d575087518751145b61027d5760405162461bcd60e51b815260206004820152602660248201527f4c656e677468206f66207369676e61747572652061727261797320646f6e742060448201526536b0ba31b41760d11b60648201526084015b60405180910390fd5b6001600160a01b03851633146102d55760405162461bcd60e51b815260206004820152601d60248201527f4578656375746f722068617320746f206265207468652073656e6465720000006044820152606401610274565b5f7f16648533e10c4f8bde2a6a78bc78b44e8745ebde881546ce1a9e5758c6c0952d7fb8dc02dde922989f2f9c331431088d8b7e24696ed816c001c5b82192a1c91a8f5f1b86858560405161032b9291906111cf565b6040805191829003822060015460208401959095526001600160a01b039384169183019190915260608201526080810192909252881660a082015260c0810186905260e001604051602081830303815290604052805190602001206040516020016103ad92919061190160f01b81526002810192909252602282015260420190565b6040516020818303038152906040528051906020012090505f805f8b5190505f5b81811015610547575f61042e868f84815181106103ed576103ed6111de565b60200260200101518f8581518110610407576104076111de565b60200260200101518f8681518110610421576104216111de565b6020026020010151610853565b9050836001600160a01b0316816001600160a01b0316116104915760405162461bcd60e51b815260206004820152601c60248201527f5369676e61747572657320617265206f7574206f66206f726465722e000000006044820152606401610274565b6001600160a01b0381165f9081526003602052604090205460ff166105125760405162461bcd60e51b815260206004820152603160248201527f41646472657373207265636f76657265642066726f6d207369676e61747572656044820152701034b9903737ba10309039b4b3b732b91760791b6064820152608401610274565b6001600160a01b0381165f90815260046020526040902054909350839061053c9060ff16866111f2565b9450506001016103ce565b505f548310156105b75760405162461bcd60e51b815260206004820152603560248201527f5369676e6174757265207765696768747320646f6e27742061646420757020746044820152746f207468652072657175697265642071756f72756d60581b6064820152608401610274565b600180546105c4916111f2565b6001556001600160a01b0388163b6106375760405162461bcd60e51b815260206004820152603060248201527f44657374696e6174696f6e20616464726573732073686f756c6420626520612060448201526f636f6e7472616374206164647265737360801b6064820152608401610274565b5f886001600160a01b03168888886040516106539291906111cf565b5f604051808303815f8787f1925050503d805f811461068d576040519150601f19603f3d011682016040523d82523d5f602084013e610692565b606091505b5050809150507f12755f149014f092798e7a1dcebf8826377f7885d03bd09cba554d56703788f78988888b6040516106cd9493929190611217565b60405180910390a1806107225760405162461bcd60e51b815260206004820181905260248201527f5375626d697373696f6e20746f2064657374696e6174696f6e206661696c65646044820152606401610274565b50505050505050505050505050565b6060600280548060200260200160405190810160405280929190818152602001828054801561078757602002820191905f5260205f20905b81546001600160a01b03168152600190910190602001808311610769575b5050505050905090565b3330146108065760405162461bcd60e51b815260206004820152603f60248201527f4f6e6c79207468697320636f6e74726163742063616e20736574207369676e6560448201527f7273206166746572207369676e617475726520766572696669636174696f6e006064820152608401610274565b61081183838361087f565b7fe2c7cc05d6a250c8fb4d739ae5f31172a68a7d6c959f49711fee51c7099c801530848484604051610846949392919061125f565b60405180910390a1505050565b5f805f8061086388888888610c10565b9250925092506108738282610cd8565b50909695505050505050565b6020835111156108e75760405162461bcd60e51b815260206004820152602d60248201527f436f6e747261637420616c6c6f777320616464696e6720757020746f2033322060448201526c39b4b3b732b9399037b7363c9760991b6064820152608401610274565b5f811161092c5760405162461bcd60e51b815260206004820152601360248201527228bab7b93ab69031b0b73737ba10313290181760691b6044820152606401610274565b6002545f5b818110156109db575f60035f60028481548110610950576109506111de565b5f918252602080832091909101546001600160a01b031683528201929092526040018120805460ff1916921515929092179091556002805460049183918590811061099d5761099d6111de565b5f918252602080832091909101546001600160a01b031683528201929092526040019020805460ff191660ff92909216919091179055600101610931565b5083515f908190815b81811015610b7857826001600160a01b0316888281518110610a0857610a086111de565b60200260200101516001600160a01b031611610a665760405162461bcd60e51b815260206004820152601a60248201527f4164647265737365732073686f756c6420626520736f727465640000000000006044820152606401610274565b600160035f8a8481518110610a7d57610a7d6111de565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020015f205f6101000a81548160ff021916908315150217905550868181518110610acc57610acc6111de565b602002602001015160045f8a8481518110610ae957610ae96111de565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020015f205f6101000a81548160ff021916908360ff160217905550868181518110610b3957610b396111de565b602002602001015160ff1684610b4f91906111f2565b9350878181518110610b6357610b636111de565b602002602001015192508060010190506109e4565b5082851115610bef5760405162461bcd60e51b815260206004820152603e60248201527f51756f72756d206d757374206265206c657373207468616e206f72206571756160448201527f6c20746f2073756d206f6620616c6c207369676e6572207765696768747300006064820152608401610274565b8651610c029060029060208a0190610d94565b5050505f9290925550505050565b5f80807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0841115610c4957505f91506003905082610cce565b604080515f808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa158015610c9a573d5f803e3d5ffd5b5050604051601f1901519150506001600160a01b038116610cc557505f925060019150829050610cce565b92505f91508190505b9450945094915050565b5f826003811115610ceb57610ceb6112cf565b03610cf4575050565b6001826003811115610d0857610d086112cf565b03610d265760405163f645eedf60e01b815260040160405180910390fd5b6002826003811115610d3a57610d3a6112cf565b03610d5b5760405163fce698f760e01b815260048101829052602401610274565b6003826003811115610d6f57610d6f6112cf565b03610d90576040516335e2f38360e21b815260048101829052602401610274565b5050565b828054828255905f5260205f20908101928215610de7579160200282015b82811115610de757825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190610db2565b50610df3929150610df7565b5090565b5b80821115610df3575f8155600101610df8565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff81118282101715610e4857610e48610e0b565b604052919050565b5f67ffffffffffffffff821115610e6957610e69610e0b565b5060051b60200190565b5f82601f830112610e82575f80fd5b8135610e95610e9082610e50565b610e1f565b8082825260208201915060208360051b860101925085831115610eb6575f80fd5b602085015b83811015610ee157803560ff81168114610ed3575f80fd5b835260209283019201610ebb565b5095945050505050565b5f82601f830112610efa575f80fd5b8135610f08610e9082610e50565b8082825260208201915060208360051b860101925085831115610f29575f80fd5b602085015b83811015610ee1578035835260209283019201610f2e565b80356001600160a01b0381168114610f5c575f80fd5b919050565b5f8083601f840112610f71575f80fd5b50813567ffffffffffffffff811115610f88575f80fd5b602083019150836020828501011115610f9f575f80fd5b9250929050565b5f805f805f805f8060e0898b031215610fbd575f80fd5b883567ffffffffffffffff811115610fd3575f80fd5b610fdf8b828c01610e73565b985050602089013567ffffffffffffffff811115610ffb575f80fd5b6110078b828c01610eeb565b975050604089013567ffffffffffffffff811115611023575f80fd5b61102f8b828c01610eeb565b96505061103e60608a01610f46565b945061104c60808a01610f46565b935060a0890135925060c089013567ffffffffffffffff81111561106e575f80fd5b61107a8b828c01610f61565b999c989b5096995094979396929594505050565b5f6020828403121561109e575f80fd5b6110a782610f46565b9392505050565b5f8151808452602084019350602083015f5b828110156110e75781516001600160a01b03168652602095860195909101906001016110c0565b5093949350505050565b602081525f6110a760208301846110ae565b5f805f60608486031215611115575f80fd5b833567ffffffffffffffff81111561112b575f80fd5b8401601f8101861361113b575f80fd5b8035611149610e9082610e50565b8082825260208201915060208360051b85010192508883111561116a575f80fd5b6020840193505b828410156111935761118284610f46565b825260209384019390910190611171565b9550505050602084013567ffffffffffffffff8111156111b1575f80fd5b6111bd86828701610e73565b93969395505050506040919091013590565b818382375f9101908152919050565b634e487b7160e01b5f52603260045260245ffd5b8082018082111561121157634e487b7160e01b5f52601160045260245ffd5b92915050565b6001600160a01b03851681526060602082018190528101839052828460808301375f608084830101525f6080601f19601f860116830101905082604083015295945050505050565b6001600160a01b03851681526080602082018190525f90611282908301866110ae565b8281036040840152845180825260208087019201905f5b818110156112ba57835160ff16835260209384019390920191600101611299565b50506060939093019390935250949350505050565b634e487b7160e01b5f52602160045260245ffdfea26469706673582212208a2211d33b6a3e2525a613c20565b9768042c2f970e559b309fdde158d647c3964736f6c634300081a0033
Verified Source Code Partial Match
Compiler: v0.8.26+commit.8a97fa7a
EVM: shanghai
Optimization: Yes (200 runs)
MultiSign.sol 192 lines
// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;
import {ECDSA} from 'openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol';
/**
* @dev This is an implementation of an on-chain multi-sign. On-chain multi-sign ensures that a quorum of signatures
* needs to be submitted before the transaction is passed on to the ERC20 contract(in our case). To verify signatures
* and hash data in a particular way, we use the EIP712.sol scheme: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-712.md.
*
* @custom:security-contact [email protected]
*/
contract MultiSign {
//keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract,bytes32 salt)")
bytes32 constant public EIP712DOMAIN_TYPEHASH = 0xd87cd6ef79d4e2b95e15ce8abf732db51ec771f1ca2edccf22a46c729ac56472;
//keccak256("MultiSignTransaction(address destination,bytes data,uint256 nonce,address executor,uint256 gasLimit)")
bytes32 constant public MULTISIGN_TYPEHASH = 0xb8dc02dde922989f2f9c331431088d8b7e24696ed816c001c5b82192a1c91a8f;
//randomly generated salt
bytes32 constant public SALT = 0x55c2a1c584c6a7013cb797a4622f427c630274bf9e8d9ec26ab9015ddaabcb33;
//keccak256("MultiSign")
bytes32 constant public NAME_HASH = 0xa2743967920baf970a18574423a5e903484167f01ff6c1b931ebc9e87d7792b9;
// keccak256("1")
bytes32 constant public VERSION_HASH = 0xc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6;
bytes32 private immutable DOMAIN_SEPARATOR;
/**
* A state variable to store the total weight of all signatures required to successfully finish
* execution of the `execute` method.
*/
uint256 public quorum;
/**
* Every transaction submitted to this contract should have a nonce associated to it just like
* any other EOA or Contract Account. This state variable holds that value.
*/
uint256 public nonce;
address[] private signersArr;
mapping (address => bool) private isSigner;
mapping (address => uint8) private weights;
/**
* @dev Event emitted when the state of the contract changes.
*
* @param account The contract for which the signer information was updated, which is this.
* @param signers The new array of signer address.
* @param weights The new array of weights of the signers.
* @param quorum The cumulative weight of all signatures should exceed or match this value.
*/
event SignersChanged(address account, address[] signers, uint8[] weights, uint256 quorum);
/**
* @dev Event emitted when the destination contract is called with the provided calldata.
*
* @param destination The contract being called with the provided calldata.
* @param data The encoded bytes that will lead to execution of a method and change state of the destination
* contract.
* @param gasLimit The maximum amount of gas that can be consumed by the destination contract to execute the
* calldata.
*/
event DestinationCalled(address destination, bytes data, uint256 gasLimit);
/**
* Default constructor to initialize the MultiSign contract.
* Signer addresses submitted to the contract should be ordered by their string values.
**/
constructor (address[] memory _signers, uint8[] memory _weights, uint256 _quorum) {
DOMAIN_SEPARATOR = keccak256(abi.encode(
EIP712DOMAIN_TYPEHASH,
NAME_HASH,
VERSION_HASH,
block.chainid,
address(this),
SALT
));
setSigners_(_signers, _weights, _quorum);
emit SignersChanged(address(this), _signers, _weights, _quorum);
}
/**
* @dev Returns the list of signer addresses in an array.
*/
function signers() external view returns (address[] memory) {
return signersArr;
}
/**
* @dev Given an address of a signer, return the weight of it's signature that gets counted
* for this account.
*/
function signerWeight(address signer) external view returns (uint8) {
return weights[signer];
}
// Note that signers_ must be strictly increasing, in order to prevent duplicates
function setSigners_(address[] memory _signers, uint8[] memory _weights, uint256 _quorum) private {
require(_signers.length <= 32, "Contract allows adding up to 32 signers only.");
require(_quorum > 0, "Quorum cannot be 0.");
// remove old signers from map and set weights to 0
uint256 existingSignerArrLength = signersArr.length;
for (uint256 i = 0; i < existingSignerArrLength; ++i) {
isSigner[signersArr[i]] = false;
weights[signersArr[i]] = 0;
}
// add new signers to map
uint256 signatureWeights = 0;
address lastAdd = address(0);
uint256 newSignerArrLength = _signers.length;
for (uint256 i = 0; i < newSignerArrLength; ++i) {
require(_signers[i] > lastAdd, "Addresses should be sorted");
isSigner[_signers[i]] = true;
weights[_signers[i]] = _weights[i];
signatureWeights += _weights[i];
lastAdd = _signers[i];
}
require(_quorum <= signatureWeights, "Quorum must be less than or equal to sum of all signer weights");
// set signers array and quorum
signersArr = _signers;
quorum = _quorum;
}
/**
* @dev This method facilitates changing the signer addresses, their weights and quorum. Since
* this method changes the state of the contract, it emits the `SignersChanged` event at the
* end of successful execution.
* This method can be called by this contract only in order to verify that the signatures are
* from existing signers with privilege to do so.
*/
function setSigners(address[] memory _signers, uint8[] memory _weights, uint256 _quorum) external {
require(msg.sender == address(this), "Only this contract can set signers after signature verification");
setSigners_(_signers, _weights, _quorum);
emit SignersChanged(address(this), _signers, _weights, _quorum);
}
/**
* @dev This method is called by an EOA/funding account with the correct set of signatures to eventually
* make a call to the `destination` with provided call data.
* Example, calls to the ERC20 contract are made from this method for all MultiSign accounts.
*/
function execute(
uint8[] memory sigV, bytes32[] memory sigR, bytes32[] memory sigS, address executor, address destination,
uint256 gasLimit, bytes calldata data
) external {
require(sigR.length == sigS.length && sigR.length == sigV.length, "Length of signature arrays dont match.");
require(executor == msg.sender, "Executor has to be the sender");
bytes32 digest = keccak256(abi.encodePacked(
"\x19\x01",
DOMAIN_SEPARATOR,
keccak256(abi.encode(
MULTISIGN_TYPEHASH,
destination,
keccak256(data),
nonce,
executor,
gasLimit
))
));
uint256 signatureWeights = 0;
address lastAdd = address(0); // cannot have address(0) as an owner
uint256 signaturesLength = sigV.length;
for (uint256 i = 0; i < signaturesLength; ++i) {
address recovered = ECDSA.recover(digest, sigV[i], sigR[i], sigS[i]);
require(recovered > lastAdd, "Signatures are out of order.");
require(isSigner[recovered], "Address recovered from signature is not a signer.");
lastAdd = recovered;
signatureWeights += weights[recovered];
}
require(signatureWeights >= quorum, "Signature weights don't add up to the required quorum");
// If we make it here all signatures are accounted for.
nonce = nonce + 1;
require(destination.code.length > 0, "Destination address should be a contract address");
bool success = false;
(success,) = destination.call{gas: gasLimit}(data);
emit DestinationCalled(destination, data, gasLimit);
require(success, "Submission to destination failed");
}
}
ECDSA.sol 180 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/cryptography/ECDSA.sol)
pragma solidity ^0.8.20;
/**
* @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
*
* These functions can be used to verify that a message was signed by the holder
* of the private keys of a given address.
*/
library ECDSA {
enum RecoverError {
NoError,
InvalidSignature,
InvalidSignatureLength,
InvalidSignatureS
}
/**
* @dev The signature derives the `address(0)`.
*/
error ECDSAInvalidSignature();
/**
* @dev The signature has an invalid length.
*/
error ECDSAInvalidSignatureLength(uint256 length);
/**
* @dev The signature has an S value that is in the upper half order.
*/
error ECDSAInvalidSignatureS(bytes32 s);
/**
* @dev Returns the address that signed a hashed message (`hash`) with `signature` or an error. This will not
* return address(0) without also returning an error description. Errors are documented using an enum (error type)
* and a bytes32 providing additional information about the error.
*
* If no error is returned, then the address can be used for verification purposes.
*
* The `ecrecover` EVM precompile allows for malleable (non-unique) signatures:
* this function rejects them by requiring the `s` value to be in the lower
* half order, and the `v` value to be either 27 or 28.
*
* IMPORTANT: `hash` _must_ be the result of a hash operation for the
* verification to be secure: it is possible to craft signatures that
* recover to arbitrary addresses for non-hashed data. A safe way to ensure
* this is by receiving a hash of the original message (which may otherwise
* be too long), and then calling {MessageHashUtils-toEthSignedMessageHash} on it.
*
* Documentation for signature generation:
* - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
* - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
*/
function tryRecover(
bytes32 hash,
bytes memory signature
) internal pure returns (address recovered, RecoverError err, bytes32 errArg) {
if (signature.length == 65) {
bytes32 r;
bytes32 s;
uint8 v;
// ecrecover takes the signature parameters, and the only way to get them
// currently is to use assembly.
assembly ("memory-safe") {
r := mload(add(signature, 0x20))
s := mload(add(signature, 0x40))
v := byte(0, mload(add(signature, 0x60)))
}
return tryRecover(hash, v, r, s);
} else {
return (address(0), RecoverError.InvalidSignatureLength, bytes32(signature.length));
}
}
/**
* @dev Returns the address that signed a hashed message (`hash`) with
* `signature`. This address can then be used for verification purposes.
*
* The `ecrecover` EVM precompile allows for malleable (non-unique) signatures:
* this function rejects them by requiring the `s` value to be in the lower
* half order, and the `v` value to be either 27 or 28.
*
* IMPORTANT: `hash` _must_ be the result of a hash operation for the
* verification to be secure: it is possible to craft signatures that
* recover to arbitrary addresses for non-hashed data. A safe way to ensure
* this is by receiving a hash of the original message (which may otherwise
* be too long), and then calling {MessageHashUtils-toEthSignedMessageHash} on it.
*/
function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
(address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, signature);
_throwError(error, errorArg);
return recovered;
}
/**
* @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
*
* See https://eips.ethereum.org/EIPS/eip-2098[ERC-2098 short signatures]
*/
function tryRecover(
bytes32 hash,
bytes32 r,
bytes32 vs
) internal pure returns (address recovered, RecoverError err, bytes32 errArg) {
unchecked {
bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
// We do not check for an overflow here since the shift operation results in 0 or 1.
uint8 v = uint8((uint256(vs) >> 255) + 27);
return tryRecover(hash, v, r, s);
}
}
/**
* @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
*/
function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {
(address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, r, vs);
_throwError(error, errorArg);
return recovered;
}
/**
* @dev Overload of {ECDSA-tryRecover} that receives the `v`,
* `r` and `s` signature fields separately.
*/
function tryRecover(
bytes32 hash,
uint8 v,
bytes32 r,
bytes32 s
) internal pure returns (address recovered, RecoverError err, bytes32 errArg) {
// EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
// unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
// the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most
// signatures from current libraries generate a unique signature with an s-value in the lower half order.
//
// If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
// with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
// vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
// these malleable signatures as well.
if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
return (address(0), RecoverError.InvalidSignatureS, s);
}
// If the signature is valid (and not malleable), return the signer address
address signer = ecrecover(hash, v, r, s);
if (signer == address(0)) {
return (address(0), RecoverError.InvalidSignature, bytes32(0));
}
return (signer, RecoverError.NoError, bytes32(0));
}
/**
* @dev Overload of {ECDSA-recover} that receives the `v`,
* `r` and `s` signature fields separately.
*/
function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {
(address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, v, r, s);
_throwError(error, errorArg);
return recovered;
}
/**
* @dev Optionally reverts with the corresponding custom error according to the `error` argument provided.
*/
function _throwError(RecoverError error, bytes32 errorArg) private pure {
if (error == RecoverError.NoError) {
return; // no error: do nothing
} else if (error == RecoverError.InvalidSignature) {
revert ECDSAInvalidSignature();
} else if (error == RecoverError.InvalidSignatureLength) {
revert ECDSAInvalidSignatureLength(uint256(errorArg));
} else if (error == RecoverError.InvalidSignatureS) {
revert ECDSAInvalidSignatureS(errorArg);
}
}
}
Read Contract
EIP712DOMAIN_TYPEHASH 0xc49f91d3 → bytes32
MULTISIGN_TYPEHASH 0x5b61be2b → bytes32
NAME_HASH 0x04622c2e → bytes32
SALT 0xba9a91a5 → bytes32
VERSION_HASH 0x9e4e7318 → bytes32
nonce 0xaffed0e0 → uint256
quorum 0x1703a018 → uint256
signerWeight 0x2a9a3cca → uint8
signers 0x46f0975a → address[]
Write Contract 2 functions
These functions modify contract state and require a wallet transaction to execute.
execute 0x11858c7a
uint8[] sigV
bytes32[] sigR
bytes32[] sigS
address executor
address destination
uint256 gasLimit
bytes data
setSigners 0x7460837f
address[] _signers
uint8[] _weights
uint256 _quorum
Recent Transactions
No transactions found for this address