From ef3215b137272f38368448f6beaf663eb4109749 Mon Sep 17 00:00:00 2001 From: ninokeldishvili Date: Wed, 4 Sep 2024 18:06:57 +0400 Subject: [PATCH 1/9] Remove duplicate functions --- test/abstract/FlowERC1155Test.sol | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/test/abstract/FlowERC1155Test.sol b/test/abstract/FlowERC1155Test.sol index 7e45440f..5aabd418 100644 --- a/test/abstract/FlowERC1155Test.sol +++ b/test/abstract/FlowERC1155Test.sol @@ -23,21 +23,6 @@ abstract contract FlowERC1155Test is FlowBasicTest { vm.resumeGasMetering(); } - function expressionDeployer(address expression, uint256[] memory constants, bytes memory bytecode) - internal - returns (EvaluableConfigV3 memory) - { - expressionDeployerDeployExpression2MockCall(bytecode, constants, expression, bytes(hex"0006")); - return EvaluableConfigV3(iDeployer, bytecode, constants); - } - - function expressionDeployer(uint256 key, address expression, uint256[] memory constants) - internal - returns (EvaluableConfigV3 memory) - { - return expressionDeployer(expression, constants, abi.encodePacked(vm.addr(key))); - } - function deployIFlowERC1155V5(string memory uri) internal returns (IFlowERC1155V5 flowErc1155, EvaluableV2 memory evaluable) From 8554fbb4ec66e9827676d253eb0d82cab8879d99 Mon Sep 17 00:00:00 2001 From: ninokeldishvili Date: Thu, 5 Sep 2024 11:25:19 +0400 Subject: [PATCH 2/9] Add alice address check to prevent it being a contract --- test/concrete/flowErc1155/FlowTest.sol | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/test/concrete/flowErc1155/FlowTest.sol b/test/concrete/flowErc1155/FlowTest.sol index c5cc4999..ec41216c 100644 --- a/test/concrete/flowErc1155/FlowTest.sol +++ b/test/concrete/flowErc1155/FlowTest.sol @@ -13,15 +13,27 @@ import {IInterpreterV2, DEFAULT_STATE_NAMESPACE} from "rain.interpreter.interfac import {IInterpreterStoreV2} from "rain.interpreter.interface/interface/IInterpreterStoreV2.sol"; import {FlowTransferV1, ERC20Transfer, ERC721Transfer, ERC1155Transfer} from "src/interface/unstable/IFlowV5.sol"; import { - IFlowERC1155V5, ERC1155SupplyChange, FlowERC1155IOV1 + IFlowERC1155V5, + ERC1155SupplyChange, + FlowERC1155IOV1, + FLOW_ERC1155_HANDLE_TRANSFER_ENTRYPOINT, + FLOW_ERC1155_HANDLE_TRANSFER_MAX_OUTPUTS } from "../../../src/interface/unstable/IFlowERC1155V5.sol"; import {FlowERC1155Test} from "test/abstract/FlowERC1155Test.sol"; import {IFlowERC1155V5} from "../../../src/interface/unstable/IFlowERC1155V5.sol"; +import {Address} from "openzeppelin-contracts/contracts/utils/Address.sol"; import {SignContextLib} from "test/lib/SignContextLib.sol"; +import {LibUint256Array} from "rain.solmem/lib/LibUint256Array.sol"; +import {LibUint256Matrix} from "rain.solmem/lib/LibUint256Matrix.sol"; +import {LibContextWrapper} from "test/lib/LibContextWrapper.sol"; +import {LibEncodedDispatch} from "rain.interpreter.interface/lib/caller/LibEncodedDispatch.sol"; contract Erc1155FlowTest is FlowERC1155Test { using LibEvaluable for EvaluableV2; using SignContextLib for Vm; + using Address for address; + using LibUint256Matrix for uint256[]; + using LibUint256Array for uint256[]; function testFlowERC1155FlowERC20ToERC20( uint256 erc20OutAmmount, @@ -257,6 +269,7 @@ contract Erc1155FlowTest is FlowERC1155Test { vm.assume(sentinel != amount); vm.assume(expressionA != expressionB); vm.assume(writeToStore.length != 0); + vm.assume(!alice.isContract()); address[] memory expressions = new address[](1); expressions[0] = expressionA; From b5c717284321f37b73ad528d320f4b26a81c5c60 Mon Sep 17 00:00:00 2001 From: ninokeldishvili Date: Thu, 5 Sep 2024 15:59:14 +0400 Subject: [PATCH 3/9] Failing test testFlowERC1155SupportsTransferPreflightHook --- test/concrete/flowErc1155/FlowTest.sol | 78 ++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/test/concrete/flowErc1155/FlowTest.sol b/test/concrete/flowErc1155/FlowTest.sol index ec41216c..6a79740d 100644 --- a/test/concrete/flowErc1155/FlowTest.sol +++ b/test/concrete/flowErc1155/FlowTest.sol @@ -35,6 +35,84 @@ contract Erc1155FlowTest is FlowERC1155Test { using LibUint256Matrix for uint256[]; using LibUint256Array for uint256[]; + function testFlowERC1155SupportsTransferPreflightHook( + address alice, + uint128 amount, + uint128 id, + address expressionA, + address expressionB, + string memory uri + ) external { + vm.assume(alice != address(0)); + vm.assume(sentinel != amount); + vm.assume(expressionA != expressionB); + + address[] memory expressions = new address[](1); + expressions[0] = expressionA; + + (IFlowERC1155V5 flow, EvaluableV2[] memory evaluables) = + deployIFlowERC1155V5(expressions, expressionB, new uint256[][](1), uri); + assumeEtchable(alice, address(flow)); + + { + ERC1155SupplyChange[] memory mints = new ERC1155SupplyChange[](1); + mints[0] = ERC1155SupplyChange({account: alice, id: id, amount: amount}); + + ERC1155SupplyChange[] memory burns = new ERC1155SupplyChange[](1); + burns[0] = ERC1155SupplyChange({account: alice, id: id, amount: amount}); + + uint256[] memory stack = generateFlowStack( + FlowERC1155IOV1( + mints, + burns, + FlowTransferV1(new ERC20Transfer[](0), new ERC721Transfer[](0), new ERC1155Transfer[](0)) + ) + ); + interpreterEval2MockCall(stack, new uint256[](0)); + } + + uint256[][] memory context = LibContextWrapper.buildAndSetContext( + LibUint256Array.arrayFrom(uint256(uint160(address(alice))), uint256(uint160(address(flow))), amount) + .matrixFrom(), + new SignedContextV1[](0), + address(alice), + address(flow) + ); + + { + interpreterEval2ExpectCall( + address(flow), + LibEncodedDispatch.encode2( + expressionB, FLOW_ERC1155_HANDLE_TRANSFER_ENTRYPOINT, FLOW_ERC1155_HANDLE_TRANSFER_MAX_OUTPUTS + ), + context + ); + + flow.flow(evaluables[0], new uint256[](0), new SignedContextV1[](0)); + + vm.startPrank(alice); + IERC1155(address(flow)).safeTransferFrom(alice, address(flow), id, amount, ""); + vm.stopPrank(); + } + + { + interpreterEval2RevertCall( + address(flow), + LibEncodedDispatch.encode2( + expressionB, FLOW_ERC1155_HANDLE_TRANSFER_ENTRYPOINT, FLOW_ERC1155_HANDLE_TRANSFER_MAX_OUTPUTS + ), + context + ); + + flow.flow(evaluables[0], new uint256[](0), new SignedContextV1[](0)); + + vm.startPrank(alice); + vm.expectRevert("REVERT_EVAL2_CALL"); + IERC1155(address(flow)).transfer(address(flow), amount); + vm.stopPrank(); + } + } + function testFlowERC1155FlowERC20ToERC20( uint256 erc20OutAmmount, uint256 erc20BInAmmount, From f50b84f8085d375a9fd97684eda9dc92276b57c9 Mon Sep 17 00:00:00 2001 From: ninokeldishvili Date: Tue, 10 Sep 2024 11:51:13 +0400 Subject: [PATCH 4/9] Add address checks and change transfer to safetransfer --- test/concrete/flowErc1155/FlowTest.sol | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/concrete/flowErc1155/FlowTest.sol b/test/concrete/flowErc1155/FlowTest.sol index 2fbc59ab..100ba7f7 100644 --- a/test/concrete/flowErc1155/FlowTest.sol +++ b/test/concrete/flowErc1155/FlowTest.sol @@ -31,9 +31,9 @@ import {LibEncodedDispatch} from "rain.interpreter.interface/lib/caller/LibEncod contract Erc1155FlowTest is FlowERC1155Test { using LibEvaluable for EvaluableV2; using SignContextLib for Vm; - using Address for address; using LibUint256Matrix for uint256[]; using LibUint256Array for uint256[]; + using Address for address; function testFlowERC1155SupportsTransferPreflightHook( address alice, @@ -46,6 +46,7 @@ contract Erc1155FlowTest is FlowERC1155Test { vm.assume(alice != address(0)); vm.assume(sentinel != amount); vm.assume(expressionA != expressionB); + vm.assume(!alice.isContract()); address[] memory expressions = new address[](1); expressions[0] = expressionA; @@ -108,7 +109,7 @@ contract Erc1155FlowTest is FlowERC1155Test { vm.startPrank(alice); vm.expectRevert("REVERT_EVAL2_CALL"); - IERC1155(address(flow)).transfer(address(flow), amount); + IERC1155(address(flow)).safeTransferFrom(alice, address(flow), id, amount, ""); vm.stopPrank(); } } @@ -126,6 +127,7 @@ contract Erc1155FlowTest is FlowERC1155Test { vm.assume(sentinel != erc1155OutTokenId); vm.assume(sentinel != erc1155OutAmmount); vm.assume(address(0) != alice); + vm.assume(!alice.isContract()); vm.label(alice, "Alice"); From 8d558ff35ce8588f5987107eb3b33da48c534c8c Mon Sep 17 00:00:00 2001 From: ninokeldishvili Date: Fri, 13 Sep 2024 12:27:14 +0400 Subject: [PATCH 5/9] Fix failing testFlowERC1155FlowERC721ToERC721 --- test/concrete/flowErc1155/FlowTest.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/concrete/flowErc1155/FlowTest.sol b/test/concrete/flowErc1155/FlowTest.sol index 06b5b1e7..5b48cdd1 100644 --- a/test/concrete/flowErc1155/FlowTest.sol +++ b/test/concrete/flowErc1155/FlowTest.sol @@ -283,7 +283,7 @@ contract Erc1155FlowTest is FlowERC1155Test { mints[0] = ERC1155SupplyChange({account: alice, id: erc721InTokenId, amount: amount}); ERC1155SupplyChange[] memory burns = new ERC1155SupplyChange[](1); - burns[0] = ERC1155SupplyChange({account: alice, id: erc721InTokenId, amount: 0 ether}); + burns[0] = ERC1155SupplyChange({account: alice, id: erc721InTokenId, amount: amount}); uint256[] memory stack = generateFlowStack( FlowERC1155IOV1( From 74d83306bda45c5d89b1396ef6be9f5774787f06 Mon Sep 17 00:00:00 2001 From: ninokeldishvili Date: Tue, 17 Sep 2024 08:46:54 +0400 Subject: [PATCH 6/9] Remove burns. add different token id-s and amounts --- test/concrete/flowErc1155/FlowTest.sol | 70 ++++++++++++++------------ 1 file changed, 38 insertions(+), 32 deletions(-) diff --git a/test/concrete/flowErc1155/FlowTest.sol b/test/concrete/flowErc1155/FlowTest.sol index b11254af..c264d48e 100644 --- a/test/concrete/flowErc1155/FlowTest.sol +++ b/test/concrete/flowErc1155/FlowTest.sol @@ -37,14 +37,14 @@ contract Erc1155FlowTest is FlowERC1155Test { function testFlowERC1155SupportsTransferPreflightHook( address alice, - uint128 amount, - uint128 id, + uint256 tokenIdA, + uint256 tokenIdB, + uint256 amountA, + uint256 amountB, address expressionA, - address expressionB, - string memory uri + address expressionB ) external { vm.assume(alice != address(0)); - vm.assume(sentinel != amount); vm.assume(expressionA != expressionB); vm.assume(!alice.isContract()); @@ -52,64 +52,70 @@ contract Erc1155FlowTest is FlowERC1155Test { expressions[0] = expressionA; (IFlowERC1155V5 flow, EvaluableV2[] memory evaluables) = - deployIFlowERC1155V5(expressions, expressionB, new uint256[][](1), uri); + deployIFlowERC1155V5(expressions, expressionB, new uint256[][](1), "uri"); assumeEtchable(alice, address(flow)); + // Mint tokens to Alice { - ERC1155SupplyChange[] memory mints = new ERC1155SupplyChange[](1); - mints[0] = ERC1155SupplyChange({account: alice, id: id, amount: amount}); - - ERC1155SupplyChange[] memory burns = new ERC1155SupplyChange[](1); - burns[0] = ERC1155SupplyChange({account: alice, id: id, amount: amount}); + ERC1155SupplyChange[] memory mints = new ERC1155SupplyChange[](2); + mints[0] = ERC1155SupplyChange({account: alice, id: tokenIdA, amount: amountA}); + mints[1] = ERC1155SupplyChange({account: alice, id: tokenIdB, amount: amountB}); uint256[] memory stack = generateFlowStack( FlowERC1155IOV1( mints, - burns, + new ERC1155SupplyChange[](0), FlowTransferV1(new ERC20Transfer[](0), new ERC721Transfer[](0), new ERC1155Transfer[](0)) ) ); interpreterEval2MockCall(stack, new uint256[](0)); } - uint256[][] memory context = LibContextWrapper.buildAndSetContext( - LibUint256Array.arrayFrom(uint256(uint160(address(alice))), uint256(uint160(address(flow))), amount) - .matrixFrom(), + // Attempt a token transfer + uint256[][] memory contextTransferA = LibContextWrapper.buildAndSetContext( + LibUint256Array.arrayFrom( + uint256(uint160(address(alice))), uint256(uint160(address(flow))), tokenIdA, amountA + ).matrixFrom(), new SignedContextV1[](0), address(alice), address(flow) ); - { - interpreterEval2ExpectCall( - address(flow), - LibEncodedDispatch.encode2( - expressionB, FLOW_ERC1155_HANDLE_TRANSFER_ENTRYPOINT, FLOW_ERC1155_HANDLE_TRANSFER_MAX_OUTPUTS - ), - context - ); + // Expect call token transfer + interpreterEval2ExpectCall( + address(flow), + LibEncodedDispatch.encode2( + expressionB, FLOW_ERC1155_HANDLE_TRANSFER_ENTRYPOINT, FLOW_ERC1155_HANDLE_TRANSFER_MAX_OUTPUTS + ), + contextTransferA + ); - flow.flow(evaluables[0], new uint256[](0), new SignedContextV1[](0)); + flow.flow(evaluables[0], new uint256[](0), new SignedContextV1[](0)); - vm.startPrank(alice); - IERC1155(address(flow)).safeTransferFrom(alice, address(flow), id, amount, ""); - vm.stopPrank(); - } + vm.startPrank(alice); + IERC1155(address(flow)).safeTransferFrom(alice, address(flow), tokenIdA, amountA, ""); + vm.stopPrank(); { + uint256[][] memory contextTransferB = LibContextWrapper.buildAndSetContext( + LibUint256Array.arrayFrom(uint256(uint160(address(alice))), uint256(uint160(address(flow))), tokenIdB) + .matrixFrom(), + new SignedContextV1[](0), + address(alice), + address(flow) + ); + interpreterEval2RevertCall( address(flow), LibEncodedDispatch.encode2( expressionB, FLOW_ERC1155_HANDLE_TRANSFER_ENTRYPOINT, FLOW_ERC1155_HANDLE_TRANSFER_MAX_OUTPUTS ), - context + contextTransferB ); - flow.flow(evaluables[0], new uint256[](0), new SignedContextV1[](0)); - vm.startPrank(alice); vm.expectRevert("REVERT_EVAL2_CALL"); - IERC1155(address(flow)).safeTransferFrom(alice, address(flow), id, amount, ""); + IERC1155(address(flow)).safeTransferFrom(alice, address(flow), tokenIdB, amountB, ""); vm.stopPrank(); } } From e503a3c56435fbe32bfaa79718676e7bdffc580f Mon Sep 17 00:00:00 2001 From: ninokeldishvili Date: Tue, 17 Sep 2024 12:33:10 +0400 Subject: [PATCH 7/9] Add sentinel checks for variables --- test/concrete/flowErc1155/FlowTest.sol | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/test/concrete/flowErc1155/FlowTest.sol b/test/concrete/flowErc1155/FlowTest.sol index c264d48e..f57a03b9 100644 --- a/test/concrete/flowErc1155/FlowTest.sol +++ b/test/concrete/flowErc1155/FlowTest.sol @@ -2,6 +2,7 @@ pragma solidity =0.8.19; import {Test, Vm} from "forge-std/Test.sol"; +import "forge-std/console.sol"; import {EvaluableV2} from "rain.interpreter.interface/lib/caller/LibEvaluable.sol"; import {IERC20Upgradeable as IERC20} from "openzeppelin-contracts-upgradeable/contracts/token/ERC20/IERC20Upgradeable.sol"; @@ -47,6 +48,10 @@ contract Erc1155FlowTest is FlowERC1155Test { vm.assume(alice != address(0)); vm.assume(expressionA != expressionB); vm.assume(!alice.isContract()); + vm.assume(sentinel != tokenIdA); + vm.assume(sentinel != tokenIdB); + vm.assume(sentinel != amountA); + vm.assume(sentinel != amountB); address[] memory expressions = new address[](1); expressions[0] = expressionA; @@ -54,6 +59,7 @@ contract Erc1155FlowTest is FlowERC1155Test { (IFlowERC1155V5 flow, EvaluableV2[] memory evaluables) = deployIFlowERC1155V5(expressions, expressionB, new uint256[][](1), "uri"); assumeEtchable(alice, address(flow)); + console.log("contextTransferAsss:", uint256(uint160(address(alice)))); // Mint tokens to Alice { @@ -80,6 +86,12 @@ contract Erc1155FlowTest is FlowERC1155Test { address(alice), address(flow) ); + console.log("contextTransferA:", uint256(uint160(address(alice)))); + console.log(uint256(uint160(address(flow))), tokenIdA); + + console.log("ExpressionA:", address(expressionA)); + console.log("ExpressionB:", address(expressionB)); + console.log("Alice's balance before transfer: ", IERC1155(address(flow)).balanceOf(alice, tokenIdA)); // Expect call token transfer interpreterEval2ExpectCall( @@ -89,12 +101,14 @@ contract Erc1155FlowTest is FlowERC1155Test { ), contextTransferA ); - + console.log("Calling flow.flow"); flow.flow(evaluables[0], new uint256[](0), new SignedContextV1[](0)); + console.log("Called flow.flow"); vm.startPrank(alice); IERC1155(address(flow)).safeTransferFrom(alice, address(flow), tokenIdA, amountA, ""); vm.stopPrank(); + console.log("Called safeTransferFrom"); { uint256[][] memory contextTransferB = LibContextWrapper.buildAndSetContext( From c544120e01a765752ec7eefbac3f86b45da4be9e Mon Sep 17 00:00:00 2001 From: ninokeldishvili Date: Tue, 17 Sep 2024 12:59:32 +0400 Subject: [PATCH 8/9] Comment out expectRevert --- test/concrete/flowErc1155/FlowTest.sol | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/test/concrete/flowErc1155/FlowTest.sol b/test/concrete/flowErc1155/FlowTest.sol index f57a03b9..59519173 100644 --- a/test/concrete/flowErc1155/FlowTest.sol +++ b/test/concrete/flowErc1155/FlowTest.sol @@ -2,7 +2,6 @@ pragma solidity =0.8.19; import {Test, Vm} from "forge-std/Test.sol"; -import "forge-std/console.sol"; import {EvaluableV2} from "rain.interpreter.interface/lib/caller/LibEvaluable.sol"; import {IERC20Upgradeable as IERC20} from "openzeppelin-contracts-upgradeable/contracts/token/ERC20/IERC20Upgradeable.sol"; @@ -59,7 +58,6 @@ contract Erc1155FlowTest is FlowERC1155Test { (IFlowERC1155V5 flow, EvaluableV2[] memory evaluables) = deployIFlowERC1155V5(expressions, expressionB, new uint256[][](1), "uri"); assumeEtchable(alice, address(flow)); - console.log("contextTransferAsss:", uint256(uint160(address(alice)))); // Mint tokens to Alice { @@ -86,12 +84,6 @@ contract Erc1155FlowTest is FlowERC1155Test { address(alice), address(flow) ); - console.log("contextTransferA:", uint256(uint160(address(alice)))); - console.log(uint256(uint160(address(flow))), tokenIdA); - - console.log("ExpressionA:", address(expressionA)); - console.log("ExpressionB:", address(expressionB)); - console.log("Alice's balance before transfer: ", IERC1155(address(flow)).balanceOf(alice, tokenIdA)); // Expect call token transfer interpreterEval2ExpectCall( @@ -101,14 +93,11 @@ contract Erc1155FlowTest is FlowERC1155Test { ), contextTransferA ); - console.log("Calling flow.flow"); flow.flow(evaluables[0], new uint256[](0), new SignedContextV1[](0)); - console.log("Called flow.flow"); vm.startPrank(alice); IERC1155(address(flow)).safeTransferFrom(alice, address(flow), tokenIdA, amountA, ""); vm.stopPrank(); - console.log("Called safeTransferFrom"); { uint256[][] memory contextTransferB = LibContextWrapper.buildAndSetContext( @@ -128,7 +117,7 @@ contract Erc1155FlowTest is FlowERC1155Test { ); vm.startPrank(alice); - vm.expectRevert("REVERT_EVAL2_CALL"); + // vm.expectRevert("REVERT_EVAL2_CALL"); IERC1155(address(flow)).safeTransferFrom(alice, address(flow), tokenIdB, amountB, ""); vm.stopPrank(); } From 652d7b3092fda284b28241e1556c84035ccf5539 Mon Sep 17 00:00:00 2001 From: Erik Dubovyk Date: Fri, 27 Sep 2024 22:38:43 +0300 Subject: [PATCH 9/9] updated for new abstraction structure --- test/abstract/FlowERC1155Test.sol | 7 +- test/concrete/flowErc1155/Erc1155FlowTest.sol | 106 ++++++++---------- test/concrete/flowErc20/Erc20FlowTest.sol | 41 ++----- test/concrete/flowErc721/Erc721FlowTest.sol | 24 ++-- 4 files changed, 69 insertions(+), 109 deletions(-) diff --git a/test/abstract/FlowERC1155Test.sol b/test/abstract/FlowERC1155Test.sol index a6a4b7b5..807691a1 100644 --- a/test/abstract/FlowERC1155Test.sol +++ b/test/abstract/FlowERC1155Test.sol @@ -23,7 +23,7 @@ abstract contract FlowERC1155Test is FlowTest { internal returns (IFlowERC1155V5 flowErc1155, EvaluableV2 memory evaluable) { - (flowErc1155, evaluable) = deployIFlowERC1155V5(address(0), uri); + (flowErc1155, evaluable) = deployIFlowERC1155V5(address(uint160(uint256(keccak256("expression")))), uri); } function deployIFlowERC1155V5(address expression, string memory uri) @@ -33,8 +33,9 @@ abstract contract FlowERC1155Test is FlowTest { address[] memory expressions = new address[](1); expressions[0] = expression; uint256[] memory constants = new uint256[](0); - (IFlowERC1155V5 flowErc1155, EvaluableV2[] memory evaluables) = - deployIFlowERC1155V5(expressions, address(1), constants.matrixFrom(), uri); + (IFlowERC1155V5 flowErc1155, EvaluableV2[] memory evaluables) = deployIFlowERC1155V5( + expressions, address(uint160(uint256(keccak256("configExpression")))), constants.matrixFrom(), uri + ); return (flowErc1155, evaluables[0]); } diff --git a/test/concrete/flowErc1155/Erc1155FlowTest.sol b/test/concrete/flowErc1155/Erc1155FlowTest.sol index d95eb5a6..b4713bf0 100644 --- a/test/concrete/flowErc1155/Erc1155FlowTest.sol +++ b/test/concrete/flowErc1155/Erc1155FlowTest.sol @@ -36,90 +36,76 @@ contract Erc1155FlowTest is FlowERC1155Test { using LibUint256Array for uint256[]; using Address for address; - function testFlowERC1155SupportsTransferPreflightHook( - address alice, - uint256 tokenIdA, - uint256 tokenIdB, - uint256 amountA, - uint256 amountB, - address expressionA, - address expressionB - ) external { + /** + * @notice Tests the support for the transferPreflight hook. + */ + /// forge-config: default.fuzz.runs = 100 + function testFlowERC1155SupportsTransferPreflightHook(address alice, uint128 amount, uint256 id) external { vm.assume(alice != address(0)); - vm.assume(expressionA != expressionB); - vm.assume(!alice.isContract()); - vm.assume(sentinel != tokenIdA); - vm.assume(sentinel != tokenIdB); - vm.assume(sentinel != amountA); - vm.assume(sentinel != amountB); - - address[] memory expressions = new address[](1); - expressions[0] = expressionA; + vm.assume(amount != 0); - (IFlowERC1155V5 flow, EvaluableV2[] memory evaluables) = - deployIFlowERC1155V5(expressions, expressionB, new uint256[][](1), "uri"); + (IFlowERC1155V5 flow, EvaluableV2 memory evaluable) = deployIFlowERC1155V5("https://www.rainprotocol.xyz/nft/"); assumeEtchable(alice, address(flow)); // Mint tokens to Alice { - ERC1155SupplyChange[] memory mints = new ERC1155SupplyChange[](2); - mints[0] = ERC1155SupplyChange({account: alice, id: tokenIdA, amount: amountA}); - mints[1] = ERC1155SupplyChange({account: alice, id: tokenIdB, amount: amountB}); - - uint256[] memory stack = generateFlowStack( - FlowERC1155IOV1( - mints, - new ERC1155SupplyChange[](0), - FlowTransferV1(new ERC20Transfer[](0), new ERC721Transfer[](0), new ERC1155Transfer[](0)) - ) - ); + (uint256[] memory stack,) = mintFlowStack(alice, amount, id, transferEmpty()); interpreterEval2MockCall(stack, new uint256[](0)); } - // Attempt a token transfer - uint256[][] memory contextTransferA = LibContextWrapper.buildAndSetContext( - LibUint256Array.arrayFrom( - uint256(uint160(address(alice))), uint256(uint160(address(flow))), tokenIdA, amountA - ).matrixFrom(), + uint256[] memory ids = new uint256[](1); + ids[0] = id; + + uint256[] memory amounts = new uint256[](1); + amounts[0] = amount; + + uint256[][] memory context = LibContextWrapper.buildAndSetContext( + LibUint256Matrix.matrixFrom( + LibUint256Array.arrayFrom( + uint256(uint160(alice)), uint256(uint160(alice)), uint256(uint160(address(flow))) + ), + ids, + amounts + ), new SignedContextV1[](0), address(alice), address(flow) ); - // Expect call token transfer - interpreterEval2ExpectCall( - address(flow), - LibEncodedDispatch.encode2( - expressionB, FLOW_ERC1155_HANDLE_TRANSFER_ENTRYPOINT, FLOW_ERC1155_HANDLE_TRANSFER_MAX_OUTPUTS - ), - contextTransferA - ); - flow.flow(evaluables[0], new uint256[](0), new SignedContextV1[](0)); - - vm.startPrank(alice); - IERC1155(address(flow)).safeTransferFrom(alice, address(flow), tokenIdA, amountA, ""); - vm.stopPrank(); - { - uint256[][] memory contextTransferB = LibContextWrapper.buildAndSetContext( - LibUint256Array.arrayFrom(uint256(uint160(address(alice))), uint256(uint160(address(flow))), tokenIdB) - .matrixFrom(), - new SignedContextV1[](0), - address(alice), - address(flow) + interpreterEval2ExpectCall( + address(flow), + LibEncodedDispatch.encode2( + address(uint160(uint256(keccak256("configExpression")))), + FLOW_ERC1155_HANDLE_TRANSFER_ENTRYPOINT, + FLOW_ERC1155_HANDLE_TRANSFER_MAX_OUTPUTS + ), + context ); + flow.flow(evaluable, new uint256[](0), new SignedContextV1[](0)); + + vm.startPrank(alice); + IERC1155(address(flow)).safeTransferFrom(alice, address(flow), id, amount, ""); + vm.stopPrank(); + } + + { interpreterEval2RevertCall( address(flow), LibEncodedDispatch.encode2( - expressionB, FLOW_ERC1155_HANDLE_TRANSFER_ENTRYPOINT, FLOW_ERC1155_HANDLE_TRANSFER_MAX_OUTPUTS + address(uint160(uint256(keccak256("configExpression")))), + FLOW_ERC1155_HANDLE_TRANSFER_ENTRYPOINT, + FLOW_ERC1155_HANDLE_TRANSFER_MAX_OUTPUTS ), - contextTransferB + context ); + flow.flow(evaluable, new uint256[](0), new SignedContextV1[](0)); + + vm.expectRevert("REVERT_EVAL2_CALL"); vm.startPrank(alice); - // vm.expectRevert("REVERT_EVAL2_CALL"); - IERC1155(address(flow)).safeTransferFrom(alice, address(flow), tokenIdB, amountB, ""); + IERC1155(address(flow)).safeTransferFrom(alice, address(flow), id, amount, ""); vm.stopPrank(); } } diff --git a/test/concrete/flowErc20/Erc20FlowTest.sol b/test/concrete/flowErc20/Erc20FlowTest.sol index 07ea757e..c3204a81 100644 --- a/test/concrete/flowErc20/Erc20FlowTest.sol +++ b/test/concrete/flowErc20/Erc20FlowTest.sol @@ -36,37 +36,14 @@ contract Erc20FlowTest is FlowERC20Test { * @notice Tests the support for the transferPreflight hook. */ /// forge-config: default.fuzz.runs = 100 - function testFlowERC20SupportsTransferPreflightHook( - address alice, - uint128 amount, - address expressionA, - address expressionB - ) external { + function testFlowERC20SupportsTransferPreflightHook(address alice, uint128 amount) external { vm.assume(alice != address(0)); - vm.assume(sentinel != amount); - vm.assume(expressionA != expressionB); - - address[] memory expressions = new address[](1); - expressions[0] = expressionA; - (IFlowERC20V5 flow, EvaluableV2[] memory evaluables) = - deployFlowERC20(expressions, expressionB, new uint256[][](1), "Flow ERC20", "F20"); + (IFlowERC20V5 flow, EvaluableV2 memory evaluable) = deployFlowERC20("Flow ERC20", "F20"); assumeEtchable(alice, address(flow)); { - ERC20SupplyChange[] memory mints = new ERC20SupplyChange[](1); - mints[0] = ERC20SupplyChange({account: alice, amount: amount}); - - ERC20SupplyChange[] memory burns = new ERC20SupplyChange[](1); - burns[0] = ERC20SupplyChange({account: alice, amount: 0 ether}); - - uint256[] memory stack = generateFlowStack( - FlowERC20IOV1( - mints, - burns, - FlowTransferV1(new ERC20Transfer[](0), new ERC721Transfer[](0), new ERC1155Transfer[](0)) - ) - ); + (uint256[] memory stack,) = mintFlowStack(alice, amount, 0, transferEmpty()); interpreterEval2MockCall(stack, new uint256[](0)); } @@ -82,12 +59,14 @@ contract Erc20FlowTest is FlowERC20Test { interpreterEval2ExpectCall( address(flow), LibEncodedDispatch.encode2( - expressionB, FLOW_ERC20_HANDLE_TRANSFER_ENTRYPOINT, FLOW_ERC20_HANDLE_TRANSFER_MAX_OUTPUTS + address(uint160(uint256(keccak256("configExpression")))), + FLOW_ERC20_HANDLE_TRANSFER_ENTRYPOINT, + FLOW_ERC20_HANDLE_TRANSFER_MAX_OUTPUTS ), context ); - flow.flow(evaluables[0], new uint256[](0), new SignedContextV1[](0)); + flow.flow(evaluable, new uint256[](0), new SignedContextV1[](0)); vm.startPrank(alice); IERC20(address(flow)).transfer(address(flow), amount); @@ -98,12 +77,14 @@ contract Erc20FlowTest is FlowERC20Test { interpreterEval2RevertCall( address(flow), LibEncodedDispatch.encode2( - expressionB, FLOW_ERC20_HANDLE_TRANSFER_ENTRYPOINT, FLOW_ERC20_HANDLE_TRANSFER_MAX_OUTPUTS + address(uint160(uint256(keccak256("configExpression")))), + FLOW_ERC20_HANDLE_TRANSFER_ENTRYPOINT, + FLOW_ERC20_HANDLE_TRANSFER_MAX_OUTPUTS ), context ); - flow.flow(evaluables[0], new uint256[](0), new SignedContextV1[](0)); + flow.flow(evaluable, new uint256[](0), new SignedContextV1[](0)); vm.startPrank(alice); vm.expectRevert("REVERT_EVAL2_CALL"); diff --git a/test/concrete/flowErc721/Erc721FlowTest.sol b/test/concrete/flowErc721/Erc721FlowTest.sol index 5282ef9e..3dfb601c 100644 --- a/test/concrete/flowErc721/Erc721FlowTest.sol +++ b/test/concrete/flowErc721/Erc721FlowTest.sol @@ -41,27 +41,15 @@ contract Erc721FlowTest is FlowERC721Test { /// forge-config: default.fuzz.runs = 100 function testFlowERC721SupportsTransferPreflightHook(address alice, uint256 tokenIdA, uint256 tokenIdB) external { vm.assume(alice != address(0)); - vm.assume(sentinel != tokenIdA); - vm.assume(sentinel != tokenIdB); vm.assume(tokenIdA != tokenIdB); - vm.assume(!alice.isContract()); (IFlowERC721V5 flow, EvaluableV2 memory evaluable) = deployFlowERC721({name: "", symbol: "", baseURI: ""}); assumeEtchable(alice, address(flow)); { - ERC721SupplyChange[] memory mints = new ERC721SupplyChange[](2); - mints[0] = ERC721SupplyChange({account: alice, id: tokenIdA}); - mints[1] = ERC721SupplyChange({account: alice, id: tokenIdB}); - - uint256[] memory stack = generateFlowStack( - FlowERC721IOV1( - mints, - new ERC721SupplyChange[](0), - FlowTransferV1(new ERC20Transfer[](0), new ERC721Transfer[](0), new ERC1155Transfer[](0)) - ) - ); + (uint256[] memory stack,) = mintFlowStack(alice, 0, tokenIdA, transferEmpty()); interpreterEval2MockCall(stack, new uint256[](0)); + IFlowERC721V5(flow).flow(evaluable, new uint256[](0), new SignedContextV1[](0)); } { @@ -84,13 +72,17 @@ contract Erc721FlowTest is FlowERC721Test { contextTransferA ); - IFlowERC721V5(flow).flow(evaluable, new uint256[](0), new SignedContextV1[](0)); - vm.startPrank(alice); IERC721(address(flow)).transferFrom({from: alice, to: address(flow), tokenId: tokenIdA}); vm.stopPrank(); } + { + (uint256[] memory stack,) = mintFlowStack(alice, 0, tokenIdB, transferEmpty()); + interpreterEval2MockCall(stack, new uint256[](0)); + IFlowERC721V5(flow).flow(evaluable, new uint256[](0), new SignedContextV1[](0)); + } + { uint256[][] memory contextTransferB = LibContextWrapper.buildAndSetContext( LibUint256Array.arrayFrom(uint256(uint160(address(alice))), uint256(uint160(address(flow))), tokenIdB)