26516 - [SC - Insight] Gnosis Multisig Contract can become unusable
Previous26509 - [SC - Insight] Exodus Mode ForceNext26519 - [SC - Insight] Consider introducing the ability to change requ...
Last updated
Was this helpful?
Last updated
Was this helpful?
Was this helpful?
const {ethers} = require("hardhat")
const {expect, assert} = require("chai")
var gnosis
let owners, deployer
describe("ReplaceOwner bug", function()
{
before(async function(){
owners = (await ethers.getSigners()).slice(0,6)
deployer = owners[0]
})
context("Setup Contract (4/6 multisig) ", () => {
it("Should deploy with 6 owners, 4 required ", async function(){
let gnosisF = await ethers.getContractFactory("MultiSigWallet", deployer)
gnosis = await gnosisF.deploy(
owners,
4
);
expect(await gnosis.required()).to.eq(4);
expect( (await gnosis.getOwners() ).length).to.eq(6);
})
})
context("Bug proof of concept", () => {
it("Should remove two owners", async function(){
let ABI = [
"function transfer(address to, uint amount)",
"function removeOwner(address owner)"
];
let iface = new ethers.Interface(ABI);
data = iface.encodeFunctionData("removeOwner", [ owners[owners.length - 1].address, ] )
//one owner proposes an action through submitTransaction and the others
//adhere through confirmTransaction
// remove one owner [CODE START]
await gnosis.submitTransaction(
await gnosis.getAddress(), //destination
0, //value
data //data
)
for( i=1; i<=3; i++)
{
signer = owners[i];
await gnosis.connect(signer).confirmTransaction(
0 //transaction id
);
}
expect((await gnosis.getOwners()).length).to.eq(5)
// remove one owner [CODE END]
// remove another owner [CODE START]
data = iface.encodeFunctionData("removeOwner", [ owners[owners.length - 2].address, ] )
await gnosis.submitTransaction(
await gnosis.getAddress(), //destination
0, //value
data //data
)
for( i=1; i<=3; i++)
{
signer = owners[i];
await gnosis.connect(signer).confirmTransaction(
1 //transaction id
);
}
expect((await gnosis.getOwners()).length).to.eq(4)
// remove another owner [CODE END]
})
it("Should replace an Owner with zero address", async function(){
let ABI = [
"function transfer(address to, uint amount)",
"function replaceOwner(address owner, address newOwner)"
];
let iface = new ethers.Interface(ABI);
data = iface.encodeFunctionData("replaceOwner", [ owners[2].address, '0x0000000000000000000000000000000000000000'] )
await gnosis.submitTransaction(
await gnosis.getAddress(), //destination
0, //value
data //data
)
for( i=1; i<=3; i++)
{
signer = owners[i];
await gnosis.connect(signer).confirmTransaction(
2 //transaction id
);
}
expect(await gnosis.required()).to.eq(4);
expect((await gnosis.getOwners()).length).to.eq(4);
console.log("Owners are ", await gnosis.getOwners() );
console.log("Required amount of signatures are ", await gnosis.required() );
})
})
})