aboutsummaryrefslogtreecommitdiffstats
path: root/packages/contracts/src/2.0.0/multisig/MultiSigWallet.sol
diff options
context:
space:
mode:
authorAmir Bandeali <abandeali1@gmail.com>2018-09-01 06:20:58 +0800
committerAmir Bandeali <abandeali1@gmail.com>2018-09-04 22:57:47 +0800
commitada5563b1fd2024ef310786eb8b1f32f3ecee4f0 (patch)
tree664cacf59d65fc4c9b130a405a8c5d275dbd43d7 /packages/contracts/src/2.0.0/multisig/MultiSigWallet.sol
parent78d4fc59a5ea5e2c3da9c221967dc792445419ae (diff)
downloaddexon-0x-contracts-ada5563b1fd2024ef310786eb8b1f32f3ecee4f0.tar
dexon-0x-contracts-ada5563b1fd2024ef310786eb8b1f32f3ecee4f0.tar.gz
dexon-0x-contracts-ada5563b1fd2024ef310786eb8b1f32f3ecee4f0.tar.bz2
dexon-0x-contracts-ada5563b1fd2024ef310786eb8b1f32f3ecee4f0.tar.lz
dexon-0x-contracts-ada5563b1fd2024ef310786eb8b1f32f3ecee4f0.tar.xz
dexon-0x-contracts-ada5563b1fd2024ef310786eb8b1f32f3ecee4f0.tar.zst
dexon-0x-contracts-ada5563b1fd2024ef310786eb8b1f32f3ecee4f0.zip
Update to most recent multisig
Diffstat (limited to 'packages/contracts/src/2.0.0/multisig/MultiSigWallet.sol')
-rw-r--r--packages/contracts/src/2.0.0/multisig/MultiSigWallet.sol90
1 files changed, 58 insertions, 32 deletions
diff --git a/packages/contracts/src/2.0.0/multisig/MultiSigWallet.sol b/packages/contracts/src/2.0.0/multisig/MultiSigWallet.sol
index eb54fe047..516e7391c 100644
--- a/packages/contracts/src/2.0.0/multisig/MultiSigWallet.sol
+++ b/packages/contracts/src/2.0.0/multisig/MultiSigWallet.sol
@@ -1,13 +1,14 @@
// solhint-disable
-pragma solidity ^0.4.10;
+pragma solidity ^0.4.15;
/// @title Multisignature wallet - Allows multiple parties to agree on transactions before execution.
/// @author Stefan George - <stefan.george@consensys.net>
contract MultiSigWallet {
- uint constant public MAX_OWNER_COUNT = 50;
-
+ /*
+ * Events
+ */
event Confirmation(address indexed sender, uint indexed transactionId);
event Revocation(address indexed sender, uint indexed transactionId);
event Submission(uint indexed transactionId);
@@ -18,6 +19,14 @@ contract MultiSigWallet {
event OwnerRemoval(address indexed owner);
event RequirementChange(uint required);
+ /*
+ * Constants
+ */
+ uint constant public MAX_OWNER_COUNT = 50;
+
+ /*
+ * Storage
+ */
mapping (uint => Transaction) public transactions;
mapping (uint => mapping (address => bool)) public confirmations;
mapping (address => bool) public isOwner;
@@ -32,60 +41,54 @@ contract MultiSigWallet {
bool executed;
}
+ /*
+ * Modifiers
+ */
modifier onlyWallet() {
- if (msg.sender != address(this))
- throw;
+ require(msg.sender == address(this));
_;
}
modifier ownerDoesNotExist(address owner) {
- if (isOwner[owner])
- throw;
+ require(!isOwner[owner]);
_;
}
modifier ownerExists(address owner) {
- if (!isOwner[owner])
- throw;
+ require(isOwner[owner]);
_;
}
modifier transactionExists(uint transactionId) {
- if (transactions[transactionId].destination == 0)
- throw;
+ require(transactions[transactionId].destination != 0);
_;
}
modifier confirmed(uint transactionId, address owner) {
- if (!confirmations[transactionId][owner])
- throw;
+ require(confirmations[transactionId][owner]);
_;
}
modifier notConfirmed(uint transactionId, address owner) {
- if (confirmations[transactionId][owner])
- throw;
+ require(!confirmations[transactionId][owner]);
_;
}
modifier notExecuted(uint transactionId) {
- if (transactions[transactionId].executed)
- throw;
+ require(!transactions[transactionId].executed);
_;
}
modifier notNull(address _address) {
- if (_address == 0)
- throw;
+ require(_address != 0);
_;
}
modifier validRequirement(uint ownerCount, uint _required) {
- if ( ownerCount > MAX_OWNER_COUNT
- || _required > ownerCount
- || _required == 0
- || ownerCount == 0)
- throw;
+ require(ownerCount <= MAX_OWNER_COUNT
+ && _required <= ownerCount
+ && _required != 0
+ && ownerCount != 0);
_;
}
@@ -108,8 +111,7 @@ contract MultiSigWallet {
validRequirement(_owners.length, _required)
{
for (uint i=0; i<_owners.length; i++) {
- if (isOwner[_owners[i]] || _owners[i] == 0)
- throw;
+ require(!isOwner[_owners[i]] && _owners[i] != 0);
isOwner[_owners[i]] = true;
}
owners = _owners;
@@ -151,7 +153,7 @@ contract MultiSigWallet {
/// @dev Allows to replace an owner with a new owner. Transaction has to be sent by wallet.
/// @param owner Address of owner to be replaced.
- /// @param owner Address of new owner.
+ /// @param newOwner Address of new owner.
function replaceOwner(address owner, address newOwner)
public
onlyWallet
@@ -222,20 +224,44 @@ contract MultiSigWallet {
/// @param transactionId Transaction ID.
function executeTransaction(uint transactionId)
public
+ ownerExists(msg.sender)
+ confirmed(transactionId, msg.sender)
notExecuted(transactionId)
{
if (isConfirmed(transactionId)) {
- Transaction tx = transactions[transactionId];
- tx.executed = true;
- if (tx.destination.call.value(tx.value)(tx.data))
+ Transaction storage txn = transactions[transactionId];
+ txn.executed = true;
+ if (external_call(txn.destination, txn.value, txn.data.length, txn.data))
Execution(transactionId);
else {
ExecutionFailure(transactionId);
- tx.executed = false;
+ txn.executed = false;
}
}
}
+ // call has been separated into its own function in order to take advantage
+ // of the Solidity's code generator to produce a loop that copies tx.data into memory.
+ function external_call(address destination, uint value, uint dataLength, bytes data) internal returns (bool) {
+ bool result;
+ assembly {
+ let x := mload(0x40) // "Allocate" memory for output (0x40 is where "free memory" pointer is stored by convention)
+ let d := add(data, 32) // First 32 bytes are the padded length of data, so exclude that
+ result := call(
+ sub(gas, 34710), // 34710 is the value that solidity is currently emitting
+ // It includes callGas (700) + callVeryLow (3, to pay for SUB) + callValueTransferGas (9000) +
+ // callNewAccountGas (25000, in case the destination address does not exist and needs creating)
+ destination,
+ value,
+ d,
+ dataLength, // Size of the input (in bytes) - this is what fixes the padding problem
+ x,
+ 0 // Output is ignored, therefore the output size is zero
+ )
+ }
+ return result;
+ }
+
/// @dev Returns the confirmation status of a transaction.
/// @param transactionId Transaction ID.
/// @return Confirmation status.
@@ -364,4 +390,4 @@ contract MultiSigWallet {
for (i=from; i<to; i++)
_transactionIds[i - from] = transactionIdsTemp[i];
}
-}
+} \ No newline at end of file