Fix base multisig style

This commit is contained in:
Amir Bandeali
2019-09-17 14:19:57 -07:00
parent 6fd55b2f49
commit 0d259d13b9

View File

@@ -9,34 +9,34 @@ contract MultiSigWallet {
/* /*
* Events * Events
*/ */
event Confirmation(address indexed sender, uint indexed transactionId); event Confirmation(address indexed sender, uint256 indexed transactionId);
event Revocation(address indexed sender, uint indexed transactionId); event Revocation(address indexed sender, uint256 indexed transactionId);
event Submission(uint indexed transactionId); event Submission(uint256 indexed transactionId);
event Execution(uint indexed transactionId); event Execution(uint256 indexed transactionId);
event ExecutionFailure(uint indexed transactionId); event ExecutionFailure(uint256 indexed transactionId);
event Deposit(address indexed sender, uint value); event Deposit(address indexed sender, uint256 value);
event OwnerAddition(address indexed owner); event OwnerAddition(address indexed owner);
event OwnerRemoval(address indexed owner); event OwnerRemoval(address indexed owner);
event RequirementChange(uint required); event RequirementChange(uint256 required);
/* /*
* Constants * Constants
*/ */
uint constant public MAX_OWNER_COUNT = 50; uint256 constant public MAX_OWNER_COUNT = 50;
/* /*
* Storage * Storage
*/ */
mapping (uint => Transaction) public transactions; mapping (uint256 => Transaction) public transactions;
mapping (uint => mapping (address => bool)) public confirmations; mapping (uint256 => mapping (address => bool)) public confirmations;
mapping (address => bool) public isOwner; mapping (address => bool) public isOwner;
address[] public owners; address[] public owners;
uint public required; uint256 public required;
uint public transactionCount; uint256 public transactionCount;
struct Transaction { struct Transaction {
address destination; address destination;
uint value; uint256 value;
bytes data; bytes data;
bool executed; bool executed;
} }
@@ -68,7 +68,7 @@ contract MultiSigWallet {
_; _;
} }
modifier transactionExists(uint transactionId) { modifier transactionExists(uint256 transactionId) {
require( require(
transactions[transactionId].destination != address(0), transactions[transactionId].destination != address(0),
"TX_DOESNT_EXIST" "TX_DOESNT_EXIST"
@@ -76,7 +76,7 @@ contract MultiSigWallet {
_; _;
} }
modifier confirmed(uint transactionId, address owner) { modifier confirmed(uint256 transactionId, address owner) {
require( require(
confirmations[transactionId][owner], confirmations[transactionId][owner],
"TX_NOT_CONFIRMED" "TX_NOT_CONFIRMED"
@@ -84,7 +84,7 @@ contract MultiSigWallet {
_; _;
} }
modifier notConfirmed(uint transactionId, address owner) { modifier notConfirmed(uint256 transactionId, address owner) {
require( require(
!confirmations[transactionId][owner], !confirmations[transactionId][owner],
"TX_ALREADY_CONFIRMED" "TX_ALREADY_CONFIRMED"
@@ -92,7 +92,7 @@ contract MultiSigWallet {
_; _;
} }
modifier notExecuted(uint transactionId) { modifier notExecuted(uint256 transactionId) {
require( require(
!transactions[transactionId].executed, !transactions[transactionId].executed,
"TX_ALREADY_EXECUTED" "TX_ALREADY_EXECUTED"
@@ -108,7 +108,7 @@ contract MultiSigWallet {
_; _;
} }
modifier validRequirement(uint ownerCount, uint _required) { modifier validRequirement(uint256 ownerCount, uint256 _required) {
require( require(
ownerCount <= MAX_OWNER_COUNT ownerCount <= MAX_OWNER_COUNT
&& _required <= ownerCount && _required <= ownerCount
@@ -124,8 +124,9 @@ contract MultiSigWallet {
external external
payable payable
{ {
if (msg.value > 0) if (msg.value > 0) {
emit Deposit(msg.sender, msg.value); emit Deposit(msg.sender, msg.value);
}
} }
/* /*
@@ -136,13 +137,16 @@ contract MultiSigWallet {
/// @param _required Number of required confirmations. /// @param _required Number of required confirmations.
constructor( constructor(
address[] memory _owners, address[] memory _owners,
uint _required uint256 _required
) )
public public
validRequirement(_owners.length, _required) validRequirement(_owners.length, _required)
{ {
for (uint i=0; i<_owners.length; i++) { for (uint256 i = 0; i < _owners.length; i++) {
require(!isOwner[_owners[i]] && _owners[i] != address(0)); require(
!isOwner[_owners[i]] && _owners[i] != address(0),
"DUPLICATE_OR_NULL_OWNER"
);
isOwner[_owners[i]] = true; isOwner[_owners[i]] = true;
} }
owners = _owners; owners = _owners;
@@ -171,14 +175,16 @@ contract MultiSigWallet {
ownerExists(owner) ownerExists(owner)
{ {
isOwner[owner] = false; isOwner[owner] = false;
for (uint i=0; i<owners.length - 1; i++) for (uint256 i = 0; i < owners.length - 1; i++) {
if (owners[i] == owner) { if (owners[i] == owner) {
owners[i] = owners[owners.length - 1]; owners[i] = owners[owners.length - 1];
break; break;
} }
}
owners.length -= 1; owners.length -= 1;
if (required > owners.length) if (required > owners.length) {
changeRequirement(owners.length); changeRequirement(owners.length);
}
emit OwnerRemoval(owner); emit OwnerRemoval(owner);
} }
@@ -191,11 +197,12 @@ contract MultiSigWallet {
ownerExists(owner) ownerExists(owner)
ownerDoesNotExist(newOwner) ownerDoesNotExist(newOwner)
{ {
for (uint i=0; i<owners.length; i++) for (uint256 i = 0; i < owners.length; i++) {
if (owners[i] == owner) { if (owners[i] == owner) {
owners[i] = newOwner; owners[i] = newOwner;
break; break;
} }
}
isOwner[owner] = false; isOwner[owner] = false;
isOwner[newOwner] = true; isOwner[newOwner] = true;
emit OwnerRemoval(owner); emit OwnerRemoval(owner);
@@ -204,7 +211,7 @@ contract MultiSigWallet {
/// @dev Allows to change the number of required confirmations. Transaction has to be sent by wallet. /// @dev Allows to change the number of required confirmations. Transaction has to be sent by wallet.
/// @param _required Number of required confirmations. /// @param _required Number of required confirmations.
function changeRequirement(uint _required) function changeRequirement(uint256 _required)
public public
onlyWallet onlyWallet
validRequirement(owners.length, _required) validRequirement(owners.length, _required)
@@ -218,9 +225,9 @@ contract MultiSigWallet {
/// @param value Transaction ether value. /// @param value Transaction ether value.
/// @param data Transaction data payload. /// @param data Transaction data payload.
/// @return Returns transaction ID. /// @return Returns transaction ID.
function submitTransaction(address destination, uint value, bytes memory data) function submitTransaction(address destination, uint256 value, bytes memory data)
public public
returns (uint transactionId) returns (uint256 transactionId)
{ {
transactionId = _addTransaction(destination, value, data); transactionId = _addTransaction(destination, value, data);
confirmTransaction(transactionId); confirmTransaction(transactionId);
@@ -228,7 +235,7 @@ contract MultiSigWallet {
/// @dev Allows an owner to confirm a transaction. /// @dev Allows an owner to confirm a transaction.
/// @param transactionId Transaction ID. /// @param transactionId Transaction ID.
function confirmTransaction(uint transactionId) function confirmTransaction(uint256 transactionId)
public public
ownerExists(msg.sender) ownerExists(msg.sender)
transactionExists(transactionId) transactionExists(transactionId)
@@ -241,7 +248,7 @@ contract MultiSigWallet {
/// @dev Allows an owner to revoke a confirmation for a transaction. /// @dev Allows an owner to revoke a confirmation for a transaction.
/// @param transactionId Transaction ID. /// @param transactionId Transaction ID.
function revokeConfirmation(uint transactionId) function revokeConfirmation(uint256 transactionId)
public public
ownerExists(msg.sender) ownerExists(msg.sender)
confirmed(transactionId, msg.sender) confirmed(transactionId, msg.sender)
@@ -253,7 +260,7 @@ contract MultiSigWallet {
/// @dev Allows anyone to execute a confirmed transaction. /// @dev Allows anyone to execute a confirmed transaction.
/// @param transactionId Transaction ID. /// @param transactionId Transaction ID.
function executeTransaction(uint transactionId) function executeTransaction(uint256 transactionId)
public public
ownerExists(msg.sender) ownerExists(msg.sender)
confirmed(transactionId, msg.sender) confirmed(transactionId, msg.sender)
@@ -262,9 +269,16 @@ contract MultiSigWallet {
if (isConfirmed(transactionId)) { if (isConfirmed(transactionId)) {
Transaction storage txn = transactions[transactionId]; Transaction storage txn = transactions[transactionId];
txn.executed = true; txn.executed = true;
if (_externalCall(txn.destination, txn.value, txn.data.length, txn.data)) if (
_externalCall(
txn.destination,
txn.value,
txn.data.length,
txn.data
)
) {
emit Execution(transactionId); emit Execution(transactionId);
else { } else {
emit ExecutionFailure(transactionId); emit ExecutionFailure(transactionId);
txn.executed = false; txn.executed = false;
} }
@@ -273,7 +287,15 @@ contract MultiSigWallet {
// call has been separated into its own function in order to take advantage // 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. // of the Solidity's code generator to produce a loop that copies tx.data into memory.
function _externalCall(address destination, uint value, uint dataLength, bytes memory data) internal returns (bool) { function _externalCall(
address destination,
uint256 value,
uint256 dataLength,
bytes memory data
)
internal
returns (bool)
{
bool result; bool result;
assembly { assembly {
let x := mload(0x40) // "Allocate" memory for output (0x40 is where "free memory" pointer is stored by convention) let x := mload(0x40) // "Allocate" memory for output (0x40 is where "free memory" pointer is stored by convention)
@@ -296,17 +318,19 @@ contract MultiSigWallet {
/// @dev Returns the confirmation status of a transaction. /// @dev Returns the confirmation status of a transaction.
/// @param transactionId Transaction ID. /// @param transactionId Transaction ID.
/// @return Confirmation status. /// @return Confirmation status.
function isConfirmed(uint transactionId) function isConfirmed(uint256 transactionId)
public public
view view
returns (bool) returns (bool)
{ {
uint count = 0; uint256 count = 0;
for (uint i=0; i<owners.length; i++) { for (uint256 i = 0; i < owners.length; i++) {
if (confirmations[transactionId][owners[i]]) if (confirmations[transactionId][owners[i]]) {
count += 1; count += 1;
if (count == required) }
if (count == required) {
return true; return true;
}
} }
} }
@@ -318,10 +342,14 @@ contract MultiSigWallet {
/// @param value Transaction ether value. /// @param value Transaction ether value.
/// @param data Transaction data payload. /// @param data Transaction data payload.
/// @return Returns transaction ID. /// @return Returns transaction ID.
function _addTransaction(address destination, uint value, bytes memory data) function _addTransaction(
address destination,
uint256 value,
bytes memory data
)
internal internal
notNull(destination) notNull(destination)
returns (uint transactionId) returns (uint256 transactionId)
{ {
transactionId = transactionCount; transactionId = transactionCount;
transactions[transactionId] = Transaction({ transactions[transactionId] = Transaction({
@@ -340,14 +368,16 @@ contract MultiSigWallet {
/// @dev Returns number of confirmations of a transaction. /// @dev Returns number of confirmations of a transaction.
/// @param transactionId Transaction ID. /// @param transactionId Transaction ID.
/// @return Number of confirmations. /// @return Number of confirmations.
function getConfirmationCount(uint transactionId) function getConfirmationCount(uint256 transactionId)
public public
view view
returns (uint count) returns (uint256 count)
{ {
for (uint i=0; i<owners.length; i++) for (uint256 i = 0; i < owners.length; i++) {
if (confirmations[transactionId][owners[i]]) if (confirmations[transactionId][owners[i]]) {
count += 1; count += 1;
}
}
} }
/// @dev Returns total number of transactions after filers are applied. /// @dev Returns total number of transactions after filers are applied.
@@ -357,12 +387,13 @@ contract MultiSigWallet {
function getTransactionCount(bool pending, bool executed) function getTransactionCount(bool pending, bool executed)
public public
view view
returns (uint count) returns (uint256 count)
{ {
for (uint i=0; i<transactionCount; i++) for (uint256 i = 0; i < transactionCount; i++) {
if ( pending && !transactions[i].executed if (pending && !transactions[i].executed || executed && transactions[i].executed) {
|| executed && transactions[i].executed)
count += 1; count += 1;
}
}
} }
/// @dev Returns list of owners. /// @dev Returns list of owners.
@@ -378,22 +409,24 @@ contract MultiSigWallet {
/// @dev Returns array with owner addresses, which confirmed transaction. /// @dev Returns array with owner addresses, which confirmed transaction.
/// @param transactionId Transaction ID. /// @param transactionId Transaction ID.
/// @return Returns array of owner addresses. /// @return Returns array of owner addresses.
function getConfirmations(uint transactionId) function getConfirmations(uint256 transactionId)
public public
view view
returns (address[] memory _confirmations) returns (address[] memory _confirmations)
{ {
address[] memory confirmationsTemp = new address[](owners.length); address[] memory confirmationsTemp = new address[](owners.length);
uint count = 0; uint256 count = 0;
uint i; uint256 i;
for (i=0; i<owners.length; i++) for (i = 0; i < owners.length; i++) {
if (confirmations[transactionId][owners[i]]) { if (confirmations[transactionId][owners[i]]) {
confirmationsTemp[count] = owners[i]; confirmationsTemp[count] = owners[i];
count += 1; count += 1;
} }
}
_confirmations = new address[](count); _confirmations = new address[](count);
for (i=0; i<count; i++) for (i = 0; i < count; i++) {
_confirmations[i] = confirmationsTemp[i]; _confirmations[i] = confirmationsTemp[i];
}
} }
/// @dev Returns list of transaction IDs in defined range. /// @dev Returns list of transaction IDs in defined range.
@@ -402,23 +435,28 @@ contract MultiSigWallet {
/// @param pending Include pending transactions. /// @param pending Include pending transactions.
/// @param executed Include executed transactions. /// @param executed Include executed transactions.
/// @return Returns array of transaction IDs. /// @return Returns array of transaction IDs.
function getTransactionIds(uint from, uint to, bool pending, bool executed) function getTransactionIds(
uint256 from,
uint256 to,
bool pending,
bool executed
)
public public
view view
returns (uint[] memory _transactionIds) returns (uint256[] memory _transactionIds)
{ {
uint[] memory transactionIdsTemp = new uint[](transactionCount); uint256[] memory transactionIdsTemp = new uint256[](transactionCount);
uint count = 0; uint256 count = 0;
uint i; uint256 i;
for (i=0; i<transactionCount; i++) for (i = 0; i < transactionCount; i++) {
if ( pending && !transactions[i].executed if (pending && !transactions[i].executed || executed && transactions[i].executed) {
|| executed && transactions[i].executed)
{
transactionIdsTemp[count] = i; transactionIdsTemp[count] = i;
count += 1; count += 1;
} }
_transactionIds = new uint[](to - from); }
for (i=from; i<to; i++) _transactionIds = new uint256[](to - from);
for (i = from; i < to; i++) {
_transactionIds[i - from] = transactionIdsTemp[i]; _transactionIds[i - from] = transactionIdsTemp[i];
}
} }
} }