Skip to content

Instantly share code, notes, and snippets.

@Arachnid

Arachnid/DumbMultisig.sol

Last active Sep 17, 2018
Embed
What would you like to do?
// WHATEVER YOU DO, DON'T USE THIS.
// This is a bit of demo code posted to illustrate a principle. It is unaudited,
// probably full of bugs, and definintely not production ready.
// https://twitter.com/nicksdjohnson/status/1041642345467404291
import "./DumbWallet.sol";
contract DumbMultisig {
struct MultisigConfig {
mapping(address=>bool) signatories;
uint threshold;
uint nonce;
}
mapping(address=>MultisigConfig) configs;
event SignatoryChange(address indexed wallet, address indexed signatory, bool value);
event ThresholdChange(address indexed wallet, uint threshold);
modifier authorisedOnly(DumbWallet wallet) {
require(wallet.authorised(msg.sender));
_;
}
function invoke(DumbWallet wallet, address target, uint value, bytes data, bytes32[] r, bytes32[] s, uint8[] v) payable {
MultisigConfig storage config = configs[wallet];
require(config.threshold > 0);
require(r.length == s.length);
require(r.length == v.length);
require(r.length >= config.threshold);
address previousSigner = 0;
bytes32 messageHash = keccak256(abi.encodePacked(wallet, target, value, data, config.nonce));
for(uint i = 0; i < r.length; i++) {
address signer = ecrecover(messageHash, v[i], r[i], s[i]);
require(signer > previousSigner);
previousSigner = signer;
require(config.signatories[signer]);
}
wallet.invoke.value(msg.value)(target, value, data);
config.nonce++;
}
function setSignatory(DumbWallet wallet, address signatory, bool value) authorisedOnly(wallet) {
configs[wallet].signatories[signatory] = value;
SignatoryChange(wallet, signatory, value);
}
function setThreshold(DumbWallet wallet, uint threshold) authorisedOnly(wallet) {
configs[wallet].threshold = threshold;
ThresholdChange(wallet, threshold);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.