Skip to content

Commit

Permalink
Fix simulation contract deployment during broadcast
Browse files Browse the repository at this point in the history
  • Loading branch information
mdehoog committed Dec 11, 2024
1 parent ed36aac commit c6a9989
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 20 deletions.
20 changes: 14 additions & 6 deletions script/universal/MultisigBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,12 @@ abstract contract MultisigBase is CommonBase {
IGnosisSafe(_safe).checkSignatures({dataHash: hash, data: data, signatures: _signatures});
}

function _executeTransaction(address _safe, IMulticall3.Call3[] memory _calls, bytes memory _signatures)
internal
returns (Vm.AccountAccess[] memory, Simulation.Payload memory)
{
function _executeTransaction(
address _safe,
IMulticall3.Call3[] memory _calls,
bytes memory _signatures,
bool _broadcast
) internal returns (Vm.AccountAccess[] memory, Simulation.Payload memory) {
bytes memory data = abi.encodeCall(IMulticall3.aggregate3, (_calls));
bytes32 hash = _getTransactionHash(_safe, data);
_signatures = Signatures.prepareSignatures(_safe, hash, _signatures);
Expand All @@ -102,7 +104,7 @@ abstract contract MultisigBase is CommonBase {
Simulation.logSimulationLink({_to: _safe, _from: msg.sender, _data: simData});

vm.startStateDiffRecording();
bool success = _execTransaction(_safe, data, _signatures);
bool success = _execTransaction(_safe, data, _signatures, _broadcast);
Vm.AccountAccess[] memory accesses = vm.stopAndReturnStateDiff();
require(success, "MultisigBase::_executeTransaction: Transaction failed");
require(accesses.length > 0, "MultisigBase::_executeTransaction: No state changes");
Expand Down Expand Up @@ -164,7 +166,13 @@ abstract contract MultisigBase is CommonBase {
);
}

function _execTransaction(address _safe, bytes memory _data, bytes memory _signatures) internal returns (bool) {
function _execTransaction(address _safe, bytes memory _data, bytes memory _signatures, bool _broadcast)
internal
returns (bool)
{
if (_broadcast) {
vm.broadcast();
}
return IGnosisSafe(_safe).execTransaction({
to: MULTICALL3_ADDRESS,
value: 0,
Expand Down
6 changes: 2 additions & 4 deletions script/universal/MultisigBuilder.sol
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ abstract contract MultisigBuilder is MultisigBase {
vm.store(safe, SAFE_NONCE_SLOT, bytes32(_getNonce(safe)));

(Vm.AccountAccess[] memory accesses, Simulation.Payload memory simPayload) =
_executeTransaction(safe, _buildCalls(), _signatures);
_executeTransaction(safe, _buildCalls(), _signatures, false);

_postRun(accesses, simPayload);
_postCheck(accesses, simPayload);
Expand All @@ -117,10 +117,8 @@ abstract contract MultisigBuilder is MultisigBase {
* step 1. In this scenario, the caller doesn't need to be a signer of the multisig.
*/
function run(bytes memory _signatures) public {
vm.startBroadcast();
(Vm.AccountAccess[] memory accesses, Simulation.Payload memory simPayload) =
_executeTransaction(_ownerSafe(), _buildCalls(), _signatures);
vm.stopBroadcast();
_executeTransaction(_ownerSafe(), _buildCalls(), _signatures, true);

_postRun(accesses, simPayload);
_postCheck(accesses, simPayload);
Expand Down
8 changes: 2 additions & 6 deletions script/universal/NestedMultisigBuilder.sol
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,8 @@ abstract contract NestedMultisigBuilder is MultisigBase {
IMulticall3.Call3[] memory nestedCalls = _buildCalls();
IMulticall3.Call3 memory call = _generateApproveCall(_ownerSafe(), nestedCalls);

vm.startBroadcast();
(Vm.AccountAccess[] memory accesses, Simulation.Payload memory simPayload) =
_executeTransaction(_signerSafe, _toArray(call), _signatures);
vm.stopBroadcast();
_executeTransaction(_signerSafe, _toArray(call), _signatures, true);

_postApprove(accesses, simPayload);
}
Expand All @@ -129,10 +127,8 @@ abstract contract NestedMultisigBuilder is MultisigBase {
// signatures is empty, because `_executeTransaction` internally collects all of the approvedHash addresses
bytes memory signatures;

vm.startBroadcast();
(Vm.AccountAccess[] memory accesses, Simulation.Payload memory simPayload) =
_executeTransaction(_ownerSafe(), nestedCalls, signatures);
vm.stopBroadcast();
_executeTransaction(_ownerSafe(), nestedCalls, signatures, true);

_postRun(accesses, simPayload);
_postCheck(accesses, simPayload);
Expand Down
12 changes: 8 additions & 4 deletions script/universal/Simulation.sol
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,19 @@ library Simulation {
return accesses;
}

function overrideSafeThresholdAndNonce(address _safe, uint256 _nonce) public view returns (StateOverride memory) {
function overrideSafeThresholdAndNonce(address _safe, uint256 _nonce)
internal
view
returns (StateOverride memory)
{
StateOverride memory state = StateOverride({contractAddress: _safe, overrides: new StorageOverride[](0)});
state = addThresholdOverride(_safe, state);
state = addNonceOverride(_safe, state, _nonce);
return state;
}

function overrideSafeThresholdOwnerAndNonce(address _safe, address _owner, uint256 _nonce)
public
internal
view
returns (StateOverride memory)
{
Expand Down Expand Up @@ -133,12 +137,12 @@ library Simulation {
return StateOverride({contractAddress: _state.contractAddress, overrides: overrides});
}

function logSimulationLink(address _to, bytes memory _data, address _from) public view {
function logSimulationLink(address _to, bytes memory _data, address _from) internal view {
logSimulationLink(_to, _data, _from, new StateOverride[](0));
}

function logSimulationLink(address _to, bytes memory _data, address _from, StateOverride[] memory _overrides)
public
internal
view
{
string memory proj = vm.envOr("TENDERLY_PROJECT", string("TENDERLY_PROJECT"));
Expand Down

0 comments on commit c6a9989

Please sign in to comment.