diff --git a/contracts/MultiSigWallet.sol b/contracts/MultiSigWallet.sol index e733efe..c7b2b5c 100644 --- a/contracts/MultiSigWallet.sol +++ b/contracts/MultiSigWallet.sol @@ -2,6 +2,11 @@ pragma solidity ^0.8.9; + +/// @title A Multisig wallet +/// @author DecenterAI +/// @notice Serves as treasury for decenter AI + contract MultiSigWallet { event Deposit(address indexed sender, uint amount); event Submit(uint indexed txId); @@ -43,6 +48,10 @@ contract MultiSigWallet { _; } + + /// @notice Deploys the smart contract and creates owners and approval number + /// @dev Assigns _owners to wallet owners list + // @dev Assigns _required to number of approvals required constructor(address[] memory _owners, uint _required){ require(_owners.length > 0, "Owners required"); require(_required > 0 && _required <= _owners.length,"Invalid required number of owners"); @@ -53,10 +62,13 @@ contract MultiSigWallet { require(owner != address(0), "Invalid owner"); require(!isOwner[owner], "Owner is not unique"); + isOwner[owner] = true; + //add owner owners.push(owner); } + //set required number required = _required; } @@ -66,7 +78,15 @@ contract MultiSigWallet { emit Deposit(msg.sender, msg.value); } + /** + *@notice Submits withdrawal transaction fro approval + *@dev Function can only be called by a wallet owner + *@param _to The address of the account that will receive the token + *@param _value The value of eth `address` will receive + *@param _data The call data for the transfer function + */ function submit(address _to , uint _value, bytes calldata _data) external onlyOwner{ + //add transaction to transaction list transactions.push( Transaction({ to: _to, @@ -79,13 +99,26 @@ contract MultiSigWallet { emit Submit(transactions.length - 1); } - + /** + *@notice Approves transfer transaction + *@dev Function can only be called by a wallet owner + *@dev _txId must exist in submitted transactions + *@dev _txId must be approved + *@dev _txId must have not been executed + *@param _txId The transaction id for the withdrawal transaction + */ function approve(uint _txId) external onlyOwner txExists(_txId) notApproved(_txId) notExecuted(_txId){ + //approve transaction approved[_txId][msg.sender] = true; emit Approve(msg.sender, _txId); } - + /** + *@notice Checks number of approvals provided for a transaction + *@dev Function can only be called withhin the smartcontract + *@param _txId The transaction id to get number of approvals + *@return count Returns a uint + */ function _getApprovalCount(uint _txId) private view returns (uint count){ for(uint i; i < owners.length; i++){ if(approved[_txId][owners[i]]){ @@ -95,20 +128,35 @@ contract MultiSigWallet { } + /** + *@notice Executes the withdraw transaction + *@dev _txId must exist in submitted transactions + *@dev _txId must have not been executed + *@param _txId The id of the withdraw transaction + */ function execute(uint _txId) external txExists(_txId) notExecuted(_txId){ require(_getApprovalCount(_txId) >= required, "approvals < required"); Transaction storage transaction = transactions[_txId]; transaction.executed = true; + //withdraw (bool success, ) = transaction.to.call{value: transaction.value}(transaction.data); require(success, "tx failed"); emit Execute(_txId); } + + /** + *@notice Revokes approval for a withdrawal transaction + *@dev Function can only be called by a wallet owner + *@dev _txId must exist in submitted transactions + *@dev _txId must have not been executed + *@param _txId transaction Id for the withraw transaction + */ function revoke(uint _txId) external onlyOwner txExists(_txId) notExecuted(_txId){ require(approved[_txId][msg.sender],"tx not approved"); - + //revoke approval approved[_txId][msg.sender] = false; emit Revoke(msg.sender, _txId); } diff --git a/contracts/Payment.sol b/contracts/Payment.sol index 4b9e5fd..746ea74 100644 --- a/contracts/Payment.sol +++ b/contracts/Payment.sol @@ -4,6 +4,11 @@ pragma solidity ^0.8.9; import "./MultiSigWallet.sol"; + +/// @title A Multisig wallet +/// @author DecenterAI +/// @notice Serves as deposit contract + contract Payment { MultiSigWallet public wallet; mapping(address => uint) public depositRecord; @@ -11,15 +16,26 @@ contract Payment { event Deposit(address indexed payer, uint _amount, bool status); event Erase(address indexed user); + /** + *@notice Deposits eth into the treasury + *@param _amount The amount of eth deposited + */ function deposit(uint _amount) external payable{ require(msg.value == _amount, "invalid deposit amount"); + //deposit to treasury (bool success, ) = address(wallet).call{value: msg.value}(""); + //record deposit depositRecord[msg.sender] = msg.value; emit Deposit(msg.sender, _amount, success); } + /** + *@notice Removes deposit record for a user + *@param _user Address of the depositor + */ function zeroDepositRecord(address _user) external { + //remove record depositRecord[_user] = 0; emit Erase(_user); }