Skip to content

Commit

Permalink
Add test for metatransaction/multicall vulnerability
Browse files Browse the repository at this point in the history
  • Loading branch information
area committed Sep 23, 2024
1 parent c7b3ee9 commit 2d05b41
Showing 1 changed file with 24 additions and 0 deletions.
24 changes: 24 additions & 0 deletions test/contracts-network/colony.js
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,30 @@ contract("Colony", (accounts) => {

await checkErrorRevert(colony.executeMetaTransaction(USER1, txData, r, s, v, { from: USER1 }), "metatransaction-signer-signature-mismatch");
});

it("not vulnerable to metatransactions / multicall vulnerability", async () => {
// https://blog.solidityscan.com/unveiling-the-erc-2771context-and-multicall-vulnerability-f96ffa5b499f
// Create an expenditure as a user
await colony.makeExpenditure(1, UINT256_MAX, 1);

// Should not be able to multicall and cancel it as another user, pretending to be the first user
const expenditureId = await colony.getExpenditureCount();
let txData1 = await colony.contract.methods.cancelExpenditure(expenditureId).encodeABI();

const METATRANSACTION_FLAG = ethers.utils.id("METATRANSACTION");

txData1 += METATRANSACTION_FLAG.slice(2) + USER0.slice(2);

const txData2 = await colony.contract.methods.multicall([txData1]).encodeABI();

const { r, s, v } = await getMetaTransactionParameters(txData2, USER1, colony.address);

// User 1 can't cancel the expenditure directly
await checkErrorRevert(colony.cancelExpenditure(expenditureId, { from: USER1 }), "colony-expenditure-not-owner");

// And can't via metatransaction using specially constructed malicious txdata
await checkErrorRevert(colony.executeMetaTransaction(USER1, txData2, r, s, v, { from: USER1 }), "colony-metatx-function-call-unsuccessful");
});
});

describe("when executing a multicall transaction", () => {
Expand Down

0 comments on commit 2d05b41

Please sign in to comment.