mirror of https://github.com/ConsenSys/mythril
blockchainethereumsmart-contractssoliditysecurityprogram-analysissecurity-analysissymbolic-execution
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.
89 lines
1.9 KiB
89 lines
1.9 KiB
11 months ago
|
|
||
|
pragma solidity 0.5.0;
|
||
|
|
||
|
contract WalletLibrary {
|
||
|
|
||
|
struct PendingState {
|
||
|
uint yetNeeded;
|
||
|
uint ownersDone;
|
||
|
uint index;
|
||
|
}
|
||
|
|
||
|
struct Transaction {
|
||
|
address to;
|
||
|
uint value;
|
||
|
bytes data;
|
||
|
}
|
||
|
|
||
|
modifier onlymanyowners(bytes32 _operation) {
|
||
|
if (confirmAndCheck(_operation))
|
||
|
_;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
function initMultiowned(address[] memory _owners, uint _required) public only_uninitialized {
|
||
|
m_numOwners = _owners.length + 1;
|
||
|
m_owners[1] = uint(msg.sender);
|
||
|
m_ownerIndex[uint(msg.sender)] = 1;
|
||
|
for (uint i = 0; i < _owners.length; ++i)
|
||
|
{
|
||
|
m_owners[2 + i] = uint(_owners[i]);
|
||
|
m_ownerIndex[uint(_owners[i])] = 2 + i;
|
||
|
}
|
||
|
m_required = _required;
|
||
|
}
|
||
|
|
||
|
modifier only_uninitialized { require(m_numOwners == 0); _; }
|
||
|
|
||
|
|
||
|
function kill(address payable _to) onlymanyowners(keccak256(msg.data)) external {
|
||
|
selfdestruct(_to);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
function confirmAndCheck(bytes32 _operation) internal returns (bool) {
|
||
|
uint ownerIndex = m_ownerIndex[uint(msg.sender)];
|
||
|
if (ownerIndex == 0) return false;
|
||
|
|
||
|
PendingState memory pending = m_pending[_operation];
|
||
|
if (pending.yetNeeded == 0) {
|
||
|
pending.yetNeeded = m_required;
|
||
|
pending.ownersDone = 0;
|
||
|
pending.index = m_pendingIndex.length++;
|
||
|
m_pendingIndex[pending.index] = _operation;
|
||
|
}
|
||
|
uint ownerIndexBit = 2**ownerIndex;
|
||
|
if (pending.ownersDone & ownerIndexBit == 0) {
|
||
|
if (pending.yetNeeded <= 1) {
|
||
|
delete m_pendingIndex[m_pending[_operation].index];
|
||
|
delete m_pending[_operation];
|
||
|
return true;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// not enough: record that this owner in particular confirmed.
|
||
|
pending.yetNeeded--;
|
||
|
pending.ownersDone |= ownerIndexBit;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
uint public m_required;
|
||
|
uint public m_numOwners;
|
||
|
|
||
|
|
||
|
// list of owners
|
||
|
uint[256] m_owners;
|
||
|
|
||
|
mapping(uint => uint) m_ownerIndex;
|
||
|
mapping(bytes32 => PendingState) m_pending;
|
||
|
bytes32[] m_pendingIndex;
|
||
|
|
||
|
}
|