diff --git a/test/GPv2Settlement.test.ts b/test/GPv2Settlement.test.ts deleted file mode 100644 index 2a0fbd36..00000000 --- a/test/GPv2Settlement.test.ts +++ /dev/null @@ -1,132 +0,0 @@ -import { expect } from "chai"; -import { MockContract } from "ethereum-waffle"; -import { Contract } from "ethers"; -import { artifacts, ethers, waffle } from "hardhat"; - -import { PRE_SIGNED, packOrderUidParams } from "../src/ts"; - -describe("GPv2Settlement", () => { - const [deployer, owner, ...traders] = waffle.provider.getWallets(); - - let authenticator: Contract; - let vault: MockContract; - let settlement: Contract; - - beforeEach(async () => { - const GPv2AllowListAuthentication = await ethers.getContractFactory( - "GPv2AllowListAuthentication", - deployer, - ); - authenticator = await GPv2AllowListAuthentication.deploy(); - await authenticator.initializeManager(owner.address); - - const IVault = await artifacts.readArtifact("IVault"); - vault = await waffle.deployMockContract(deployer, IVault.abi); - - const GPv2Settlement = await ethers.getContractFactory( - "GPv2SettlementTestInterface", - deployer, - ); - settlement = await GPv2Settlement.deploy( - authenticator.address, - vault.address, - ); - }); - - describe("Order Refunds", () => { - const orderUids = [ - packOrderUidParams({ - orderDigest: `0x${"11".repeat(32)}`, - owner: traders[0].address, - validTo: 0, - }), - packOrderUidParams({ - orderDigest: `0x${"22".repeat(32)}`, - owner: traders[0].address, - validTo: 0, - }), - packOrderUidParams({ - orderDigest: `0x${"33".repeat(32)}`, - owner: traders[0].address, - validTo: 0, - }), - ]; - - const commonTests = (freeStorageFunction: string) => { - const testFunction = `${freeStorageFunction}Test`; - - it("should revert if not called from an interaction", async () => { - await expect(settlement[freeStorageFunction]([])).to.be.revertedWith( - "not an interaction", - ); - }); - - it("should revert if the encoded order UIDs are malformed", async () => { - const orderUid = packOrderUidParams({ - orderDigest: ethers.constants.HashZero, - owner: ethers.constants.AddressZero, - validTo: 0, - }); - - for (const malformedOrderUid of [ - ethers.utils.hexDataSlice(orderUid, 0, 55), - ethers.utils.hexZeroPad(orderUid, 57), - ]) { - await expect( - settlement[testFunction]([malformedOrderUid]), - ).to.be.revertedWith("invalid uid"); - } - }); - - it("should revert if the order is still valid", async () => { - const orderUid = packOrderUidParams({ - orderDigest: `0x${"42".repeat(32)}`, - owner: traders[0].address, - validTo: 0xffffffff, - }); - - await expect(settlement[testFunction]([orderUid])).to.be.revertedWith( - "order still valid", - ); - }); - }; - - describe("freeFilledAmountStorage", () => { - it("should set filled amount to 0 for all orders", async () => { - for (const orderUid of orderUids) { - await settlement.connect(traders[0]).invalidateOrder(orderUid); - expect(await settlement.filledAmount(orderUid)).to.not.deep.equal( - ethers.constants.Zero, - ); - } - - await settlement.freeFilledAmountStorageTest(orderUids); - for (const orderUid of orderUids) { - expect(await settlement.filledAmount(orderUid)).to.equal( - ethers.constants.Zero, - ); - } - }); - - commonTests("freeFilledAmountStorage"); - }); - - describe("freePreSignatureStorage", () => { - it("should clear pre-signatures", async () => { - for (const orderUid of orderUids) { - await settlement.connect(traders[0]).setPreSignature(orderUid, true); - expect(await settlement.preSignature(orderUid)).to.equal(PRE_SIGNED); - } - - await settlement.freePreSignatureStorageTest(orderUids); - for (const orderUid of orderUids) { - expect(await settlement.preSignature(orderUid)).to.equal( - ethers.constants.Zero, - ); - } - }); - - commonTests("freePreSignatureStorage"); - }); - }); -}); diff --git a/test/GPv2Settlement/OrderRefunds.t.sol b/test/GPv2Settlement/OrderRefunds.t.sol new file mode 100644 index 00000000..31a5ebcb --- /dev/null +++ b/test/GPv2Settlement/OrderRefunds.t.sol @@ -0,0 +1,117 @@ +// SPDX-License-Identifier: LGPL-3.0-or-later +pragma solidity ^0.8; + +import {GPv2Order} from "src/contracts/libraries/GPv2Order.sol"; + +import {Helper} from "./Helper.sol"; +import {Order} from "test/libraries/Order.sol"; + +enum FreeFunctionVariant { + FreeFilledAmountStorage, + FreePreSignatureStorage +} + +abstract contract Variant is Helper { + FreeFunctionVariant internal immutable freeFn; + + constructor(FreeFunctionVariant _freeFn) { + freeFn = _freeFn; + } + + function defaultOrderUids() internal view returns (bytes[] memory orderUids) { + orderUids = new bytes[](3); + orderUids[0] = Order.computeOrderUid(keccak256("order1"), trader.addr, 0); + orderUids[1] = Order.computeOrderUid(keccak256("order2"), trader.addr, 0); + orderUids[2] = Order.computeOrderUid(keccak256("order3"), trader.addr, 0); + } + + function freeFunctionCall(bytes[] memory orderUids) private { + if (freeFn == FreeFunctionVariant.FreeFilledAmountStorage) { + settlement.freeFilledAmountStorage(orderUids); + } else if (freeFn == FreeFunctionVariant.FreePreSignatureStorage) { + settlement.freePreSignatureStorage(orderUids); + } else { + revert("Invalid free function"); + } + } + + function freeFunctionCallTest(bytes[] memory orderUids) private { + if (freeFn == FreeFunctionVariant.FreeFilledAmountStorage) { + settlement.freeFilledAmountStorageTest(orderUids); + } else if (freeFn == FreeFunctionVariant.FreePreSignatureStorage) { + settlement.freePreSignatureStorageTest(orderUids); + } else { + revert("Invalid free function"); + } + } + + function test_should_revert_if_not_called_from_an_interaction() public { + bytes[] memory emptyOrderUids = new bytes[](0); + + vm.expectRevert("GPv2: not an interaction"); + freeFunctionCall(emptyOrderUids); + } + + function test_should_revert_if_the_encoded_order_uid_are_malformed() public { + bytes memory orderUidLt = new bytes(GPv2Order.UID_LENGTH - 1); + bytes memory orderUidGt = new bytes(GPv2Order.UID_LENGTH + 1); + + checkInvalidLength(orderUidLt); + checkInvalidLength(orderUidGt); + } + + function test_should_revert_if_order_is_still_valid() public { + bytes[] memory orderUids = new bytes[](1); + orderUids[0] = Order.computeOrderUid(keccak256("order0"), trader.addr, type(uint32).max); + + vm.expectRevert("GPv2: order still valid"); + freeFunctionCallTest(orderUids); + } + + function checkInvalidLength(bytes memory orderUid) private { + bytes[] memory orderUids = new bytes[](1); + orderUids[0] = orderUid; + vm.expectRevert("GPv2: invalid uid"); + freeFunctionCallTest(orderUids); + } +} + +contract FreeFilledAmountStorage is Variant(FreeFunctionVariant.FreeFilledAmountStorage) { + function test_should_set_filled_amount_to_0_for_all_orders() public { + bytes[] memory orderUids = defaultOrderUids(); + + for (uint256 i = 0; i < orderUids.length; i++) { + vm.prank(trader.addr); + settlement.invalidateOrder(orderUids[i]); + assertEq(settlement.filledAmount(orderUids[i]), type(uint256).max, "filledAmount should be set to max"); + } + + settlement.freeFilledAmountStorageTest(orderUids); + + for (uint256 i = 0; i < orderUids.length; i++) { + assertEq(settlement.filledAmount(orderUids[i]), 0, "filledAmount should be set to 0"); + } + } +} + +contract FreePreSignatureStorage is Variant(FreeFunctionVariant.FreePreSignatureStorage) { + function test_should_clear_pre_signatures() public { + bytes[] memory orderUids = defaultOrderUids(); + + for (uint256 i = 0; i < orderUids.length; i++) { + vm.prank(trader.addr); + settlement.setPreSignature(orderUids[i], true); + assertEq( + settlement.preSignature(orderUids[i]), + uint256(keccak256("GPv2Signing.Scheme.PreSign")), + "preSignature not set" + ); + } + + settlement.freePreSignatureStorageTest(orderUids); + + for (uint256 i = 0; i < orderUids.length; i++) { + assertEq(settlement.preSignature(orderUids[i]), uint256(0), "preSignature should be set to 0"); + } + } +}