diff --git a/contracts/accounting/FarmAccounting.sol b/contracts/accounting/FarmAccounting.sol index 78e2a6e..60597f0 100644 --- a/contracts/accounting/FarmAccounting.sol +++ b/contracts/accounting/FarmAccounting.sol @@ -31,25 +31,25 @@ library FarmAccounting { } } - function startFarming(Info storage info, uint256 amount, uint256 period) internal returns(uint256) { + function startFarming(Info storage info, uint256 amount, uint256 period) internal returns(uint256 newAmount) { if (period == 0) revert ZeroDuration(); if (period > type(uint32).max) revert DurationTooLarge(); + newAmount = amount; // If something left from prev farming add it to the new farming (uint40 finished, uint32 duration, uint184 reward, uint256 balance) = (info.finished, info.duration, info.reward, info.balance); if (block.timestamp < finished) { - amount += reward - farmedSinceCheckpointScaled(info, finished - duration) / _SCALE; + newAmount += reward - farmedSinceCheckpointScaled(info, finished - duration) / _SCALE; } - if (amount > _MAX_REWARD_AMOUNT) revert AmountTooLarge(); + if (newAmount > _MAX_REWARD_AMOUNT) revert AmountTooLarge(); (info.finished, info.duration, info.reward, info.balance) = ( uint40(block.timestamp + period), uint32(period), - uint184(amount), + uint184(newAmount), balance + amount ); - return amount; } function stopFarming(Info storage info) internal returns(uint256 leftover) { diff --git a/test/FarmingPool.js b/test/FarmingPool.js index 9ff6262..4092c4c 100644 --- a/test/FarmingPool.js +++ b/test/FarmingPool.js @@ -51,6 +51,23 @@ describe('FarmingPool', function () { farm.connect(wallet2).startFarming(1000, 60 * 60 * 24), ).to.be.revertedWithCustomError(farm, 'NotDistributor'); }); + + it('should rescue extra gift tokens from farm in the case of overlapping farming', async function () { + const { gift, farm } = await loadFixture(initContracts); + const duration = BigInt(60 * 60 * 24); + const amount = 100n; + await gift.mint(farm, amount); + await farm.startFarming(1000, duration); + await time.increaseTo((await farm.farmInfo()).finished - duration / 2n); + await farm.startFarming(1000, duration); + await farm.stopFarming(); + const farmInfoBefore = await farm.farmInfo(); + console.log(`farmBalance = ${await gift.balanceOf(farm)}, farmInfo.reward = ${farmInfoBefore.reward}, farmInfo.balance = ${farmInfoBefore.balance}`); + // Shouldn't revert with InsufficientFunds + await farm.rescueFunds(gift, amount); + const farmInfoAfter = await farm.farmInfo(); + console.log(`farmBalance = ${await gift.balanceOf(farm)}, farmInfo.reward = ${farmInfoAfter.reward}, farmInfo.balance = ${farmInfoAfter.balance}`); + }); }); describe('name', function () {