diff --git a/contracts/Swaplace.sol b/contracts/Swaplace.sol index 7d19180..444858e 100644 --- a/contracts/Swaplace.sol +++ b/contracts/Swaplace.sol @@ -102,12 +102,18 @@ contract Swaplace is SwapFactory, ISwaplace, IERC165 { Swap memory swap = _swaps[swapId]; if (swap.owner != msg.sender) revert InvalidAddress(); - (, uint32 expiry, , uint256 value) = decodeConfig(swap.config); + (, uint32 expiry, uint8 recipient, uint256 value) = decodeConfig( + swap.config + ); - if (expiry < block.timestamp) revert InvalidExpiry(); + if (expiry < block.timestamp && (value == 0 || recipient > 0)) { + revert InvalidExpiry(); + } _swaps[swapId].config = 0; - if (value > 0) _payNativeEth(msg.sender, value * 1e12); + if (value > 0 && recipient == 0) { + _payNativeEth(msg.sender, value * 1e12); + } emit SwapCanceled(swapId, msg.sender); } diff --git a/test/TestSwaplace.test.ts b/test/TestSwaplace.test.ts index 9b86dfb..13be114 100644 --- a/test/TestSwaplace.test.ts +++ b/test/TestSwaplace.test.ts @@ -1099,6 +1099,146 @@ describe("Swaplace", async function () { balanceAfter.add(gasPrice.mul(gasUsed)), ); }); + + it("Should be able to {cancelSwap} and return ethers to {owner} even after expiration", async function () { + const bidingAddr = [MockERC20.address]; + const bidingAmountOrId = [50]; + + const askingAddr = [ + MockERC20.address, + MockERC20.address, + MockERC20.address, + ]; + const askingAmountOrId = [50, 100, 150]; + + const valueToSend: BigNumber = ethers.utils.parseEther("0.5"); + + const currentTimestamp = (await blocktimestamp()) + 1000000; + const config = await Swaplace.encodeConfig( + zeroAddress, + currentTimestamp, + 0, + valueToSend.div(1e12), + ); + + const swap: Swap = await composeSwap( + owner.address, + config, + bidingAddr, + bidingAmountOrId, + askingAddr, + askingAmountOrId, + ); + + await expect( + await Swaplace.connect(owner).createSwap(swap, { + value: valueToSend, + }), + ) + .to.emit(Swaplace, "SwapCreated") + .withArgs(await Swaplace.totalSwaps(), owner.address, zeroAddress); + + await network.provider.send("evm_increaseTime", [1000000]); + + const balanceBefore = await owner.getBalance(); + + const lastSwap = await Swaplace.totalSwaps(); + const tx = await Swaplace.connect(owner).cancelSwap(lastSwap); + const receipt = await tx.wait(); + const gasUsed = receipt.gasUsed; + const gasPrice = receipt.effectiveGasPrice; + + const balanceAfter = await owner.getBalance(); + expect(balanceBefore.add(valueToSend)).to.be.equals( + balanceAfter.add(gasPrice.mul(gasUsed)), + ); + }); + + it("Should be able to {cancelSwap} before expiration if the recipient is the {owner}", async function () { + const bidingAddr = [MockERC20.address]; + const bidingAmountOrId = [50]; + + const askingAddr = [ + MockERC20.address, + MockERC20.address, + MockERC20.address, + ]; + const askingAmountOrId = [50, 100, 150]; + + const valueToSend: BigNumber = ethers.utils.parseEther("0.5"); + + const currentTimestamp = (await blocktimestamp()) + 1000000; + const config = await Swaplace.encodeConfig( + zeroAddress, + currentTimestamp, + 1, + valueToSend.div(1e12), + ); + + const swap: Swap = await composeSwap( + owner.address, + config, + bidingAddr, + bidingAmountOrId, + askingAddr, + askingAmountOrId, + ); + + await expect(await Swaplace.connect(owner).createSwap(swap)) + .to.emit(Swaplace, "SwapCreated") + .withArgs(await Swaplace.totalSwaps(), owner.address, zeroAddress); + + const lastSwap = await Swaplace.totalSwaps(); + await expect(await Swaplace.connect(owner).cancelSwap(lastSwap)) + .to.emit(Swaplace, "SwapCanceled") + .withArgs(lastSwap, owner.address); + + await expect( + Swaplace.connect(owner).cancelSwap(lastSwap), + ).to.be.revertedWithCustomError(Swaplace, `InvalidExpiry`); + }); + + it("Should not be able to {cancelSwap} after expiration if the recipient is the {owner}", async function () { + const bidingAddr = [MockERC20.address]; + const bidingAmountOrId = [50]; + + const askingAddr = [ + MockERC20.address, + MockERC20.address, + MockERC20.address, + ]; + const askingAmountOrId = [50, 100, 150]; + + const valueToSend: BigNumber = ethers.utils.parseEther("0.5"); + + const currentTimestamp = (await blocktimestamp()) + 1000000; + const config = await Swaplace.encodeConfig( + zeroAddress, + currentTimestamp, + 1, + valueToSend.div(1e12), + ); + + const swap: Swap = await composeSwap( + owner.address, + config, + bidingAddr, + bidingAmountOrId, + askingAddr, + askingAmountOrId, + ); + + await expect(await Swaplace.connect(owner).createSwap(swap)) + .to.emit(Swaplace, "SwapCreated") + .withArgs(await Swaplace.totalSwaps(), owner.address, zeroAddress); + + await network.provider.send("evm_increaseTime", [1000000]); + + const lastSwap = await Swaplace.totalSwaps(); + await expect( + Swaplace.connect(owner).cancelSwap(lastSwap), + ).to.be.revertedWithCustomError(Swaplace, `InvalidExpiry`); + }); }); context("Reverts when canceling Swaps", () => {