Skip to content

Commit 14e1152

Browse files
committed
Add detailed test case for dividend contract
Update the dividend contract
1 parent dc6a80c commit 14e1152

File tree

2 files changed

+416
-11
lines changed

2 files changed

+416
-11
lines changed

contracts/dividend.sol

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,16 @@ contract DividendContract is ReentrancyGuard {
7070
return cycles[currentCycleIndex];
7171
}
7272

73+
function getTotalStaked(uint256 cycleIndex) public view returns (uint256) {
74+
if (cycleIndex == currentCycleIndex) {
75+
return totalStaked;
76+
} else if (cycleIndex < currentCycleIndex) {
77+
return cycles[cycleIndex].totalStaked;
78+
} else {
79+
return 0;
80+
}
81+
}
82+
7383
// deposit token to the current cycle
7484
function _depositToken(address token, uint256 amount) internal {
7585
require(amount > 0, "Cannot deposit 0");
@@ -118,10 +128,12 @@ contract DividendContract is ReentrancyGuard {
118128
}
119129

120130
// print the stake records
131+
/*
121132
console.log("will print stake records for user %s", user);
122133
for (uint i = 0; i < stakeRecords.length; i++) {
123134
console.log("StakeRecords: cycleIndex %d, stake mount %d", stakeRecords[i].cycleIndex, stakeRecords[i].amount);
124135
}
136+
*/
125137

126138
for (uint i = stakeRecords.length - 1; ; i--) {
127139
if (stakeRecords[i].cycleIndex <= cycleIndex) {
@@ -165,20 +177,21 @@ contract DividendContract is ReentrancyGuard {
165177
// withdraw staking tokens from current first and then next cycles
166178
// withdraw amount must be less than or equal to the staked amount
167179
function unstake(uint256 amount) external nonReentrant {
180+
require(amount > 0, "Cannot unstake 0");
168181
StakeRecord[] storage stakeRecords = UserStakeRecords[msg.sender];
169182
require(stakeRecords.length > 0, "No stake record found");
170183

171184
console.log("user unstake <=== amount %d, cycle %d, user %s", amount, currentCycleIndex, msg.sender);
172185

173186
// get the last stake record of the user
174187
StakeRecord storage lastStakeRecord = stakeRecords[stakeRecords.length - 1];
175-
require(lastStakeRecord.amount >= amount, "Insufficient staked amount");
188+
require(lastStakeRecord.amount >= amount, "Insufficient stake amount");
176189

177190
// 如果存在当前周期的质押操作,那么这个质押操作是可以直接撤销的不影响周期数据(当前质押要在下个周期进入cycleInfo中)
178191
// 如果不是当前周期的质押操作,或者当前周期的质押数量不足,那么这个质押操作是需要从上个周期关联的cycleInfo数据中减去的
179-
console.log("unstaking amount %d", amount);
180-
console.log("currentCycleIndex %d, lastStakeRecord.cycleIndex %d, amount %d", currentCycleIndex, lastStakeRecord.cycleIndex, lastStakeRecord.amount);
181-
console.log("lastStakeRecord.cycleIndex %d", lastStakeRecord.cycleIndex);
192+
// console.log("unstaking amount %d", amount);
193+
// console.log("currentCycleIndex %d, lastStakeRecord.cycleIndex %d, amount %d", currentCycleIndex, lastStakeRecord.cycleIndex, lastStakeRecord.amount);
194+
// console.log("lastStakeRecord.cycleIndex %d", lastStakeRecord.cycleIndex);
182195
if (lastStakeRecord.cycleIndex == currentCycleIndex) {
183196

184197
uint256 newAmount = 0;
@@ -197,9 +210,9 @@ contract DividendContract is ReentrancyGuard {
197210
uint256 diff = amount - newAmount;
198211

199212
StakeRecord storage prevStakeRecord = stakeRecords[stakeRecords.length - 2];
200-
console.log("prevStakeRecord.amount %d", prevStakeRecord.amount);
201-
console.log("prevStakeRecord.cycleIndex %d", prevStakeRecord.cycleIndex);
202-
console.log("prevStakeRecord.totalStaked %d", cycles[prevStakeRecord.cycleIndex].totalStaked);
213+
// console.log("prevStakeRecord.amount %d", prevStakeRecord.amount);
214+
// console.log("prevStakeRecord.cycleIndex %d", prevStakeRecord.cycleIndex);
215+
// console.log("prevStakeRecord.totalStaked %d", cycles[prevStakeRecord.cycleIndex].totalStaked);
203216

204217
// the last record is unstaked all and is empty, delete it
205218
stakeRecords.pop();
@@ -218,6 +231,7 @@ contract DividendContract is ReentrancyGuard {
218231

219232
totalStaked -= amount;
220233

234+
console.log("will unstake transfer %s ===> %d", msg.sender, amount);
221235
require(IERC20(stakingToken).transfer(msg.sender, amount), "Unstake failed");
222236

223237
emit Unstake(msg.sender, amount);
@@ -244,15 +258,16 @@ contract DividendContract is ReentrancyGuard {
244258
}
245259

246260
// check if the user has settled the rewards for the cycle
247-
function isDividendWithdrawed(address user, uint256 cycleIndex, address token) public view returns (bool) {
248-
bytes32 key = keccak256(abi.encodePacked(user, cycleIndex, token));
261+
function isDividendWithdrawed(uint256 cycleIndex, address token) public view returns (bool) {
262+
bytes32 key = keccak256(abi.encodePacked(msg.sender, cycleIndex, token));
249263
return withdrawDividendState[key];
250264
}
251265

252266
// claim rewards for the cycle
253267
function withdrawDividends(uint256[] calldata cycleIndexs, address[] calldata tokens) external nonReentrant {
254268
require(cycleIndexs.length > 0, "No cycle index");
255269
require(tokens.length > 0, "No token");
270+
// require(UserStakeRecords[msg.sender].length > 0, "No stake record");
256271

257272
// display the params
258273
console.log("will withdraw dividends user %s", msg.sender);
@@ -275,7 +290,8 @@ contract DividendContract is ReentrancyGuard {
275290
// withdraw every token
276291
for (uint j = 0; j < tokens.length; j++) {
277292
address token = tokens[j];
278-
require(!isDividendWithdrawed(msg.sender, cycleIndex, token), "Already claimed");
293+
bytes32 key = keccak256(abi.encodePacked(msg.sender, cycleIndex, token));
294+
require(!withdrawDividendState[key], "Already claimed");
279295

280296
CycleInfo storage cycle = cycles[cycleIndex];
281297

@@ -287,6 +303,9 @@ contract DividendContract is ReentrancyGuard {
287303
// 所以需要进入下一个周期才会生效,所以这里使用前一个周期的数据
288304
uint256 userStaked = _getStakeAmount(msg.sender, cycleIndex - 1);
289305
console.log("userStaked %d, cycle %d", userStaked, cycleIndex);
306+
if (userStaked == 0) {
307+
continue;
308+
}
290309

291310
// find the token reward of the cycle
292311
uint256 rewardAmount = 0;
@@ -305,14 +324,14 @@ contract DividendContract is ReentrancyGuard {
305324
}
306325

307326
// set the withdraw state of the user and the cycle and the token
308-
bytes32 key = keccak256(abi.encodePacked(msg.sender, cycleIndex, token));
309327
withdrawDividendState[key] = true;
310328
}
311329
}
312330

313331
// do the transfer
314332
for (uint i = 0; i < realRewardLength; i++) {
315333
RewardInfo memory reward = rewards[i];
334+
console.log("will withdraw transfer %s %s ===> %d", reward.token, msg.sender, reward.amount);
316335
if (reward.token == address(0)) {
317336
payable(msg.sender).transfer(reward.amount);
318337
} else {

0 commit comments

Comments
 (0)