Created
April 24, 2021 22:37
-
-
Save saaqibz/a5f59bc39747e995ca39cf622d9d4e1a to your computer and use it in GitHub Desktop.
Multisig wallet contract written in solidity
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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