diff --git a/contracts/contracts/Subscriptions.sol b/contracts/contracts/Subscriptions.sol index 2447901..70ffc82 100644 --- a/contracts/contracts/Subscriptions.sol +++ b/contracts/contracts/Subscriptions.sol @@ -279,6 +279,7 @@ contract Subscriptions is Ownable { Subscription memory sub = subscriptions[user]; require(sub.start != 0, 'no subscription found'); require(sub.rate != 0, 'cannot extend a zero rate subscription'); + require(amount % sub.rate == 0, "amount not multiple of rate"); uint64 newEnd = uint64(Math.max(sub.end, block.timestamp)) + uint64(amount / sub.rate); diff --git a/contracts/test/contract.test.ts b/contracts/test/contract.test.ts index e1bdea4..73f3faa 100644 --- a/contracts/test/contract.test.ts +++ b/contracts/test/contract.test.ts @@ -652,14 +652,28 @@ describe('Subscriptions contract', () => { subscribeBlockNumber ); }); - + + it('should not allow extending an active subscription if amount is not multiple of rate', async function () { + const now = await latestBlockTimestamp(); + const start = now; + const end = now.add(1000); + const rate = BigNumber.from(7); + const amountToExtend = BigNumber.from(2000); // newEnd: end + 2000/7 = 1000 + 286 = 1286 + + // mine past the start of the subscription + await mineNBlocks(150); + + const tx = subscriptions.addTo(subscriber1.address, amountToExtend); + await expect(tx).revertedWith('amount not multiple of rate'); + }); + it('should allow extending an active subscription', async function () { const now = await latestBlockTimestamp(); const start = now; const end = now.add(1000); const rate = BigNumber.from(5); const amountToExtend = BigNumber.from(2000); // newEnd: end + 2000/5 = 1000 + 400 = 1400 - + const subscribeBlockNumber = await subscribe( stableToken, subscriptions, @@ -688,7 +702,7 @@ describe('Subscriptions contract', () => { const end = now.add(1000); const rate = BigNumber.from(5); const amountToExtend = BigNumber.from(2000); // newEnd: end + 2000/5 = 1000 + 400 = 1400 - + const subscribeBlockNumber = await subscribe( stableToken, subscriptions, @@ -1409,10 +1423,14 @@ async function addToSubscription( // * Tx const tx = subscriptions.connect(signer.signer).addTo(user, amount); const receipt = await (await tx).wait(); - const txTimestamp = (await subscriptions.provider.getBlock(receipt.blockNumber!)).timestamp; + const txTimestamp = ( + await subscriptions.provider.getBlock(receipt.blockNumber!) + ).timestamp; // * Check events - const newEnd = BigNumber.from(Math.max(beforeSub.end.toNumber(), txTimestamp)).add(amount.div(beforeSub.rate)); + const newEnd = BigNumber.from( + Math.max(beforeSub.end.toNumber(), txTimestamp) + ).add(Math.ceil(amount.toNumber() / beforeSub.rate.toNumber())); await expect(tx) .to.emit(subscriptions, 'Extend') .withArgs(user, beforeSub.end, newEnd, amount); @@ -1423,9 +1441,7 @@ async function addToSubscription( subscriptions.address ); expect(afterBalance).to.eq(beforeBalance.sub(amount)); - expect(afterContractBalance).to.eq( - beforeContractBalance.add(amount) - ); + expect(afterContractBalance).to.eq(beforeContractBalance.add(amount)); // * Check state const afterSub = await subscriptions.subscriptions(user);