Fix base multisig style
This commit is contained in:
@@ -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];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user