Skip to content

Commit

Permalink
Allow tx value to be specified for each tx submitted to factory in array
Browse files Browse the repository at this point in the history
  • Loading branch information
cag committed Dec 28, 2020
1 parent 678e320 commit 075c6e8
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 19 deletions.
21 changes: 16 additions & 5 deletions contracts/solc-0.8/CPKFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ pragma solidity >=0.8.0;
import { IGnosisSafeProxyFactory } from "./dep-ports/IGnosisSafeProxyFactory.sol";
import { ProxyImplSetter } from "./ProxyImplSetter.sol";

struct CPKFactoryTx {
uint value;
bytes data;
}

contract CPKFactory {
event CPKCreation(
address indexed proxy,
Expand Down Expand Up @@ -38,7 +43,7 @@ contract CPKFactory {
address owner,
address safeVersion,
uint256 salt,
bytes[] calldata txsCalldata
CPKFactoryTx[] calldata txs
)
external
payable
Expand All @@ -54,11 +59,13 @@ contract CPKFactory {

ProxyImplSetter(proxy).setImplementation(safeVersion);

uint sumTxsValues = 0;
bytes memory lastReturnData;

for (uint i = 0; i < txsCalldata.length; i++) {
for (uint i = 0; i < txs.length; i++) {
bool txSuccess;
(txSuccess, lastReturnData) = proxy.call{value: msg.value}(txsCalldata[i]);
uint txValue = txs[i].value;
sumTxsValues += txValue;
(txSuccess, lastReturnData) = proxy.call{value: txValue}(txs[i].data);
assembly {
// txSuccess == 0 means the call failed
if iszero(txSuccess) {
Expand All @@ -73,7 +80,11 @@ contract CPKFactory {
}
}

// final call in txsCalldata is assumed to be execTransaction
// it is up to the caller to make sure that the msg.value of this method
// equals the sum of all the values in the txs
require(msg.value == sumTxsValues, "msg.value must equal sum of txs' values");

// final call in txs is assumed to be execTransaction
execTransactionSuccess = abi.decode(lastReturnData, (bool));

emit CPKCreation(proxy, safeVersion, owner, salt);
Expand Down
38 changes: 24 additions & 14 deletions contracts/solc-0.8/CPKFactoryFacade.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
pragma solidity >=0.8.0;

import { Enum } from "./dep-ports/Enum.sol";
import { CPKFactory } from "./CPKFactory.sol";
import { CPKFactory, CPKFactoryTx } from "./CPKFactory.sol";

contract CPKFactoryFacade {
CPKFactory cpkFactory;
Expand Down Expand Up @@ -56,32 +56,42 @@ contract CPKFactoryFacade {
)
}

bytes[] memory txsCalldata = new bytes[](2);
CPKFactoryTx[] memory txs = new CPKFactoryTx[](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));
txs[0] = CPKFactoryTx({
value: 0,
data: 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;
txs[1] = CPKFactoryTx({
value: msg.value,
data: msg.data
});

return cpkFactory.createProxyAndExecTransaction{value: msg.value}(
owner,
safeVersion,
salt,
txsCalldata
txs
);
}
}

0 comments on commit 075c6e8

Please sign in to comment.