From 4b5fab70ea25bfee329389218aaaea7de81b728e Mon Sep 17 00:00:00 2001 From: teddy Date: Tue, 23 Jul 2024 06:31:48 -0300 Subject: [PATCH] feat: add btt for isValidSignature (#161) * test: btt tests for bpool.swapExactAmountIn * chore: delete preexisting unit tests * test: small renames from feedback * test: be explicit about untestable code * test: adding skipped test for unreachable condition * test: code wasnt so unreachable after all * refactor: get rid of _setRecord * test: btt tests for bcowpool.verify * chore: delete preexisting unit tests * chore: testcase renaming from review * chore: get rid of _setTokens altogether * test: fuzz all possible valid order.sellAmount values * chore: rename correctOrder -> validOrder * test: btt tests for bcowpool.isValidSignature * chore: remove preexisting unit tests replaced by ones in this pr * fix: more descriptive tree --- test/unit/BCoWPool.t.sol | 70 ------------------- .../BCoWPool/BCoWPool_IsValidSignature.t.sol | 56 +++++++++++++++ .../BCoWPool/BCoWPool_IsValidSignature.tree | 10 +++ 3 files changed, 66 insertions(+), 70 deletions(-) create mode 100644 test/unit/BCoWPool/BCoWPool_IsValidSignature.t.sol create mode 100644 test/unit/BCoWPool/BCoWPool_IsValidSignature.tree diff --git a/test/unit/BCoWPool.t.sol b/test/unit/BCoWPool.t.sol index 722780ce..7d448ae6 100644 --- a/test/unit/BCoWPool.t.sol +++ b/test/unit/BCoWPool.t.sol @@ -77,73 +77,3 @@ contract BCoWPool_Unit_Constructor is BaseCoWPoolTest { assertEq(pool.APP_DATA(), _appData); } } - -contract BCoWPool_Unit_IsValidSignature is BaseCoWPoolTest { - function setUp() public virtual override { - super.setUp(); - for (uint256 i = 0; i < TOKENS_AMOUNT; i++) { - vm.mockCall(tokens[i], abi.encodePacked(IERC20.approve.selector), abi.encode(true)); - } - vm.mockCall(address(bCoWPool.FACTORY()), abi.encodeWithSelector(IBCoWFactory.logBCoWPool.selector), abi.encode()); - bCoWPool.finalize(); - } - - modifier happyPath(GPv2Order.Data memory _order) { - // sets the order appData to the one defined at deployment (setUp) - _order.appData = appData; - - // stores the order hash in the transient storage slot - bytes32 _orderHash = GPv2Order.hash(_order, domainSeparator); - bCoWPool.call__setLock(_orderHash); - _; - } - - function test_Revert_OrderWithWrongAppdata(GPv2Order.Data memory _order, bytes32 _appData) public { - vm.assume(_appData != appData); - _order.appData = _appData; - bytes32 _orderHash = GPv2Order.hash(_order, domainSeparator); - vm.expectRevert(IBCoWPool.AppDataDoesNotMatch.selector); - bCoWPool.isValidSignature(_orderHash, abi.encode(_order)); - } - - function test_Revert_OrderSignedWithWrongDomainSeparator( - GPv2Order.Data memory _order, - bytes32 _differentDomainSeparator - ) public happyPath(_order) { - vm.assume(_differentDomainSeparator != domainSeparator); - bytes32 _orderHash = GPv2Order.hash(_order, _differentDomainSeparator); - vm.expectRevert(IBCoWPool.OrderDoesNotMatchMessageHash.selector); - bCoWPool.isValidSignature(_orderHash, abi.encode(_order)); - } - - function test_Revert_OrderWithUnrelatedSignature( - GPv2Order.Data memory _order, - bytes32 _orderHash - ) public happyPath(_order) { - vm.expectRevert(IBCoWPool.OrderDoesNotMatchMessageHash.selector); - bCoWPool.isValidSignature(_orderHash, abi.encode(_order)); - } - - function test_Revert_OrderHashDifferentFromCommitment( - GPv2Order.Data memory _order, - bytes32 _differentCommitment - ) public happyPath(_order) { - bCoWPool.call__setLock(_differentCommitment); - bytes32 _orderHash = GPv2Order.hash(_order, domainSeparator); - vm.expectRevert(IBCoWPool.OrderDoesNotMatchCommitmentHash.selector); - bCoWPool.isValidSignature(_orderHash, abi.encode(_order)); - } - - function test_Call_Verify(GPv2Order.Data memory _order) public happyPath(_order) { - bytes32 _orderHash = GPv2Order.hash(_order, domainSeparator); - bCoWPool.mock_call_verify(_order); - bCoWPool.expectCall_verify(_order); - bCoWPool.isValidSignature(_orderHash, abi.encode(_order)); - } - - function test_Return_MagicValue(GPv2Order.Data memory _order) public happyPath(_order) { - bytes32 _orderHash = GPv2Order.hash(_order, domainSeparator); - bCoWPool.mock_call_verify(_order); - assertEq(bCoWPool.isValidSignature(_orderHash, abi.encode(_order)), IERC1271.isValidSignature.selector); - } -} diff --git a/test/unit/BCoWPool/BCoWPool_IsValidSignature.t.sol b/test/unit/BCoWPool/BCoWPool_IsValidSignature.t.sol new file mode 100644 index 00000000..aeb8086b --- /dev/null +++ b/test/unit/BCoWPool/BCoWPool_IsValidSignature.t.sol @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.25; + +import {IERC20} from '@cowprotocol/interfaces/IERC20.sol'; + +import {GPv2Order} from '@cowprotocol/libraries/GPv2Order.sol'; +import {IERC1271} from '@openzeppelin/contracts/interfaces/IERC1271.sol'; + +import {BCoWPoolBase} from './BCoWPoolBase.sol'; +import {IBCoWPool} from 'interfaces/IBCoWPool.sol'; + +contract BCoWPoolIsValidSignature is BCoWPoolBase { + GPv2Order.Data validOrder; + bytes32 validHash; + + function setUp() public virtual override { + super.setUp(); + // only set up the values that are checked in this method + validOrder.appData = appData; + validHash = GPv2Order.hash(validOrder, domainSeparator); + + bCoWPool.mock_call_verify(validOrder); + } + + function test_RevertWhen_OrdersAppdataIsDifferentThanOneSetAtConstruction(bytes32 appData_) external { + vm.assume(appData != appData_); + validOrder.appData = appData_; + // it should revert + vm.expectRevert(IBCoWPool.AppDataDoesNotMatch.selector); + bCoWPool.isValidSignature(validHash, abi.encode(validOrder)); + } + + function test_RevertWhen_OrderHashDoesNotMatchHashedOrder(bytes32 orderHash) external { + vm.assume(orderHash != validHash); + // it should revert + vm.expectRevert(IBCoWPool.OrderDoesNotMatchMessageHash.selector); + bCoWPool.isValidSignature(orderHash, abi.encode(validOrder)); + } + + function test_RevertWhen_HashedOrderDoesNotMatchCommitment(bytes32 commitment) external { + vm.assume(validHash != commitment); + bCoWPool.call__setLock(commitment); + // it should revert + vm.expectRevert(IBCoWPool.OrderDoesNotMatchCommitmentHash.selector); + bCoWPool.isValidSignature(validHash, abi.encode(validOrder)); + } + + function test_WhenPreconditionsAreMet() external { + // can't do it in setUp because transient storage is wiped in between + bCoWPool.call__setLock(validHash); + // it calls verify + bCoWPool.expectCall_verify(validOrder); + // it returns EIP-1271 magic value + assertEq(bCoWPool.isValidSignature(validHash, abi.encode(validOrder)), IERC1271.isValidSignature.selector); + } +} diff --git a/test/unit/BCoWPool/BCoWPool_IsValidSignature.tree b/test/unit/BCoWPool/BCoWPool_IsValidSignature.tree new file mode 100644 index 00000000..524e8290 --- /dev/null +++ b/test/unit/BCoWPool/BCoWPool_IsValidSignature.tree @@ -0,0 +1,10 @@ +BCoWPool::IsValidSignature +├── when orders appdata is different than one set at construction +│ └── it should revert +├── when orderHash does not match hashed order +│ └── it should revert +├── when hashed order does not match commitment +│ └── it should revert +└── when preconditions are met + ├── it calls verify + └── it returns EIP-1271 magic value