{"compilation":{"language":"Solidity","compiler":"solc","compilerVersion":"0.4.16+commit.d7661dd9","compilerSettings":{"libraries":{},"optimizer":{"runs":200,"enabled":true},"remappings":[]},"name":"MultiSigWallet","fullyQualifiedName":"MultiSigWallet.sol:MultiSigWallet"},"sources":{"MultiSigWallet.sol":{"content":"/// @title Multisignature wallet - Allows multiple parties to agree on transactions before execution.\r\n/// @author Stefan George - <stefan.george@consensys.net>\r\ncontract MultiSigWallet {\r\n\r\n    uint constant public MAX_OWNER_COUNT = 50;\r\n\r\n    event Confirmation(address indexed sender, uint indexed transactionId);\r\n    event Revocation(address indexed sender, uint indexed transactionId);\r\n    event Submission(uint indexed transactionId);\r\n    event Execution(uint indexed transactionId);\r\n    event ExecutionFailure(uint indexed transactionId);\r\n    event Deposit(address indexed sender, uint value);\r\n    event OwnerAddition(address indexed owner);\r\n    event OwnerRemoval(address indexed owner);\r\n    event RequirementChange(uint required);\r\n\r\n    mapping (uint => Transaction) public transactions;\r\n    mapping (uint => mapping (address => bool)) public confirmations;\r\n    mapping (address => bool) public isOwner;\r\n    address[] public owners;\r\n    uint public required;\r\n    uint public transactionCount;\r\n\r\n    struct Transaction {\r\n        address destination;\r\n        uint value;\r\n        bytes data;\r\n        bool executed;\r\n    }\r\n\r\n    modifier onlyWallet() {\r\n        if (msg.sender != address(this))\r\n            throw;\r\n        _;\r\n    }\r\n\r\n    modifier ownerDoesNotExist(address owner) {\r\n        if (isOwner[owner])\r\n            throw;\r\n        _;\r\n    }\r\n\r\n    modifier ownerExists(address owner) {\r\n        if (!isOwner[owner])\r\n            throw;\r\n        _;\r\n    }\r\n\r\n    modifier transactionExists(uint transactionId) {\r\n        if (transactions[transactionId].destination == 0)\r\n            throw;\r\n        _;\r\n    }\r\n\r\n    modifier confirmed(uint transactionId, address owner) {\r\n        if (!confirmations[transactionId][owner])\r\n            throw;\r\n        _;\r\n    }\r\n\r\n    modifier notConfirmed(uint transactionId, address owner) {\r\n        if (confirmations[transactionId][owner])\r\n            throw;\r\n        _;\r\n    }\r\n\r\n    modifier notExecuted(uint transactionId) {\r\n        if (transactions[transactionId].executed)\r\n            throw;\r\n        _;\r\n    }\r\n\r\n    modifier notNull(address _address) {\r\n        if (_address == 0)\r\n            throw;\r\n        _;\r\n    }\r\n\r\n    modifier validRequirement(uint ownerCount, uint _required) {\r\n        if (   ownerCount > MAX_OWNER_COUNT\r\n            || _required > ownerCount\r\n            || _required == 0\r\n            || ownerCount == 0)\r\n            throw;\r\n        _;\r\n    }\r\n\r\n    /// @dev Fallback function allows to deposit ether.\r\n    function()\r\n        payable\r\n    {\r\n        if (msg.value > 0)\r\n            Deposit(msg.sender, msg.value);\r\n    }\r\n\r\n    /*\r\n     * Public functions\r\n     */\r\n    /// @dev Contract constructor sets initial owners and required number of confirmations.\r\n    /// @param _owners List of initial owners.\r\n    /// @param _required Number of required confirmations.\r\n    function MultiSigWallet(address[] _owners, uint _required)\r\n        public\r\n        validRequirement(_owners.length, _required)\r\n    {\r\n        for (uint i=0; i<_owners.length; i++) {\r\n            if (isOwner[_owners[i]] || _owners[i] == 0)\r\n                throw;\r\n            isOwner[_owners[i]] = true;\r\n        }\r\n        owners = _owners;\r\n        required = _required;\r\n    }\r\n\r\n    /// @dev Allows to add a new owner. Transaction has to be sent by wallet.\r\n    /// @param owner Address of new owner.\r\n    function addOwner(address owner)\r\n        public\r\n        onlyWallet\r\n        ownerDoesNotExist(owner)\r\n        notNull(owner)\r\n        validRequirement(owners.length + 1, required)\r\n    {\r\n        isOwner[owner] = true;\r\n        owners.push(owner);\r\n        OwnerAddition(owner);\r\n    }\r\n\r\n    /// @dev Allows to remove an owner. Transaction has to be sent by wallet.\r\n    /// @param owner Address of owner.\r\n    function removeOwner(address owner)\r\n        public\r\n        onlyWallet\r\n        ownerExists(owner)\r\n    {\r\n        isOwner[owner] = false;\r\n        for (uint i=0; i<owners.length - 1; i++)\r\n            if (owners[i] == owner) {\r\n                owners[i] = owners[owners.length - 1];\r\n                break;\r\n            }\r\n        owners.length -= 1;\r\n        if (required > owners.length)\r\n            changeRequirement(owners.length);\r\n        OwnerRemoval(owner);\r\n    }\r\n\r\n    /// @dev Allows to replace an owner with a new owner. Transaction has to be sent by wallet.\r\n    /// @param owner Address of owner to be replaced.\r\n    /// @param owner Address of new owner.\r\n    function replaceOwner(address owner, address newOwner)\r\n        public\r\n        onlyWallet\r\n        ownerExists(owner)\r\n        ownerDoesNotExist(newOwner)\r\n    {\r\n        for (uint i=0; i<owners.length; i++)\r\n            if (owners[i] == owner) {\r\n                owners[i] = newOwner;\r\n                break;\r\n            }\r\n        isOwner[owner] = false;\r\n        isOwner[newOwner] = true;\r\n        OwnerRemoval(owner);\r\n        OwnerAddition(newOwner);\r\n    }\r\n\r\n    /// @dev Allows to change the number of required confirmations. Transaction has to be sent by wallet.\r\n    /// @param _required Number of required confirmations.\r\n    function changeRequirement(uint _required)\r\n        public\r\n        onlyWallet\r\n        validRequirement(owners.length, _required)\r\n    {\r\n        required = _required;\r\n        RequirementChange(_required);\r\n    }\r\n\r\n    /// @dev Allows an owner to submit and confirm a transaction.\r\n    /// @param destination Transaction target address.\r\n    /// @param value Transaction ether value.\r\n    /// @param data Transaction data payload.\r\n    /// @return Returns transaction ID.\r\n    function submitTransaction(address destination, uint value, bytes data)\r\n        public\r\n        returns (uint transactionId)\r\n    {\r\n        transactionId = addTransaction(destination, value, data);\r\n        confirmTransaction(transactionId);\r\n    }\r\n\r\n    /// @dev Allows an owner to confirm a transaction.\r\n    /// @param transactionId Transaction ID.\r\n    function confirmTransaction(uint transactionId)\r\n        public\r\n        ownerExists(msg.sender)\r\n        transactionExists(transactionId)\r\n        notConfirmed(transactionId, msg.sender)\r\n    {\r\n        confirmations[transactionId][msg.sender] = true;\r\n        Confirmation(msg.sender, transactionId);\r\n        executeTransaction(transactionId);\r\n    }\r\n\r\n    /// @dev Allows an owner to revoke a confirmation for a transaction.\r\n    /// @param transactionId Transaction ID.\r\n    function revokeConfirmation(uint transactionId)\r\n        public\r\n        ownerExists(msg.sender)\r\n        confirmed(transactionId, msg.sender)\r\n        notExecuted(transactionId)\r\n    {\r\n        confirmations[transactionId][msg.sender] = false;\r\n        Revocation(msg.sender, transactionId);\r\n    }\r\n\r\n    /// @dev Allows anyone to execute a confirmed transaction.\r\n    /// @param transactionId Transaction ID.\r\n    function executeTransaction(uint transactionId)\r\n        public\r\n        notExecuted(transactionId)\r\n    {\r\n        if (isConfirmed(transactionId)) {\r\n            Transaction tx = transactions[transactionId];\r\n            tx.executed = true;\r\n            if (tx.destination.call.value(tx.value)(tx.data))\r\n                Execution(transactionId);\r\n            else {\r\n                ExecutionFailure(transactionId);\r\n                tx.executed = false;\r\n            }\r\n        }\r\n    }\r\n\r\n    /// @dev Returns the confirmation status of a transaction.\r\n    /// @param transactionId Transaction ID.\r\n    /// @return Confirmation status.\r\n    function isConfirmed(uint transactionId)\r\n        public\r\n        constant\r\n        returns (bool)\r\n    {\r\n        uint count = 0;\r\n        for (uint i=0; i<owners.length; i++) {\r\n            if (confirmations[transactionId][owners[i]])\r\n                count += 1;\r\n            if (count == required)\r\n                return true;\r\n        }\r\n    }\r\n\r\n    /*\r\n     * Internal functions\r\n     */\r\n    /// @dev Adds a new transaction to the transaction mapping, if transaction does not exist yet.\r\n    /// @param destination Transaction target address.\r\n    /// @param value Transaction ether value.\r\n    /// @param data Transaction data payload.\r\n    /// @return Returns transaction ID.\r\n    function addTransaction(address destination, uint value, bytes data)\r\n        internal\r\n        notNull(destination)\r\n        returns (uint transactionId)\r\n    {\r\n        transactionId = transactionCount;\r\n        transactions[transactionId] = Transaction({\r\n            destination: destination,\r\n            value: value,\r\n            data: data,\r\n            executed: false\r\n        });\r\n        transactionCount += 1;\r\n        Submission(transactionId);\r\n    }\r\n\r\n    /*\r\n     * Web3 call functions\r\n     */\r\n    /// @dev Returns number of confirmations of a transaction.\r\n    /// @param transactionId Transaction ID.\r\n    /// @return Number of confirmations.\r\n    function getConfirmationCount(uint transactionId)\r\n        public\r\n        constant\r\n        returns (uint count)\r\n    {\r\n        for (uint i=0; i<owners.length; i++)\r\n            if (confirmations[transactionId][owners[i]])\r\n                count += 1;\r\n    }\r\n\r\n    /// @dev Returns total number of transactions after filers are applied.\r\n    /// @param pending Include pending transactions.\r\n    /// @param executed Include executed transactions.\r\n    /// @return Total number of transactions after filters are applied.\r\n    function getTransactionCount(bool pending, bool executed)\r\n        public\r\n        constant\r\n        returns (uint count)\r\n    {\r\n        for (uint i=0; i<transactionCount; i++)\r\n            if (   pending && !transactions[i].executed\r\n                || executed && transactions[i].executed)\r\n                count += 1;\r\n    }\r\n\r\n    /// @dev Returns list of owners.\r\n    /// @return List of owner addresses.\r\n    function getOwners()\r\n        public\r\n        constant\r\n        returns (address[])\r\n    {\r\n        return owners;\r\n    }\r\n\r\n    /// @dev Returns array with owner addresses, which confirmed transaction.\r\n    /// @param transactionId Transaction ID.\r\n    /// @return Returns array of owner addresses.\r\n    function getConfirmations(uint transactionId)\r\n        public\r\n        constant\r\n        returns (address[] _confirmations)\r\n    {\r\n        address[] memory confirmationsTemp = new address[](owners.length);\r\n        uint count = 0;\r\n        uint i;\r\n        for (i=0; i<owners.length; i++)\r\n            if (confirmations[transactionId][owners[i]]) {\r\n                confirmationsTemp[count] = owners[i];\r\n                count += 1;\r\n            }\r\n        _confirmations = new address[](count);\r\n        for (i=0; i<count; i++)\r\n            _confirmations[i] = confirmationsTemp[i];\r\n    }\r\n\r\n    /// @dev Returns list of transaction IDs in defined range.\r\n    /// @param from Index start position of transaction array.\r\n    /// @param to Index end position of transaction array.\r\n    /// @param pending Include pending transactions.\r\n    /// @param executed Include executed transactions.\r\n    /// @return Returns array of transaction IDs.\r\n    function getTransactionIds(uint from, uint to, bool pending, bool executed)\r\n        public\r\n        constant\r\n        returns (uint[] _transactionIds)\r\n    {\r\n        uint[] memory transactionIdsTemp = new uint[](transactionCount);\r\n        uint count = 0;\r\n        uint i;\r\n        for (i=0; i<transactionCount; i++)\r\n            if (   pending && !transactions[i].executed\r\n                || executed && transactions[i].executed)\r\n            {\r\n                transactionIdsTemp[count] = i;\r\n                count += 1;\r\n            }\r\n        _transactionIds = new uint[](to - from);\r\n        for (i=from; i<to; i++)\r\n            _transactionIds[i - from] = transactionIdsTemp[i];\r\n    }\r\n}"}},"proxyResolution":{"isProxy":false,"proxyType":null,"implementations":[]},"matchId":"1617378","creationMatch":"match","runtimeMatch":"match","verifiedAt":"2024-08-08T13:30:01Z","match":"match","chainId":"1","address":"0xC6CDE7C39eB2f0F0095F41570af89eFC2C1Ea828"}