Skip to content

Commit

Permalink
withdraw veJOJO reward after lock expired
Browse files Browse the repository at this point in the history
  • Loading branch information
radar bear committed Dec 4, 2024
1 parent b3dafb5 commit 212500f
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 6 deletions.
9 changes: 6 additions & 3 deletions src/token/veJOJO.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ contract veJOJO is ReentrancyGuard, Ownable {
IERC20 public immutable JOJO;
IERC20 public immutable USDC;

uint8 public constant decimals = 18;

struct LockInfo {
uint256 amount;
uint256 end;
Expand Down Expand Up @@ -98,6 +100,7 @@ contract veJOJO is ReentrancyGuard, Ownable {
USDC.safeTransfer(msg.sender, pending);
emit RewardClaimed(msg.sender, pending);
}
userLock.rewardDebt = 0;
}

function addReward(uint256 _amount) external onlyOwner {
Expand All @@ -115,7 +118,7 @@ contract veJOJO is ReentrancyGuard, Ownable {

for (uint256 i = 0; i < userLockCount[msg.sender]; i++) {
LockInfo storage userLock = userLocks[msg.sender][i];
if (block.timestamp < userLock.end) {
if (userLock.amount > 0) {
userLock.rewardDebt = (userLock.veJOJOAmount * accRewardPerShare) / 1e18;
}
}
Expand All @@ -129,7 +132,7 @@ contract veJOJO is ReentrancyGuard, Ownable {

for (uint256 i = 0; i < userLockCount[_user]; i++) {
LockInfo memory userLock = userLocks[_user][i];
if (block.timestamp < userLock.end) {
if (userLock.amount > 0) {
uint256 pending = (userLock.veJOJOAmount * accRewardPerShare / 1e18) - userLock.rewardDebt;
totalPending += pending;
}
Expand All @@ -142,7 +145,7 @@ contract veJOJO is ReentrancyGuard, Ownable {
uint256 totalBalance = 0;
for (uint256 i = 0; i < userLockCount[_user]; i++) {
LockInfo memory userLock = userLocks[_user][i];
if (block.timestamp < userLock.end) {
if (userLock.amount > 0) {
totalBalance += userLock.veJOJOAmount;
}
}
Expand Down
63 changes: 60 additions & 3 deletions test/impl/veJOJOTest.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ contract VeJOJOTest is Test {
usdcToken.transfer(owner, 10000e6);

vm.stopPrank();

}

/*********************************
Expand Down Expand Up @@ -424,7 +423,7 @@ contract VeJOJOTest is Test {
vm.expectRevert("Cannot delegate to zero address");
veJOJOContract.delegate(lockId, address(0));

// 测试无效�� lockId
// 测试无效 lockId
vm.expectRevert("Invalid lock ID");
veJOJOContract.delegate(99, address(0x123));

Expand All @@ -442,7 +441,7 @@ contract VeJOJOTest is Test {
}

function testSelfDelegateVotes() public {
// 用户存入 JOJO,此时投票权应该在自己名下
// 用户存入 JOJO,此时投票应该在自己名下
uint256 depositAmount = 1000e18;
uint256 lockTime = 365 days;
vm.startPrank(owner);
Expand Down Expand Up @@ -483,4 +482,62 @@ contract VeJOJOTest is Test {
// 验证投票权完全清零
assertEq(veJOJOContract.getVotes(address(this)), 0, "Votes should be zero after all withdrawals");
}

function testDecimals() public {
assertEq(veJOJOContract.decimals(), 18, "veJOJO decimals should be 18");
}

function testExpiredLockRewardAndBalance() public {
// Alice 存入 JOJO
uint256 depositAmount = 1000e18;
uint256 lockTime = 7 days; // 最短锁定期

vm.startPrank(alice);
jojoToken.approve(address(veJOJOContract), depositAmount);
veJOJOContract.deposit(depositAmount, lockTime);
vm.stopPrank();

uint256 expectedVeJOJOAmount = veJOJOContract.calculateVeJOJO(depositAmount, lockTime);

// owner 添加奖励
uint256 rewardAmount = 1000e6; // 1000 USDC
vm.startPrank(owner);
usdcToken.approve(address(veJOJOContract), rewardAmount);
veJOJOContract.addReward(rewardAmount);
vm.stopPrank();

// 等待锁定期结束
vm.warp(block.timestamp + lockTime + 1);

// 验证锁定到期后仍然可以计算正确的余额
assertEq(veJOJOContract.balanceOf(alice), expectedVeJOJOAmount, "Balance should remain until withdrawal");

// 验证锁定到期后仍然可以获得奖励
uint256 pendingReward = veJOJOContract.pendingReward(alice);
assertTrue(pendingReward > 0, "Should have pending reward after lock expiry");

// Alice 领取奖励
uint256 usdcBalanceBefore = usdcToken.balanceOf(alice);
vm.prank(alice);
veJOJOContract.claimReward();
uint256 usdcBalanceAfter = usdcToken.balanceOf(alice);

assertEq(usdcBalanceAfter - usdcBalanceBefore, pendingReward, "Should receive correct reward amount");

// 验证领取奖励后,如果没有新的奖励添加,pendingReward 应该为 0
assertEq(veJOJOContract.pendingReward(alice), 0, "Pending reward should be 0 after claim");

// 等待一段时间,确保即使时间过去,没有新奖励的情况下 pendingReward 仍然为 0
vm.warp(block.timestamp + 7 days);
assertEq(veJOJOContract.pendingReward(alice), 0, "Pending reward should still be 0 after time passes");

// Alice 提取 JOJO
vm.prank(alice);
veJOJOContract.withdraw(0);
(,,,uint256 rewardDebt,) = veJOJOContract.userLocks(alice, 0);
assertEq(rewardDebt, 0, "RewardDebt should be zero after withdrawal");

// 提取后余额应该为 0
assertEq(veJOJOContract.balanceOf(alice), 0, "Balance should be zero after withdrawal");
}
}

0 comments on commit 212500f

Please sign in to comment.