Skip to content

Commit

Permalink
Implement new factory
Browse files Browse the repository at this point in the history
  • Loading branch information
cag committed Oct 21, 2020
1 parent 9e2c097 commit 4246a9d
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 33 deletions.
75 changes: 45 additions & 30 deletions contracts/CPKFactory.sol
Original file line number Diff line number Diff line change
@@ -1,54 +1,69 @@
pragma solidity >=0.5.0 <0.7.0;

import { Enum } from "@gnosis.pm/safe-contracts/contracts/common/Enum.sol";
import { Proxy } from "@gnosis.pm/safe-contracts/contracts/proxies/Proxy.sol";
import { GnosisSafeProxy } from "@gnosis.pm/safe-contracts/contracts/proxies/GnosisSafeProxy.sol";
import { GnosisSafe } from "@gnosis.pm/safe-contracts/contracts/GnosisSafe.sol";

import { ProxyImplSetter } from "./ProxyImplSetter.sol";

contract CPKFactory {
event ProxyCreation(Proxy proxy);
//keccak256(
// "EIP712Domain(address verifyingContract)"
//);
bytes32 private constant DOMAIN_SEPARATOR_TYPEHASH = 0x035aff83d86937d35b32e04f0ddc6ff469290eef2f1b692d8a815c89404d4749;

//keccak256(
// "SafeTx(address to,uint256 value,bytes data,uint8 operation,uint256 safeTxGas,uint256 baseGas,uint256 gasPrice,address gasToken,address refundReceiver,uint256 nonce)"
//);
bytes32 private constant SAFE_TX_TYPEHASH = 0xbb8310d486368db6bd6f849402fdd73ad53d316b5a4b2644ad6efe0f941286d8;

ProxyImplSetter public proxyImplSetter;

constructor() public {
proxyImplSetter = new ProxyImplSetter();
}

event ProxyCreation(GnosisSafeProxy proxy);

function proxyCreationCode() external pure returns (bytes memory) {
return type(Proxy).creationCode;
return type(GnosisSafeProxy).creationCode;
}

function createProxyAndExecTransaction(
address masterCopy,
address owner,
address safeVersion,
uint256 saltNonce,
address fallbackHandler,
address to,
uint256 value,
bytes calldata data,
Enum.Operation operation
bytes calldata execTxCalldata
)
external
payable
returns (bool execTransactionSuccess)
{
GnosisSafe proxy;
bytes memory deploymentData = abi.encodePacked(type(Proxy).creationCode, abi.encode(masterCopy));
bytes32 salt = keccak256(abi.encode(msg.sender, saltNonce));
// solium-disable-next-line security/no-inline-assembly
assembly {
proxy := create2(0x0, add(0x20, deploymentData), mload(deploymentData), salt)
bytes32 salt = keccak256(abi.encode(owner, saltNonce));

address payable proxy;
{
bytes memory deploymentData = abi.encodePacked(
type(GnosisSafeProxy).creationCode,
abi.encode(proxyImplSetter)
);
// solium-disable-next-line security/no-inline-assembly
assembly {
proxy := create2(0x0, add(0x20, deploymentData), mload(deploymentData), salt)
}
require(proxy != address(0), "create2 call failed");
}
require(address(proxy) != address(0), "create2 call failed");

ProxyImplSetter(proxy).setImplementation(safeVersion);

{
address[] memory tmp = new address[](1);
tmp[0] = address(this);
proxy.setup(tmp, 1, address(0), "", fallbackHandler, address(0), 0, address(0));
tmp[0] = address(owner);
GnosisSafe(proxy).setup(tmp, 1, address(0), "", fallbackHandler, address(0), 0, address(0));
}

execTransactionSuccess = proxy.execTransaction(to, value, data, operation, 0, 0, 0, address(0), address(0),
abi.encodePacked(uint(address(this)), uint(0), uint8(1)));
proxy.call.value(msg.value)(execTxCalldata);

proxy.execTransaction(
address(proxy), 0,
abi.encodeWithSignature("swapOwner(address,address,address)", address(1), address(this), msg.sender),
Enum.Operation.Call,
0, 0, 0, address(0), address(0),
abi.encodePacked(uint(address(this)), uint(0), uint8(1))
);

emit ProxyCreation(Proxy(address(proxy)));
}
emit ProxyCreation(GnosisSafeProxy(proxy));
}
}
57 changes: 57 additions & 0 deletions contracts/CPKFactoryFacade.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
pragma solidity >=0.5.0 <0.7.0;

