Code coverage for Solidity smart-contracts
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
solidity-coverage/test/sources/zeppelin/MultisigWallet.sol

102 lines
2.9 KiB

pragma solidity ^0.4.4;
import "./Multisig.sol";
import "./Shareable.sol";
import "./DayLimit.sol";
/*
* MultisigWallet
* usage:
* bytes32 h = Wallet(w).from(oneOwner).execute(to, value, data);
* Wallet(w).from(anotherOwner).confirm(h);
*/
contract MultisigWallet is Multisig, Shareable, DayLimit {
// TYPES
// Transaction structure to remember details of transaction lest it need be saved for a later call.
struct Transaction {
address to;
uint value;
bytes data;
}
// CONSTRUCTOR
// just pass on the owner array to the multiowned and
// the limit to daylimit
function MultisigWallet(address[] _owners, uint _required, uint _daylimit)
Shareable(_owners, _required)
DayLimit(_daylimit) { }
// METHODS
// kills the contract sending everything to `_to`.
function kill(address _to) onlymanyowners(sha3(msg.data)) external {
suicide(_to);
}
// gets called when no other function matches
function() payable {
// just being sent some cash?
if (msg.value > 0)
Deposit(msg.sender, msg.value);
}
// Outside-visible transact entry point. Executes transaction immediately if below daily spend limit.
// If not, goes into multisig process. We provide a hash on return to allow the sender to provide
// shortcuts for the other confirmations (allowing them to avoid replicating the _to, _value
// and _data arguments). They still get the option of using them if they want, anyways.
function execute(address _to, uint _value, bytes _data) external onlyOwner returns (bytes32 _r) {
// first, take the opportunity to check that we're under the daily limit.
if (underLimit(_value)) {
SingleTransact(msg.sender, _value, _to, _data);
// yes - just execute the call.
if (!_to.call.value(_value)(_data)) {
throw;
}
return 0;
}
// determine our operation hash.
_r = sha3(msg.data, block.number);
if (!confirm(_r) && txs[_r].to == 0) {
txs[_r].to = _to;
txs[_r].value = _value;
txs[_r].data = _data;
ConfirmationNeeded(_r, msg.sender, _value, _to, _data);
}
}
// confirm a transaction through just the hash. we use the previous transactions map, txs, in order
// to determine the body of the transaction from the hash provided.
function confirm(bytes32 _h) onlymanyowners(_h) returns (bool) {
if (txs[_h].to != 0) {
if (!txs[_h].to.call.value(txs[_h].value)(txs[_h].data)) {
throw;
}
MultiTransact(msg.sender, _h, txs[_h].value, txs[_h].to, txs[_h].data);
delete txs[_h];
return true;
}
}
// INTERNAL METHODS
function clearPending() internal {
uint length = pendingsIndex.length;
for (uint i = 0; i < length; ++i) {
delete txs[pendingsIndex[i]];
}
super.clearPending();
}
// FIELDS
// pending transactions we have at present.
mapping (bytes32 => Transaction) txs;
}