diff --git a/test/abstract/FlowTransferOperation.sol b/test/abstract/FlowTransferOperation.sol index 6d6bf2e2..b14d535a 100644 --- a/test/abstract/FlowTransferOperation.sol +++ b/test/abstract/FlowTransferOperation.sol @@ -32,6 +32,54 @@ abstract contract FlowTransferOperation is Test { return FlowTransferV1(new ERC20Transfer[](0), new ERC721Transfer[](0), new ERC1155Transfer[](0)); } + /// Builds a `FlowTransferV1` whose first ERC20 transfer has an + /// unauthorized `from` (neither the flow contract nor the caller) and + /// whose second is a valid self-flow. Used to test the + /// `UnsupportedERC20Flow` revert path on a multi-transfer batch. + //forge-lint: disable-next-line(mixed-case-function) + function unauthorizedERC20Flow(address unauthorized, address authorized, address flow, uint256 amount) + internal + view + returns (FlowTransferV1 memory) + { + ERC20Transfer[] memory erc20Transfers = new ERC20Transfer[](2); + erc20Transfers[0] = ERC20Transfer({token: TOKEN_A, from: unauthorized, to: flow, amount: amount}); + erc20Transfers[1] = ERC20Transfer({token: TOKEN_B, from: flow, to: authorized, amount: amount}); + return FlowTransferV1(erc20Transfers, new ERC721Transfer[](0), new ERC1155Transfer[](0)); + } + + /// Same shape as `unauthorizedERC20Flow` but for ERC721. + //forge-lint: disable-next-line(mixed-case-function) + function unauthorizedERC721Flow(address unauthorized, address authorized, address flow, uint256 tokenId) + internal + view + returns (FlowTransferV1 memory) + { + ERC721Transfer[] memory erc721Transfers = new ERC721Transfer[](2); + erc721Transfers[0] = ERC721Transfer({token: TOKEN_A, from: unauthorized, to: flow, id: tokenId}); + erc721Transfers[1] = ERC721Transfer({token: TOKEN_B, from: flow, to: authorized, id: tokenId}); + return FlowTransferV1(new ERC20Transfer[](0), erc721Transfers, new ERC1155Transfer[](0)); + } + + /// Same shape as `unauthorizedERC20Flow` but for ERC1155. + //forge-lint: disable-next-line(mixed-case-function) + function unauthorizedERC1155Flow( + address unauthorized, + address authorized, + address flow, + uint256 outId, + uint256 outAmount, + uint256 inId, + uint256 inAmount + ) internal view returns (FlowTransferV1 memory) { + ERC1155Transfer[] memory erc1155Transfers = new ERC1155Transfer[](2); + erc1155Transfers[0] = + ERC1155Transfer({token: TOKEN_A, from: unauthorized, to: flow, id: outId, amount: outAmount}); + erc1155Transfers[1] = + ERC1155Transfer({token: TOKEN_B, from: flow, to: authorized, id: inId, amount: inAmount}); + return FlowTransferV1(new ERC20Transfer[](0), new ERC721Transfer[](0), erc1155Transfers); + } + //forge-lint: disable-next-line(mixed-case-function) function transferERC721ToERC1155( address addressA, diff --git a/test/src/concrete/Flow.transfer.t.sol b/test/src/concrete/Flow.transfer.t.sol index 50c6e581..4035f580 100644 --- a/test/src/concrete/Flow.transfer.t.sol +++ b/test/src/concrete/Flow.transfer.t.sol @@ -182,13 +182,7 @@ contract FlowTransferTest is FlowTest { assumeEtchable(bob, address(flow)); { - ERC20Transfer[] memory erc20Transfers = new ERC20Transfer[](2); - erc20Transfers[0] = ERC20Transfer({token: TOKEN_A, from: bob, to: address(flow), amount: erc20Amount}); - erc20Transfers[1] = ERC20Transfer({token: TOKEN_B, from: address(flow), to: alice, amount: erc20Amount}); - - uint256[] memory stack = - generateFlowStack(FlowTransferV1(erc20Transfers, new ERC721Transfer[](0), new ERC1155Transfer[](0))); - + uint256[] memory stack = generateFlowStack(unauthorizedERC20Flow(bob, alice, address(flow), erc20Amount)); interpreterEval2MockCall(stack, new uint256[](0)); } @@ -232,13 +226,8 @@ contract FlowTransferTest is FlowTest { assumeEtchable(bob, address(flow)); { - ERC721Transfer[] memory erc721Transfers = new ERC721Transfer[](2); - erc721Transfers[0] = ERC721Transfer({token: TOKEN_A, from: bob, to: address(flow), id: erc721TokenId}); - erc721Transfers[1] = ERC721Transfer({token: TOKEN_B, from: address(flow), to: alice, id: erc721TokenId}); - uint256[] memory stack = - generateFlowStack(FlowTransferV1(new ERC20Transfer[](0), erc721Transfers, new ERC1155Transfer[](0))); - + generateFlowStack(unauthorizedERC721Flow(bob, alice, address(flow), erc721TokenId)); interpreterEval2MockCall(stack, new uint256[](0)); } @@ -271,18 +260,11 @@ contract FlowTransferTest is FlowTest { assumeEtchable(bob, address(flow)); { - ERC1155Transfer[] memory erc1155Transfers = new ERC1155Transfer[](2); - erc1155Transfers[0] = ERC1155Transfer({ - token: TOKEN_A, from: bob, to: address(flow), id: erc1155OutTokenId, amount: erc1155OutAmount - }); - - erc1155Transfers[1] = ERC1155Transfer({ - token: TOKEN_B, from: address(flow), to: alice, id: erc1155InTokenId, amount: erc1155InAmount - }); - - uint256[] memory stack = - generateFlowStack(FlowTransferV1(new ERC20Transfer[](0), new ERC721Transfer[](0), erc1155Transfers)); - + uint256[] memory stack = generateFlowStack( + unauthorizedERC1155Flow( + bob, alice, address(flow), erc1155OutTokenId, erc1155OutAmount, erc1155InTokenId, erc1155InAmount + ) + ); interpreterEval2MockCall(stack, new uint256[](0)); }