diff --git a/test/abstract/FlowTransferOperation.sol b/test/abstract/FlowTransferOperation.sol index cd8edad5..8e68a954 100644 --- a/test/abstract/FlowTransferOperation.sol +++ b/test/abstract/FlowTransferOperation.sol @@ -32,6 +32,53 @@ 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 462f15b5..f07ea6e6 100644 --- a/test/src/concrete/Flow.transfer.t.sol +++ b/test/src/concrete/Flow.transfer.t.sol @@ -188,15 +188,9 @@ 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 = LibStackGeneration.generateFlowStack( - Sentinel.unwrap(RAIN_FLOW_SENTINEL), - FlowTransferV1(erc20Transfers, new ERC721Transfer[](0), new ERC1155Transfer[](0)) + Sentinel.unwrap(RAIN_FLOW_SENTINEL), unauthorizedERC20Flow(bob, alice, address(flow), erc20Amount) ); - interpreterEval2MockCall(stack, new uint256[](0)); } @@ -242,15 +236,9 @@ 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 = LibStackGeneration.generateFlowStack( - Sentinel.unwrap(RAIN_FLOW_SENTINEL), - FlowTransferV1(new ERC20Transfer[](0), erc721Transfers, new ERC1155Transfer[](0)) + Sentinel.unwrap(RAIN_FLOW_SENTINEL), unauthorizedERC721Flow(bob, alice, address(flow), erc721TokenId) ); - interpreterEval2MockCall(stack, new uint256[](0)); } @@ -283,20 +271,12 @@ 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 = LibStackGeneration.generateFlowStack( Sentinel.unwrap(RAIN_FLOW_SENTINEL), - FlowTransferV1(new ERC20Transfer[](0), new ERC721Transfer[](0), erc1155Transfers) + unauthorizedERC1155Flow( + bob, alice, address(flow), erc1155OutTokenId, erc1155OutAmount, erc1155InTokenId, erc1155InAmount + ) ); - interpreterEval2MockCall(stack, new uint256[](0)); }