@@ -1587,6 +1587,104 @@ contract L2StakingTest is L2StakingBaseTest {
15871587 // Throw an error to check gas consumption
15881588 // assertTrue(false);
15891589 }
1590+
1591+ /**
1592+ * @notice staking -> distribute -> claim -> undelegate -> distribute -> claim
1593+ */
1594+ function test_delegatorClaimAllAfterUndelegate_succeeds () public {
1595+ address zeroAdd = 0x0000000000000000000000000000000000000000 ;
1596+ hevm.startPrank (alice);
1597+ morphToken.approve (address (l2Staking), type (uint256 ).max);
1598+ l2Staking.delegateStake (firstStaker, 5 ether);
1599+ l2Staking.delegateStake (secondStaker, 5 ether);
1600+ l2Staking.delegateStake (thirdStaker, 5 ether);
1601+ hevm.stopPrank ();
1602+
1603+ uint256 time = REWARD_EPOCH;
1604+ hevm.warp (time);
1605+
1606+ // reward starting
1607+ // rewardStartTime = 86400
1608+ // block.timeStamp >= rewardStartTime
1609+ // candidateNumber > 0
1610+ hevm.prank (multisig);
1611+ l2Staking.startReward ();
1612+
1613+ // staker set commission
1614+ hevm.prank (firstStaker);
1615+ l2Staking.setCommissionRate (1 );
1616+ hevm.prank (secondStaker);
1617+ l2Staking.setCommissionRate (1 );
1618+ hevm.prank (thirdStaker);
1619+ l2Staking.setCommissionRate (1 );
1620+
1621+ // *************** epoch = 1 ******************** //
1622+ time = REWARD_EPOCH * 2 ;
1623+ hevm.warp (time);
1624+
1625+ uint256 blocksCountOfEpoch = REWARD_EPOCH / 3 ;
1626+ hevm.roll (blocksCountOfEpoch * 2 );
1627+ hevm.prank (oracleAddress);
1628+ record.setLatestRewardEpochBlock (blocksCountOfEpoch);
1629+ _updateDistribute (0 );
1630+
1631+ // effectiveEpoch = 2
1632+ hevm.startPrank (bob);
1633+ morphToken.approve (address (l2Staking), type (uint256 ).max);
1634+ l2Staking.delegateStake (secondStaker, morphBalance - 5 ether);
1635+ hevm.stopPrank ();
1636+
1637+ // ranking changed by delegate amount
1638+ uint256 secondRanking = l2Staking.stakerRankings (secondStaker);
1639+ assertEq (secondRanking, 0 + 1 );
1640+
1641+ // *********************************** //
1642+ time = REWARD_EPOCH * (1 + 2 );
1643+ hevm.roll (blocksCountOfEpoch * (1 + 2 ));
1644+ hevm.warp (time);
1645+ _updateDistribute (1 );
1646+ // *********************************** //
1647+
1648+ uint256 aliceReward1 = distribute.queryUnclaimed (firstStaker, alice);
1649+ uint256 aliceReward2 = distribute.queryUnclaimed (secondStaker, alice);
1650+ uint256 aliceReward3 = distribute.queryUnclaimed (thirdStaker, alice);
1651+ hevm.startPrank (alice);
1652+ uint256 balanceBefore = morphToken.balanceOf (alice);
1653+ l2Staking.claimReward (zeroAdd, 0 );
1654+ uint256 balanceAfter = morphToken.balanceOf (alice);
1655+ assertEq (balanceAfter, balanceBefore + aliceReward1 + aliceReward2 + aliceReward3);
1656+ hevm.stopPrank ();
1657+
1658+ hevm.startPrank (alice);
1659+ l2Staking.undelegateStake (firstStaker);
1660+ l2Staking.undelegateStake (secondStaker);
1661+ l2Staking.undelegateStake (thirdStaker);
1662+ hevm.stopPrank ();
1663+
1664+ // *********************************** //
1665+ time = REWARD_EPOCH * (2 + 2 );
1666+ hevm.roll (blocksCountOfEpoch * (2 + 2 ));
1667+ hevm.warp (time);
1668+ _updateDistribute (2 );
1669+ // *********************************** //
1670+
1671+ uint256 aliceRewardNew1 = distribute.queryUnclaimed (firstStaker, alice);
1672+ uint256 aliceRewardNew2 = distribute.queryUnclaimed (secondStaker, alice);
1673+ uint256 aliceRewardNew3 = distribute.queryUnclaimed (thirdStaker, alice);
1674+ hevm.startPrank (alice);
1675+ balanceBefore = morphToken.balanceOf (alice);
1676+ l2Staking.claimReward (zeroAdd, 0 );
1677+ balanceAfter = morphToken.balanceOf (alice);
1678+ assertEq (balanceAfter, balanceBefore + aliceRewardNew1 + aliceRewardNew2 + aliceRewardNew3);
1679+
1680+ hevm.expectRevert ("no remaining reward of the delegatee " );
1681+ distribute.queryUnclaimed (firstStaker, alice);
1682+ hevm.expectRevert ("no remaining reward of the delegatee " );
1683+ distribute.queryUnclaimed (secondStaker, alice);
1684+ hevm.expectRevert ("no remaining reward of the delegatee " );
1685+ distribute.queryUnclaimed (thirdStaker, alice);
1686+ hevm.stopPrank ();
1687+ }
15901688
15911689 /**
15921690 * @notice staking -> distribute -> claim
0 commit comments