Blockchain / Global / Address
Contract
0xa6B71E26C5e0845f74c812102Ca7114b6a896AB2
- Balance
- 0 SOMI
- Transactions sent
- 135
- Type
- Contract · 3,774 bytes of code
GnosisSafeProxyFactory Verified
- Compiler
- solc 0.7.6+commit.7338295f
- Language
- Solidity
- Optimization
- No
- EVM version
- —
- License
- —
- Verified
- 2026-10-12
contracts/proxies/GnosisSafeProxyFactory.sol
and 2 more files
Solidity
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity >=0.7.0 <0.9.0;
import "./GnosisSafeProxy.sol";
import "./IProxyCreationCallback.sol";
/// @title Proxy Factory - Allows to create new proxy contact and execute a message call to the new proxy within one transaction.
/// @author Stefan George - <stefan@gnosis.pm>
contract GnosisSafeProxyFactory {
event ProxyCreation(GnosisSafeProxy proxy, address singleton);
/// @dev Allows to create new proxy contact and execute a message call to the new proxy within one transaction.
/// @param singleton Address of singleton contract.
/// @param data Payload for message call sent to new proxy contract.
function createProxy(address singleton, bytes memory data) public returns (GnosisSafeProxy proxy) {
proxy = new GnosisSafeProxy(singleton);
if (data.length > 0)
// solhint-disable-next-line no-inline-assembly
assembly {
if eq(call(gas(), proxy, 0, add(data, 0x20), mload(data), 0, 0), 0) {
revert(0, 0)
}
}
emit ProxyCreation(proxy, singleton);
}
/// @dev Allows to retrieve the runtime code of a deployed Proxy. This can be used to check that the expected Proxy was deployed.
function proxyRuntimeCode() public pure returns (bytes memory) {
return type(GnosisSafeProxy).runtimeCode;
}
/// @dev Allows to retrieve the creation code used for the Proxy deployment. With this it is easily possible to calculate predicted address.
function proxyCreationCode() public pure returns (bytes memory) {
return type(GnosisSafeProxy).creationCode;
}
/// @dev Allows to create new proxy contact using CREATE2 but it doesn't run the initializer.
/// This method is only meant as an utility to be called from other methods
/// @param _singleton Address of singleton contract.
/// @param initializer Payload for message call sent to new proxy contract.
/// @param saltNonce Nonce that will be used to generate the salt to calculate the address of the new proxy contract.
function deployProxyWithNonce(
address _singleton,
bytes memory initializer,
uint256 saltNonce
) internal returns (GnosisSafeProxy proxy) {
// If the initializer changes the proxy address should change too. Hashing the initializer data is cheaper than just concatinating it
bytes32 salt = keccak256(abi.encodePacked(keccak256(initializer), saltNonce));
bytes memory deploymentData = abi.encodePacked(type(GnosisSafeProxy).creationCode, uint256(uint160(_singleton)));
// solhint-disable-next-line no-inline-assembly
assembly {
proxy := create2(0x0, add(0x20, deploymentData), mload(deploymentData), salt)
}
require(address(proxy) != address(0), "Create2 call failed");
}
/// @dev Allows to create new proxy contact and execute a message call to the new proxy within one transaction.
/// @param _singleton Address of singleton contract.
/// @param initializer Payload for message call sent to new proxy contract.
/// @param saltNonce Nonce that will be used to generate the salt to calculate the address of the new proxy contract.
function createProxyWithNonce(
address _singleton,
bytes memory initializer,
uint256 saltNonce
) public returns (GnosisSafeProxy proxy) {
proxy = deployProxyWithNonce(_singleton, initializer, saltNonce);
if (initializer.length > 0)
// solhint-disable-next-line no-inline-assembly
assembly {
if eq(call(gas(), proxy, 0, add(initializer, 0x20), mload(initializer), 0, 0), 0) {
revert(0, 0)
}
}
emit ProxyCreation(proxy, _singleton);
}
/// @dev Allows to create new proxy contact, execute a message call to the new proxy and call a specified callback within one transaction
/// @param _singleton Address of singleton contract.
/// @param initializer Payload for message call sent to new proxy contract.
/// @param saltNonce Nonce that will be used to generate the salt to calculate the address of the new proxy contract.
/// @param callback Callback that will be invoced after the new proxy contract has been successfully deployed and initialized.
function createProxyWithCallback(
address _singleton,
bytes memory initializer,
uint256 saltNonce,
IProxyCreationCallback callback
) public returns (GnosisSafeProxy proxy) {
uint256 saltNonceWithCallback = uint256(keccak256(abi.encodePacked(saltNonce, callback)));
proxy = createProxyWithNonce(_singleton, initializer, saltNonceWithCallback);
if (address(callback) != address(0)) callback.proxyCreated(proxy, _singleton, initializer, saltNonce);
}
/// @dev Allows to get the address for a new proxy contact created via `createProxyWithNonce`
/// This method is only meant for address calculation purpose when you use an initializer that would revert,
/// therefore the response is returned with a revert. When calling this method set `from` to the address of the proxy factory.
/// @param _singleton Address of singleton contract.
/// @param initializer Payload for message call sent to new proxy contract.
/// @param saltNonce Nonce that will be used to generate the salt to calculate the address of the new proxy contract.
function calculateCreateProxyWithNonceAddress(
address _singleton,
bytes calldata initializer,
uint256 saltNonce
) external returns (GnosisSafeProxy proxy) {
proxy = deployProxyWithNonce(_singleton, initializer, saltNonce);
revert(string(abi.encodePacked(proxy)));
}
}
Other files
contracts/proxies/GnosisSafeProxy.sol
// SPDX-License-Identifier: LGPL-3.0-only pragma solidity >=0.7.0 <0.9.0; /// @title IProxy - Helper interface to access masterCopy of the Proxy on-chain /// @author Richard Meissner - <richard@gnosis.io> interface IProxy { function masterCopy() external view returns (address); } /// @title GnosisSafeProxy - Generic proxy contract allows to execute all transactions applying the code of a master contract. /// @author Stefan George - <stefan@gnosis.io> /// @author Richard Meissner - <richard@gnosis.io> contract GnosisSafeProxy { // singleton always needs to be first declared variable, to ensure that it is at the same location in the contracts to which calls are delegated. // To reduce deployment costs this variable is internal and needs to be retrieved via `getStorageAt` address internal singleton; /// @dev Constructor function sets address of singleton contract. /// @param _singleton Singleton address. constructor(address _singleton) { require(_singleton != address(0), "Invalid singleton address provided"); singleton = _singleton; } /// @dev Fallback function forwards all transactions and returns all received return data. fallback() external payable { // solhint-disable-next-line no-inline-assembly assembly { let _singleton := and(sload(0), 0xffffffffffffffffffffffffffffffffffffffff) // 0xa619486e == keccak("masterCopy()"). The value is right padded to 32-bytes with 0s if eq(calldataload(0), 0xa619486e00000000000000000000000000000000000000000000000000000000) { mstore(0, _singleton) return(0, 0x20) } calldatacopy(0, 0, calldatasize()) let success := delegatecall(gas(), _singleton, 0, calldatasize(), 0, 0) returndatacopy(0, 0, returndatasize()) if eq(success, 0) { revert(0, returndatasize()) } return(0, returndatasize()) } } }contracts/proxies/IProxyCreationCallback.sol
// SPDX-License-Identifier: LGPL-3.0-only pragma solidity >=0.7.0 <0.9.0; import "./GnosisSafeProxy.sol"; interface IProxyCreationCallback { function proxyCreated( GnosisSafeProxy proxy, address _singleton, bytes calldata initializer, uint256 saltNonce ) external; }
ABI · 7 entries
json
[
{
"name": "ProxyCreation",
"type": "event",
"inputs": [
{
"name": "proxy",
"type": "address",
"indexed": false,
"internalType": "contract GnosisSafeProxy"
},
{
"name": "singleton",
"type": "address",
"indexed": false,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "calculateCreateProxyWithNonceAddress",
"type": "function",
"inputs": [
{
"name": "_singleton",
"type": "address",
"internalType": "address"
},
{
"name": "initializer",
"type": "bytes",
"internalType": "bytes"
},
{
"name": "saltNonce",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "proxy",
"type": "address",
"internalType": "contract GnosisSafeProxy"
}
],
"stateMutability": "nonpayable"
},
{
"name": "createProxy",
"type": "function",
"inputs": [
{
"name": "singleton",
"type": "address",
"internalType": "address"
},
{
"name": "data",
"type": "bytes",
"internalType": "bytes"
}
],
"outputs": [
{
"name": "proxy",
"type": "address",
"internalType": "contract GnosisSafeProxy"
}
],
"stateMutability": "nonpayable"
},
{
"name": "createProxyWithCallback",
"type": "function",
"inputs": [
{
"name": "_singleton",
"type": "address",
"internalType": "address"
},
{
"name": "initializer",
"type": "bytes",
"internalType": "bytes"
},
{
"name": "saltNonce",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "callback",
"type": "address",
"internalType": "contract IProxyCreationCallback"
}
],
"outputs": [
{
"name": "proxy",
"type": "address",
"internalType": "contract GnosisSafeProxy"
}
],
"stateMutability": "nonpayable"
},
{
"name": "createProxyWithNonce",
"type": "function",
"inputs": [
{
"name": "_singleton",
"type": "address",
"internalType": "address"
},
{
"name": "initializer",
"type": "bytes",
"internalType": "bytes"
},
{
"name": "saltNonce",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "proxy",
"type": "address",
"internalType": "contract GnosisSafeProxy"
}
],
"stateMutability": "nonpayable"
},
{
"name": "proxyCreationCode",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "bytes",
"internalType": "bytes"
}
],
"stateMutability": "pure"
},
{
"name": "proxyRuntimeCode",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "bytes",
"internalType": "bytes"
}
],
"stateMutability": "pure"
}
]