Source Code
Overview
ETH Balance
0 ETH
ETH Value
$0.00
Cross-Chain Transactions
Loading...
Loading
Contract Name:
GnosisSafeSameAddressMultisig
Compiler Version
v0.8.23+commit.f704f362
Optimization Enabled:
Yes with 750 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.21;
// Gnosis Safe Master Copy interface extracted from the mainnet: https://etherscan.io/address/0xd9db270c1b5e3bd161e8c8503c55ceabee709552#code#F6#L126
interface IGnosisSafe {
/// @dev Gets set of owners.
/// @return Set of Safe owners.
function getOwners() external view returns (address[] memory);
/// @dev Gets threshold.
/// @return Threshold
function getThreshold() external view returns (uint256);
}
/// @dev Zero value when it has to be different from zero.
error ZeroValue();
/// @dev Provided zero address.
error ZeroAddress();
/// @dev Multisig proxy bytecode is not whitelisted.
/// @param multisig Address of a multisig proxy.
error UnauthorizedMultisig(address multisig);
/// @dev Provided incorrect data length.
/// @param expected Expected minimum data length.
/// @param provided Provided data length.
error IncorrectDataLength(uint256 expected, uint256 provided);
/// @dev Provided incorrect multisig threshold.
/// @param expected Expected threshold.
/// @param provided Provided threshold.
error WrongThreshold(uint256 expected, uint256 provided);
/// @dev Provided incorrect number of owners.
/// @param expected Expected number of owners.
/// @param provided Provided number of owners.
error WrongNumOwners(uint256 expected, uint256 provided);
/// @dev Provided incorrect multisig owner.
/// @param provided Provided owner address.
error WrongOwner(address provided);
/// @dev Multisig transaction resulted in a failure.
/// @param provided Provided multisig address.
error MultisigExecFailed(address provided);
/// @title Gnosis Safe Same Address - Smart contract for Gnosis Safe verification of an already existent multisig address.
/// @author Aleksandr Kuperman - <[email protected]>
contract GnosisSafeSameAddressMultisig {
// Default data size to be parsed as an address of a Gnosis Safe multisig proxy address
// This exact size suggests that all the changes to the multisig have been performed and only validation is needed
uint256 public constant DEFAULT_DATA_LENGTH = 20;
// Approved multisig proxy hash
bytes32 public immutable proxyHash;
/// @dev GnosisSafeSameAddressMultisig constructor.
/// @param _proxyHash Approved multisig proxy hash.
constructor(bytes32 _proxyHash) {
if (_proxyHash == bytes32(0)) {
revert ZeroValue();
}
// Record provided multisig proxy bytecode hash
proxyHash = _proxyHash;
}
/// @dev Updates and/or verifies the existent gnosis safe multisig for changed owners and threshold.
/// @notice This function operates with existent multisig proxy that is requested to be updated in terms of
/// the set of owners' addresses and the threshold. There are two scenarios possible:
/// 1. The multisig proxy is already updated before reaching this function. Then the multisig address
/// must be passed as a payload such that its owners and threshold are verified against those specified
/// in the argument list.
/// 2. The multisig proxy is not yet updated. Then the multisig address must be passed in a packed bytes of
/// data along with the Gnosis Safe `execTransaction()` function arguments packed payload. That payload
/// is going to modify the mulsisig proxy as per its signed transaction. At the end, the updated multisig
/// proxy is going to be verified with the provided set of owners' addresses and the threshold.
/// Note that owners' addresses in the multisig are stored in reverse order compared to how they were added:
/// https://etherscan.io/address/0xd9db270c1b5e3bd161e8c8503c55ceabee709552#code#F6#L56
/// @param owners Set of updated multisig owners to verify against.
/// @param threshold Updated number for multisig transaction confirmations.
/// @param data Packed data containing address of an existent gnosis safe multisig and a payload to call the multisig with.
/// @return multisig Address of a multisig (proxy).
function create(
address[] memory owners,
uint256 threshold,
bytes memory data
) external returns (address multisig)
{
// Check for the correct data length
uint256 dataLength = data.length;
if (dataLength < DEFAULT_DATA_LENGTH) {
revert IncorrectDataLength(DEFAULT_DATA_LENGTH, data.length);
}
// Read the proxy multisig address (20 bytes) and the multisig-related data
assembly {
multisig := mload(add(data, DEFAULT_DATA_LENGTH))
}
// Check that the multisig address corresponds to the authorized multisig proxy bytecode hash
bytes32 multisigProxyHash = keccak256(multisig.code);
if (proxyHash != multisigProxyHash) {
revert UnauthorizedMultisig(multisig);
}
// If provided, read the payload that is going to change the multisig ownership and threshold
// The payload is expected to be the `execTransaction()` function call with all its arguments and signature(s)
if (dataLength > DEFAULT_DATA_LENGTH) {
uint256 payloadLength = dataLength - DEFAULT_DATA_LENGTH;
bytes memory payload = new bytes(payloadLength);
for (uint256 i = 0; i < payloadLength; ++i) {
payload[i] = data[i + DEFAULT_DATA_LENGTH];
}
// Call the multisig with the provided payload
(bool success, ) = multisig.call(payload);
if (!success) {
revert MultisigExecFailed(multisig);
}
}
// Get the provided proxy multisig owners and threshold
address[] memory checkOwners = IGnosisSafe(multisig).getOwners();
uint256 checkThreshold = IGnosisSafe(multisig).getThreshold();
// Verify updated multisig proxy for provided owners and threshold
if (threshold != checkThreshold) {
revert WrongThreshold(checkThreshold, threshold);
}
uint256 numOwners = owners.length;
if (numOwners != checkOwners.length) {
revert WrongNumOwners(checkOwners.length, numOwners);
}
// The owners' addresses in the multisig itself are stored in reverse order compared to how they were added:
// https://etherscan.io/address/0xd9db270c1b5e3bd161e8c8503c55ceabee709552#code#F6#L56
// Thus, the check must be carried out accordingly.
for (uint256 i = 0; i < numOwners; ++i) {
if (owners[i] != checkOwners[numOwners - i - 1]) {
revert WrongOwner(owners[i]);
}
}
}
}{
"optimizer": {
"enabled": true,
"runs": 750
},
"evmVersion": "paris",
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"metadata": {
"useLiteralContent": true
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"bytes32","name":"_proxyHash","type":"bytes32"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"expected","type":"uint256"},{"internalType":"uint256","name":"provided","type":"uint256"}],"name":"IncorrectDataLength","type":"error"},{"inputs":[{"internalType":"address","name":"provided","type":"address"}],"name":"MultisigExecFailed","type":"error"},{"inputs":[{"internalType":"address","name":"multisig","type":"address"}],"name":"UnauthorizedMultisig","type":"error"},{"inputs":[{"internalType":"uint256","name":"expected","type":"uint256"},{"internalType":"uint256","name":"provided","type":"uint256"}],"name":"WrongNumOwners","type":"error"},{"inputs":[{"internalType":"address","name":"provided","type":"address"}],"name":"WrongOwner","type":"error"},{"inputs":[{"internalType":"uint256","name":"expected","type":"uint256"},{"internalType":"uint256","name":"provided","type":"uint256"}],"name":"WrongThreshold","type":"error"},{"inputs":[],"name":"ZeroValue","type":"error"},{"inputs":[],"name":"DEFAULT_DATA_LENGTH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"owners","type":"address[]"},{"internalType":"uint256","name":"threshold","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"create","outputs":[{"internalType":"address","name":"multisig","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"proxyHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"}]Contract Creation Code
60a060405234801561001057600080fd5b5060405161088638038061088683398101604081905261002f91610055565b8061004d57604051637c946ed760e01b815260040160405180910390fd5b60805261006e565b60006020828403121561006757600080fd5b5051919050565b6080516107f761008f60003960008181604b015261012701526107f76000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c8063809cee2f14610046578063f02fb77414610080578063f398dba814610088575b600080fd5b61006d7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b61006d601481565b61009b6100963660046105b7565b6100b3565b6040516001600160a01b039091168152602001610077565b805160009060148110156100ec578251604051631a64813d60e11b81526014600482015260248101919091526044015b60405180910390fd5b601483015191506000826001600160a01b0316803b806020016040519081016040528181526000908060200190933c805190602001209050807f00000000000000000000000000000000000000000000000000000000000000001461016e5760405162a2307960e51b81526001600160a01b03841660048201526024016100e3565b60148211156102d757600061018460148461069d565b905060008167ffffffffffffffff8111156101a1576101a16104c4565b6040519080825280601f01601f1916602001820160405280156101cb576020820181803683370190505b50905060005b8281101561024957866101e56014836106b6565b815181106101f5576101f56106c9565b602001015160f81c60f81b828281518110610212576102126106c9565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506001016101d1565b506000856001600160a01b03168260405161026491906106df565b6000604051808303816000865af19150503d80600081146102a1576040519150601f19603f3d011682016040523d82523d6000602084013e6102a6565b606091505b50509050806102d357604051632aacb4bd60e21b81526001600160a01b03871660048201526024016100e3565b5050505b6000836001600160a01b031663a0e67e2b6040518163ffffffff1660e01b8152600401600060405180830381865afa158015610317573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261033f919081019061070e565b90506000846001600160a01b031663e75235b86040518163ffffffff1660e01b8152600401602060405180830381865afa158015610381573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103a591906107a8565b90508087146103d157604051635372461560e01b815260048101829052602481018890526044016100e3565b87518251811461040157825160405163f720290d60e01b81526004810191909152602481018290526044016100e3565b60005b818110156104b757836001610419838561069d565b610423919061069d565b81518110610433576104336106c9565b60200260200101516001600160a01b03168a8281518110610456576104566106c9565b60200260200101516001600160a01b0316146104af5789818151811061047e5761047e6106c9565b60200260200101516040516374dba67360e01b81526004016100e391906001600160a01b0391909116815260200190565b600101610404565b5050505050509392505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715610503576105036104c4565b604052919050565b600067ffffffffffffffff821115610525576105256104c4565b5060051b60200190565b6001600160a01b038116811461054457600080fd5b50565b600082601f83011261055857600080fd5b813567ffffffffffffffff811115610572576105726104c4565b610585601f8201601f19166020016104da565b81815284602083860101111561059a57600080fd5b816020850160208301376000918101602001919091529392505050565b6000806000606084860312156105cc57600080fd5b833567ffffffffffffffff808211156105e457600080fd5b818601915086601f8301126105f857600080fd5b8135602061060d6106088361050b565b6104da565b82815260059290921b8401810191818101908a84111561062c57600080fd5b948201945b838610156106535785356106448161052f565b82529482019490820190610631565b975050870135945050604086013591508082111561067057600080fd5b5061067d86828701610547565b9150509250925092565b634e487b7160e01b600052601160045260246000fd5b818103818111156106b0576106b0610687565b92915050565b808201808211156106b0576106b0610687565b634e487b7160e01b600052603260045260246000fd5b6000825160005b8181101561070057602081860181015185830152016106e6565b506000920191825250919050565b6000602080838503121561072157600080fd5b825167ffffffffffffffff81111561073857600080fd5b8301601f8101851361074957600080fd5b80516107576106088261050b565b81815260059190911b8201830190838101908783111561077657600080fd5b928401925b8284101561079d57835161078e8161052f565b8252928401929084019061077b565b979650505050505050565b6000602082840312156107ba57600080fd5b505191905056fea264697066735822122061c526595d40f3df0151de1eb5662587584ac2b55b8ca9a13ed4eff77e32e72f64736f6c63430008170033b89c1b3bdf2cf8827818646bce9a8f6e372885f8c55e5c07acbd307cb133b000
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100415760003560e01c8063809cee2f14610046578063f02fb77414610080578063f398dba814610088575b600080fd5b61006d7fb89c1b3bdf2cf8827818646bce9a8f6e372885f8c55e5c07acbd307cb133b00081565b6040519081526020015b60405180910390f35b61006d601481565b61009b6100963660046105b7565b6100b3565b6040516001600160a01b039091168152602001610077565b805160009060148110156100ec578251604051631a64813d60e11b81526014600482015260248101919091526044015b60405180910390fd5b601483015191506000826001600160a01b0316803b806020016040519081016040528181526000908060200190933c805190602001209050807fb89c1b3bdf2cf8827818646bce9a8f6e372885f8c55e5c07acbd307cb133b0001461016e5760405162a2307960e51b81526001600160a01b03841660048201526024016100e3565b60148211156102d757600061018460148461069d565b905060008167ffffffffffffffff8111156101a1576101a16104c4565b6040519080825280601f01601f1916602001820160405280156101cb576020820181803683370190505b50905060005b8281101561024957866101e56014836106b6565b815181106101f5576101f56106c9565b602001015160f81c60f81b828281518110610212576102126106c9565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506001016101d1565b506000856001600160a01b03168260405161026491906106df565b6000604051808303816000865af19150503d80600081146102a1576040519150601f19603f3d011682016040523d82523d6000602084013e6102a6565b606091505b50509050806102d357604051632aacb4bd60e21b81526001600160a01b03871660048201526024016100e3565b5050505b6000836001600160a01b031663a0e67e2b6040518163ffffffff1660e01b8152600401600060405180830381865afa158015610317573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261033f919081019061070e565b90506000846001600160a01b031663e75235b86040518163ffffffff1660e01b8152600401602060405180830381865afa158015610381573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103a591906107a8565b90508087146103d157604051635372461560e01b815260048101829052602481018890526044016100e3565b87518251811461040157825160405163f720290d60e01b81526004810191909152602481018290526044016100e3565b60005b818110156104b757836001610419838561069d565b610423919061069d565b81518110610433576104336106c9565b60200260200101516001600160a01b03168a8281518110610456576104566106c9565b60200260200101516001600160a01b0316146104af5789818151811061047e5761047e6106c9565b60200260200101516040516374dba67360e01b81526004016100e391906001600160a01b0391909116815260200190565b600101610404565b5050505050509392505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715610503576105036104c4565b604052919050565b600067ffffffffffffffff821115610525576105256104c4565b5060051b60200190565b6001600160a01b038116811461054457600080fd5b50565b600082601f83011261055857600080fd5b813567ffffffffffffffff811115610572576105726104c4565b610585601f8201601f19166020016104da565b81815284602083860101111561059a57600080fd5b816020850160208301376000918101602001919091529392505050565b6000806000606084860312156105cc57600080fd5b833567ffffffffffffffff808211156105e457600080fd5b818601915086601f8301126105f857600080fd5b8135602061060d6106088361050b565b6104da565b82815260059290921b8401810191818101908a84111561062c57600080fd5b948201945b838610156106535785356106448161052f565b82529482019490820190610631565b975050870135945050604086013591508082111561067057600080fd5b5061067d86828701610547565b9150509250925092565b634e487b7160e01b600052601160045260246000fd5b818103818111156106b0576106b0610687565b92915050565b808201808211156106b0576106b0610687565b634e487b7160e01b600052603260045260246000fd5b6000825160005b8181101561070057602081860181015185830152016106e6565b506000920191825250919050565b6000602080838503121561072157600080fd5b825167ffffffffffffffff81111561073857600080fd5b8301601f8101851361074957600080fd5b80516107576106088261050b565b81815260059190911b8201830190838101908783111561077657600080fd5b928401925b8284101561079d57835161078e8161052f565b8252928401929084019061077b565b979650505050505050565b6000602082840312156107ba57600080fd5b505191905056fea264697066735822122061c526595d40f3df0151de1eb5662587584ac2b55b8ca9a13ed4eff77e32e72f64736f6c63430008170033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
b89c1b3bdf2cf8827818646bce9a8f6e372885f8c55e5c07acbd307cb133b000
-----Decoded View---------------
Arg [0] : _proxyHash (bytes32): 0xb89c1b3bdf2cf8827818646bce9a8f6e372885f8c55e5c07acbd307cb133b000
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : b89c1b3bdf2cf8827818646bce9a8f6e372885f8c55e5c07acbd307cb133b000
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$6,202.97
Net Worth in ETH
2.551942
Token Allocations
OLAS
100.00%
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|---|---|---|---|---|
| OP | 100.00% | $0.043238 | 143,460 | $6,202.97 |
Loading...
Loading
Loading...
Loading
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.