Skip to content

Commit c0bf98e

Browse files
authored
Fix to allow withdrawing without rewards (#85)
1 parent b153495 commit c0bf98e

File tree

2 files changed

+52
-1
lines changed

2 files changed

+52
-1
lines changed

contracts/staking/AbstractStaking.sol

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,10 @@ abstract contract AbstractStaking is AbstractValueDistributor, Initializable {
102102
owedValue_ = getOwedValue(msg.sender);
103103

104104
unstake(shares_);
105-
claim(owedValue_);
105+
106+
if (owedValue_ > 0) {
107+
claim(owedValue_);
108+
}
106109
}
107110

108111
/**

test/staking/AbstractStaking.test.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,54 @@ describe("AbstractStaking", () => {
431431
expect(await abstractStaking.getOwedValue(FIRST)).to.equal(0);
432432
expect(await abstractStaking.userOwedValue(FIRST)).to.equal(0);
433433
});
434+
435+
it("should work as expected if withdraw is called right after claiming all the rewards within one block", async () => {
436+
await mintAndApproveTokens(SECOND, sharesToken, wei(200, sharesDecimals));
437+
await mintAndApproveTokens(FIRST, sharesToken, wei(200, sharesDecimals));
438+
439+
await abstractStaking.connect(FIRST).stake(wei(100, sharesDecimals));
440+
441+
// triggering the next block
442+
await mintAndApproveTokens(FIRST, sharesToken, wei(100, sharesDecimals));
443+
444+
await abstractStaking.multicall([
445+
abstractStaking.interface.encodeFunctionData("claim", [await abstractStaking.getOwedValue(FIRST)]),
446+
abstractStaking.interface.encodeFunctionData("withdraw"),
447+
]);
448+
449+
expect(await abstractStaking.getOwedValue(FIRST)).to.equal(0);
450+
expect(await abstractStaking.userOwedValue(FIRST)).to.equal(0);
451+
expect(await abstractStaking.userShares(FIRST)).to.equal(0);
452+
});
453+
454+
it("should withdraw as expected if there are no rewards because of the 0 rate", async () => {
455+
await abstractStaking.setRate(0);
456+
457+
await mintAndApproveTokens(FIRST, sharesToken, wei(100, sharesDecimals));
458+
459+
await abstractStaking.connect(FIRST).stake(wei(100, sharesDecimals));
460+
461+
await time.setNextBlockTimestamp((await time.latest()) + 30);
462+
463+
await abstractStaking.withdraw();
464+
465+
expect(await abstractStaking.getOwedValue(FIRST)).to.equal(0);
466+
expect(await abstractStaking.userOwedValue(FIRST)).to.equal(0);
467+
expect(await abstractStaking.userShares(FIRST)).to.equal(0);
468+
});
469+
470+
it("should not allow to withdraw if there are no shares", async () => {
471+
await mintAndApproveTokens(FIRST, sharesToken, wei(200, sharesDecimals));
472+
473+
await abstractStaking.connect(FIRST).stake(wei(200, sharesDecimals));
474+
475+
await expect(
476+
abstractStaking.multicall([
477+
abstractStaking.interface.encodeFunctionData("unstake", [wei(200, sharesDecimals)]),
478+
abstractStaking.interface.encodeFunctionData("withdraw"),
479+
]),
480+
).to.be.revertedWith("ValueDistributor: amount has to be more than 0");
481+
});
434482
});
435483

436484
describe("claim()", () => {

0 commit comments

Comments
 (0)