import { Enum } from "@gnosis.pm/safe-contracts/contracts/common/Enum.sol";
import { CPKFactory } from "./CPKFactory.sol";

contract CPKFactoryFacade {
CPKFactory cpkFactory;
address safeVersion;
uint256 saltNonce;
address fallbackHandler;

constructor(
CPKFactory _cpkFactory,
address _safeVersion,
uint256 _saltNonce,
address _fallbackHandler
) public {
cpkFactory = _cpkFactory;
safeVersion = _safeVersion;
saltNonce = _saltNonce;
fallbackHandler = _fallbackHandler;
}

function execTransaction(
address to,
uint256 value,
bytes calldata data,
Enum.Operation operation,
uint256 safeTxGas,
uint256 baseGas,
uint256 gasPrice,
address gasToken,
address payable refundReceiver,
bytes calldata signature
)
external
payable
returns (bool)
{
address owner;
// solium-disable-next-line security/no-inline-assembly
assembly {
owner := and(
calldataload(add(calldataload(0x124), 0x61)),
0xffffffffffffffffffffffffffffffffffffffff
)
}

return cpkFactory.createProxyAndExecTransaction.value(msg.value)(
owner,
safeVersion,
saltNonce,
fallbackHandler,
msg.data
);
}
}
2 changes: 1 addition & 1 deletion contracts/Deps.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
pragma solidity >=0.5.0 <0.7.0;

import { ProxyFactory } from "@gnosis.pm/safe-contracts/contracts/proxies/ProxyFactory.sol";
import { GnosisSafeProxyFactory } from "@gnosis.pm/safe-contracts/contracts/proxies/GnosisSafeProxyFactory.sol";
import { MultiSend } from "@gnosis.pm/safe-contracts/contracts/libraries/MultiSend.sol";
import { GnosisSafe } from "@gnosis.pm/safe-contracts/contracts/GnosisSafe.sol";
import { DefaultCallbackHandler } from "@gnosis.pm/safe-contracts/contracts/handler/DefaultCallbackHandler.sol";
Expand Down
9 changes: 9 additions & 0 deletions contracts/ProxyImplSetter.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
pragma solidity >=0.5.0 <0.7.0;

contract ProxyImplSetter {
address implementation;

function setImplementation(address _implementation) external {
implementation = _implementation;
}
}
10 changes: 9 additions & 1 deletion migrations-ts/1-deploy-contracts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ module.exports = function(deployer: Truffle.Deployer, network: string) {
if (network === 'test' || network === 'local') {
[
'GnosisSafe',
'ProxyFactory',
'GnosisSafeProxyFactory',
'MultiSend',
'DefaultCallbackHandler',
'Multistep',
Expand All @@ -17,6 +17,14 @@ module.exports = function(deployer: Truffle.Deployer, network: string) {
'ConditionalTokens'
].forEach(deploy);
}

deployer.deploy(
artifacts.require('CPKFactoryFacade'),
artifacts.require('CPKFactory').address,
artifacts.require('GnosisSafe').address,
web3.utils.keccak256(web3.utils.utf8ToHex('Contract Proxy Kit')),
artifacts.require('DefaultCallbackHandler').address,
);
} as Truffle.Migration;

export {};
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
},
"devDependencies": {
"@gnosis.pm/conditional-tokens-contracts": "^0.5.4",
"@gnosis.pm/safe-contracts": "1.1.1",
"@gnosis.pm/safe-contracts": "gnosis/safe-contracts#development",
"@truffle/hdwallet-provider": "^1.1.0",
"@typechain/truffle-v5": "^2.0.2",
"@types/chai": "^4.2.12",
Expand Down

0 comments on commit 4246a9d

Please sign in to comment.