Skip to content

Commit ba5324e

Browse files
authored
Merge pull request #700 from safe-global/feat/multisend-self-tests
Add test for forwarding calls to self for `MultiSend` and `MultiSendCallOnly`
2 parents 5aad84f + 33eb51f commit ba5324e

File tree

2 files changed

+84
-2
lines changed

2 files changed

+84
-2
lines changed

test/libraries/MultiSend.spec.ts

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
import { expect } from "chai";
22
import hre, { deployments, ethers } from "hardhat";
33
import { deployContract, getMock, getMultiSend, getSafeWithOwners, getDelegateCaller } from "../utils/setup";
4-
import { buildContractCall, buildSafeTransaction, executeTx, MetaTransaction, safeApproveHash } from "../../src/utils/execution";
4+
import {
5+
buildContractCall,
6+
buildSafeTransaction,
7+
executeTx,
8+
executeTxWithSigners,
9+
MetaTransaction,
10+
safeApproveHash,
11+
} from "../../src/utils/execution";
512
import { buildMultiSendSafeTx, encodeMultiSend } from "../../src/utils/multisend";
613

714
describe("MultiSend", () => {
@@ -281,5 +288,39 @@ describe("MultiSend", () => {
281288

282289
await expect(delegateCaller.makeDelegatecall.staticCall(multiSendAddress, data)).to.be.revertedWith(errorMessage);
283290
});
291+
292+
it("forwards the call to self when to is zero address", async () => {
293+
const {
294+
safe,
295+
multiSend,
296+
signers: [user1],
297+
} = await setupTests();
298+
const randomAddress1 = ethers.hexlify(ethers.randomBytes(20));
299+
const randomAddress2 = ethers.hexlify(ethers.randomBytes(20));
300+
301+
await expect(await safe.isOwner(randomAddress1)).to.be.false;
302+
await expect(await safe.isOwner(randomAddress2)).to.be.false;
303+
304+
const txs: MetaTransaction[] = [
305+
{
306+
to: ethers.ZeroAddress,
307+
value: 0,
308+
data: safe.interface.encodeFunctionData("addOwnerWithThreshold", [randomAddress1, 1]),
309+
operation: 0,
310+
},
311+
{
312+
to: ethers.ZeroAddress,
313+
value: 0,
314+
data: safe.interface.encodeFunctionData("addOwnerWithThreshold", [randomAddress2, 1]),
315+
operation: 0,
316+
},
317+
];
318+
const safeTx = await buildMultiSendSafeTx(multiSend, txs, await safe.nonce());
319+
320+
await executeTxWithSigners(safe, safeTx, [user1]);
321+
322+
await expect(await safe.isOwner(randomAddress1)).to.be.true;
323+
await expect(await safe.isOwner(randomAddress2)).to.be.true;
324+
});
284325
});
285326
});

test/libraries/MultiSendCallOnly.spec.ts

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
import { expect } from "chai";
22
import hre, { deployments, ethers } from "hardhat";
33
import { deployContract, getMock, getMultiSendCallOnly, getSafeWithOwners, getDelegateCaller } from "../utils/setup";
4-
import { buildContractCall, buildSafeTransaction, executeTx, MetaTransaction, safeApproveHash } from "../../src/utils/execution";
4+
import {
5+
buildContractCall,
6+
buildSafeTransaction,
7+
executeTx,
8+
executeTxWithSigners,
9+
MetaTransaction,
10+
safeApproveHash,
11+
} from "../../src/utils/execution";
512
import { buildMultiSendSafeTx } from "../../src/utils/multisend";
613

714
describe("MultiSendCallOnly", () => {
@@ -211,5 +218,39 @@ describe("MultiSendCallOnly", () => {
211218

212219
await expect(delegateCaller.makeDelegatecall.staticCall(multisendAddress, data)).to.be.revertedWith(errorMessage);
213220
});
221+
222+
it("forwards the call to self when to is zero address", async () => {
223+
const {
224+
safe,
225+
multiSend,
226+
signers: [user1],
227+
} = await setupTests();
228+
const randomAddress1 = ethers.hexlify(ethers.randomBytes(20));
229+
const randomAddress2 = ethers.hexlify(ethers.randomBytes(20));
230+
231+
await expect(await safe.isOwner(randomAddress1)).to.be.false;
232+
await expect(await safe.isOwner(randomAddress2)).to.be.false;
233+
234+
const txs: MetaTransaction[] = [
235+
{
236+
to: ethers.ZeroAddress,
237+
value: 0,
238+
data: safe.interface.encodeFunctionData("addOwnerWithThreshold", [randomAddress1, 1]),
239+
operation: 0,
240+
},
241+
{
242+
to: ethers.ZeroAddress,
243+
value: 0,
244+
data: safe.interface.encodeFunctionData("addOwnerWithThreshold", [randomAddress2, 1]),
245+
operation: 0,
246+
},
247+
];
248+
const safeTx = await buildMultiSendSafeTx(multiSend, txs, await safe.nonce());
249+
250+
await executeTxWithSigners(safe, safeTx, [user1]);
251+
252+
await expect(await safe.isOwner(randomAddress1)).to.be.true;
253+
await expect(await safe.isOwner(randomAddress2)).to.be.true;
254+
});
214255
});
215256
});

0 commit comments

Comments
 (0)