diff --git a/contracts/SharedWallet.sol b/contracts/SharedWallet.sol index 8b13789..6b6a6e5 100644 --- a/contracts/SharedWallet.sol +++ b/contracts/SharedWallet.sol @@ -1 +1,79 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +contract SharedWallet { + mapping(address => uint256) private balances; + mapping(address => bool) private isOwner; + + event OwnerAdded(address indexed owner); + event OwnerRemoved(address indexed owner); + event FundsDeposited(address indexed depositor, uint256 amount); + event FundsWithdrawn(address indexed withdrawer, uint256 amount); + event FundsTransferred(address indexed sender, address indexed recipient, uint256 amount); + + modifier onlyOwner() { + require(isOwner[msg.sender], "Not an owner"); + _; + } + + constructor(address[] memory initialOwners) { + for (uint256 i = 0; i < initialOwners.length; i++) { + require(initialOwners[i] != address(0), "Invalid owner address"); + isOwner[initialOwners[i]] = true; + emit OwnerAdded(initialOwners[i]); + } + } + + function addOwner(address newOwner) external onlyOwner { + require(newOwner != address(0), "Invalid owner address"); + require(!isOwner[newOwner], "Address is already an owner"); + isOwner[newOwner] = true; + emit OwnerAdded(newOwner); + } + + function removeOwner(address ownerToRemove) external onlyOwner { + require(isOwner[ownerToRemove], "Address is not an owner"); + // Ensure that there is always at least one owner + require(getOwnerCount() > 1, "Cannot remove the last owner"); + isOwner[ownerToRemove] = false; + emit OwnerRemoved(ownerToRemove); + } + + function depositFunds() external payable { + require(msg.value > 0, "Must deposit a non-zero amount"); + balances[msg.sender] += msg.value; + emit FundsDeposited(msg.sender, msg.value); + } + + function withdrawFunds(uint256 amount) external onlyOwner { + require(amount > 0, "Must withdraw a non-zero amount"); + require(amount <= balances[msg.sender], "Insufficient funds"); + payable(msg.sender).transfer(amount); + balances[msg.sender] -= amount; + emit FundsWithdrawn(msg.sender, amount); + } + + function transferFunds(address recipient, uint256 amount) external onlyOwner { + require(recipient != address(0), "Invalid recipient address"); + require(amount > 0, "Must transfer a non-zero amount"); + require(amount <= balances[msg.sender], "Insufficient funds"); + balances[msg.sender] -= amount; + balances[recipient] += amount; + emit FundsTransferred(msg.sender, recipient, amount); + } + + function getBalance() external view returns (uint256) { + return balances[msg.sender]; + } + + function getOwnerCount() public view returns (uint256) { + uint256 count = 0; + for (uint256 i = 0; i < msg.data.length; i++) { + if (isOwner[msg.sender]) { + count++; + } + } + return count; + } +} diff --git a/contracts/TimeLock.sol b/contracts/TimeLock.sol index 8b13789..d1f0d56 100644 --- a/contracts/TimeLock.sol +++ b/contracts/TimeLock.sol @@ -1 +1,46 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +contract TimeLockedAllowance { + + struct Account { + uint256 balance; + uint256 lockTime; + } + + mapping(address => Account) private balances; + + event Deposit(address indexed account, uint256 amount); + event Withdrawal(address indexed account, uint256 amount); + event LockTimeIncreased(address indexed account, uint256 newLockTime); + + function deposit() external payable { + balances[msg.sender].balance += msg.value; + emit Deposit(msg.sender, msg.value); + } + + function withdraw() external { + require(block.timestamp >= balances[msg.sender].lockTime, "Funds are still locked"); + + uint256 amount = balances[msg.sender].balance; + balances[msg.sender].balance = 0; + + payable(msg.sender).transfer(amount); + emit Withdrawal(msg.sender, amount); + } + + function increaseLockTime(uint256 newLockTime) external { + require(newLockTime > balances[msg.sender].lockTime, "New lock time must be greater"); + balances[msg.sender].lockTime = newLockTime; + emit LockTimeIncreased(msg.sender, newLockTime); + } + + function getBalance() external view returns (uint256) { + return balances[msg.sender].balance; + } + + function getLockTime() external view returns (uint256) { + return balances[msg.sender].lockTime; + } +}