Skip to content

Commit

Permalink
Generalize proxy setup and move version-specific calldata into facade
Browse files Browse the repository at this point in the history
  • Loading branch information
cag committed Dec 28, 2020
1 parent 31c9f9e commit 678e320
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 27 deletions.
28 changes: 20 additions & 8 deletions contracts/solc-0.8/CPKFactory.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity >=0.8.0;

import { IGnosisSafe } from "./dep-ports/IGnosisSafe.sol";
import { IGnosisSafeProxyFactory } from "./dep-ports/IGnosisSafeProxyFactory.sol";
import { ProxyImplSetter } from "./ProxyImplSetter.sol";

Expand Down Expand Up @@ -39,8 +38,7 @@ contract CPKFactory {
address owner,
address safeVersion,
uint256 salt,
address fallbackHandler,
bytes calldata execTxCalldata
bytes[] calldata txsCalldata
)
external
payable
Expand All @@ -56,13 +54,27 @@ contract CPKFactory {

ProxyImplSetter(proxy).setImplementation(safeVersion);

{
address[] memory tmp = new address[](1);
tmp[0] = address(owner);
IGnosisSafe(proxy).setup(tmp, 1, address(0), "", fallbackHandler, address(0), 0, payable(0));
bytes memory lastReturnData;

for (uint i = 0; i < txsCalldata.length; i++) {
bool txSuccess;
(txSuccess, lastReturnData) = proxy.call{value: msg.value}(txsCalldata[i]);
assembly {
// txSuccess == 0 means the call failed
if iszero(txSuccess) {
// The revert data begins one word after the lastReturnData pointer.
// At the location lastReturnData in memory, the length of the bytes is stored.
// This differs from the high-level revert(string(lastReturnData))
// as the high-level version encodes the lastReturnData in a Error(string) object.
// We want to avoid that because the underlying call should have already
// formatted the data in an Error(string) object
revert(add(0x20, lastReturnData), mload(lastReturnData))
}
}
}

proxy.call{value: msg.value}(execTxCalldata);
// final call in txsCalldata is assumed to be execTransaction
execTransactionSuccess = abi.decode(lastReturnData, (bool));

emit CPKCreation(proxy, safeVersion, owner, salt);
}
Expand Down
24 changes: 22 additions & 2 deletions contracts/solc-0.8/CPKFactoryFacade.sol
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,32 @@ contract CPKFactoryFacade {
)
}

bytes[] memory txsCalldata = new bytes[](2);
{
address[] memory owners = new address[](1);
owners[0] = address(owner);
txsCalldata[0] = abi.encodeWithSignature("setup("
"address[]," // owners
"uint256," // threshold
"address," // to
"bytes," // data
"address," // fallbackHandler
"address," // paymentToken
"uint256," // payment
"address" // paymentReceiver
")", owners, uint256(1), address(0), "", fallbackHandler, address(0), uint256(0), payable(0));
}

// msg.data works here as a substitute for encoding because this function's signature
// exactly matches the execTransaction signature from the Gnosis Safe, so the calldata
// encoding will be the same.
txsCalldata[1] = msg.data;

return cpkFactory.createProxyAndExecTransaction{value: msg.value}(
owner,
safeVersion,
salt,
fallbackHandler,
msg.data
txsCalldata
);
}
}
17 changes: 0 additions & 17 deletions contracts/solc-0.8/dep-ports/IGnosisSafe.sol

This file was deleted.

0 comments on commit 678e320

Please sign in to comment.