Skip to content

Instantly share code, notes, and snippets.

@saaqibz
Created April 24, 2021 22:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save saaqibz/a5f59bc39747e995ca39cf622d9d4e1a to your computer and use it in GitHub Desktop.
Save saaqibz/a5f59bc39747e995ca39cf622d9d4e1a to your computer and use it in GitHub Desktop.
Multisig wallet contract written in solidity
pragma solidity ^0.6.0;
contract Multisig {
address public owner;
mapping(address=>bool) public signers;
uint public numSigners;
Request[] public pending;
struct Request {
address to;
uint amt;
uint numSigners;
mapping(address => bool) signers;
}
constructor() public {
owner = msg.sender;
signers[owner] = true;
++numSigners;
}
function addSigner(address addr) external IsSigner() {
require (!signers[addr], 'signer exists');
signers[addr] = true;
++numSigners;
}
function removeSigner(address addr) external IsSigner() {
require(addr != owner, 'Owner cannot be removed');
require (signers[addr], 'no signer to remove');
delete signers[addr];
--numSigners;
}
function sign(address to, uint amt) external IsSigner() {
(uint requestIndex, bool ok) = findRequest(to, amt);
if (!ok) {
requestIndex = pending.length;
Request memory newReq = Request({
to: to,
amt: amt,
numSigners: 0
});
pending.push(newReq);
}
Request storage request = pending[requestIndex];
require (!request.signers[msg.sender], 'already signed');
request.numSigners++;
request.signers[msg.sender] = true;
}
function transfer(address payable to, uint amt) external IsSigner {
(uint requestIndex, bool ok) = findRequest(to, amt);
require(ok, 'request not found');
Request memory request = pending[requestIndex];
require(request.numSigners > 3, "need more signers");
to.transfer(amt);
}
function findRequest(address to, uint amt) internal view returns (uint requestIndex, bool) {
for (uint i=0; i < pending.length; ++i) {
Request memory req = pending[i];
if (req.to == to && req.amt == amt) {
return (i, true);
}
}
return (0, false);
}
modifier IsSigner() {
require(signers[msg.sender], 'Only existing signers can add a signer');
_;
}
function balance() external view returns (uint) {
return address(this).balance;
}
receive() external payable {}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment