-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathTodo.txt
143 lines (106 loc) · 3.95 KB
/
Todo.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
// TODO: add share functionality means if there are more then 1 recipient
// update recipient
// fallback function
// store will on chain in encrypted form.
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;
contract DigitalWill {
struct UserInfo {
address user;
mapping(address => uint256) recipientBalances;
address[] recipients;
uint lastAction;
uint256 balance;
}
mapping(address => UserInfo) public users;
event UserAdded(
address indexed user,
address[] indexed recipients,
uint256 balance
);
event UserRemoved(address indexed user);
event Withdrawn(
address indexed parent,
address indexed recipient,
uint256 balance
);
event RevertedToOwner(address indexed user, uint256 balance);
event Pinged(address indexed user);
function adduser(address[] memory _recipients) external payable {
require(msg.value > 0, "You must send some Ether to deposit.");
require(users[msg.sender].user == address(0), "User already exists");
UserInfo storage userInfo = users[msg.sender];
userInfo.user = msg.sender;
userInfo.recipients = _recipients;
userInfo.lastAction = block.timestamp;
userInfo.balance = msg.value;
uint256 recipientBalance = msg.value / _recipients.length;
for (uint i = 0; i < _recipients.length; i++) {
userInfo.recipientBalances[_recipients[i]] = recipientBalance;
}
emit UserAdded(msg.sender, _recipients, msg.value);
}
function withdraw(address parent) external {
require(users[parent].user != address(0), "User does not exist");
require(
users[parent].user == parent && isRecipient(parent, msg.sender),
"Invalid user or recipient"
);
require(
(block.timestamp - users[parent].lastAction) >= 52 weeks,
"Withdrawal not allowed yet"
);
uint256 recipientBalance = users[parent].recipientBalances[msg.sender];
(bool success, ) = msg.sender.call{value: recipientBalance}("");
require(success, "Transfer to recipient failed");
emit Withdrawn(parent, msg.sender, recipientBalance);
users[parent].balance -= recipientBalance;
users[parent].recipientBalances[msg.sender] = 0;
if (users[parent].balance == 0) {
removeUser(parent);
}
}
// add revert transection means it will transfer the amount back to the wallet.
function revertToOwner() external {
require(
msg.sender == users[msg.sender].user,
"Only owner can call this function"
);
(bool success, ) = users[msg.sender].user.call{
value: users[msg.sender].balance
}("");
require(success, "Transfer to recipient failed");
emit RevertedToOwner(msg.sender, users[msg.sender].balance);
users[msg.sender].balance = 0;
removeUser(msg.sender);
}
function ping() external {
require(
msg.sender == users[msg.sender].user,
"Only the user can call this function"
);
users[msg.sender].lastAction = block.timestamp;
emit Pinged(msg.sender);
}
// View function to return user info
function getUserInfo(address _user) public view returns (UserInfo memory) {
return users[_user];
}
function isRecipient(
address _user,
address _recipient
) public view returns (bool) {
return users[_user].recipientBalances[_recipient] > 0;
}
function isUser(address _user) public view returns (bool) {
return users[_user].user == _user;
}
function removeUser(address userAddress) internal {
require(
users[userAddress].balance == 0,
" User can't be remvoed Because User has not withdrawn yet"
);
emit UserRemoved(userAddress);
delete users[userAddress];
}
}