feat: Add TokenTransfer class to BalancerV2

- This needed to be in BalancerV2 so that the executor can also take care of transfers from the user into the tycho router, to avoid having transfer actions mixed between the router and executors
This commit is contained in:
TAMARA LIPOWSKI
2025-04-14 17:15:19 -04:00
committed by Diana Carvalho
parent 462be5463b
commit 3a73fef933
6 changed files with 66 additions and 23 deletions

View File

@@ -106,7 +106,7 @@ contract TychoRouterTestSetup is Constants, Permit2TestHelper {
pancakev3Executor = new UniswapV3Executor(
factoryPancakeV3, initCodePancakeV3, PERMIT2_ADDRESS
);
balancerv2Executor = new BalancerV2Executor();
balancerv2Executor = new BalancerV2Executor(PERMIT2_ADDRESS);
ekuboExecutor = new EkuboExecutor(ekuboCore);
curveExecutor = new CurveExecutor(ETH_ADDR_FOR_CURVE, PERMIT2_ADDRESS);

View File

@@ -6,6 +6,8 @@ import {Test} from "../../lib/forge-std/src/Test.sol";
import {Constants} from "../Constants.sol";
contract BalancerV2ExecutorExposed is BalancerV2Executor {
constructor(address _permit2) BalancerV2Executor(_permit2) {}
function decodeParams(bytes calldata data)
external
pure
@@ -14,18 +16,15 @@ contract BalancerV2ExecutorExposed is BalancerV2Executor {
IERC20 tokenOut,
bytes32 poolId,
address receiver,
bool needsApproval
bool needsApproval,
TransferType transferType
)
{
return _decodeData(data);
}
}
contract BalancerV2ExecutorTest is
BalancerV2ExecutorExposed,
Test,
Constants
{
contract BalancerV2ExecutorTest is Test, Constants {
using SafeERC20 for IERC20;
BalancerV2ExecutorExposed balancerV2Exposed;
@@ -37,12 +36,17 @@ contract BalancerV2ExecutorTest is
function setUp() public {
uint256 forkBlock = 17323404;
vm.createSelectFork(vm.rpcUrl("mainnet"), forkBlock);
balancerV2Exposed = new BalancerV2ExecutorExposed();
balancerV2Exposed = new BalancerV2ExecutorExposed(PERMIT2_ADDRESS);
}
function testDecodeParams() public view {
bytes memory params = abi.encodePacked(
WETH_ADDR, BAL_ADDR, WETH_BAL_POOL_ID, address(2), true
WETH_ADDR,
BAL_ADDR,
WETH_BAL_POOL_ID,
address(2),
true,
TokenTransfer.TransferType.NONE
);
(
@@ -50,7 +54,8 @@ contract BalancerV2ExecutorTest is
IERC20 tokenOut,
bytes32 poolId,
address receiver,
bool needsApproval
bool needsApproval,
TokenTransfer.TransferType transferType
) = balancerV2Exposed.decodeParams(params);
assertEq(address(tokenIn), WETH_ADDR);
@@ -58,6 +63,7 @@ contract BalancerV2ExecutorTest is
assertEq(poolId, WETH_BAL_POOL_ID);
assertEq(receiver, address(2));
assertEq(needsApproval, true);
assertEq(uint8(transferType), uint8(TokenTransfer.TransferType.NONE));
}
function testDecodeParamsInvalidDataLength() public {
@@ -70,8 +76,14 @@ contract BalancerV2ExecutorTest is
function testSwap() public {
uint256 amountIn = 10 ** 18;
bytes memory protocolData =
abi.encodePacked(WETH_ADDR, BAL_ADDR, WETH_BAL_POOL_ID, BOB, true);
bytes memory protocolData = abi.encodePacked(
WETH_ADDR,
BAL_ADDR,
WETH_BAL_POOL_ID,
BOB,
true,
TokenTransfer.TransferType.NONE
);
deal(WETH_ADDR, address(balancerV2Exposed), amountIn);
uint256 balanceBefore = BAL.balanceOf(BOB);
@@ -86,14 +98,15 @@ contract BalancerV2ExecutorTest is
function testDecodeIntegration() public view {
// Generated by the SwapEncoder - test_encode_balancer_v2
bytes memory protocolData =
hex"c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2ba100000625a3754423978a60c9317c58a424e3d5c6ee304399dbdb9c8ef030ab642b10820db8f560002000000000000000000141d96f2f6bef1202e4ce1ff6dad0c2cb002861d3e01";
hex"c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2ba100000625a3754423978a60c9317c58a424e3d5c6ee304399dbdb9c8ef030ab642b10820db8f560002000000000000000000141d96f2f6bef1202e4ce1ff6dad0c2cb002861d3e0105";
(
IERC20 tokenIn,
IERC20 tokenOut,
bytes32 poolId,
address receiver,
bool needsApproval
bool needsApproval,
TokenTransfer.TransferType transferType
) = balancerV2Exposed.decodeParams(protocolData);
assertEq(address(tokenIn), WETH_ADDR);
@@ -101,12 +114,13 @@ contract BalancerV2ExecutorTest is
assertEq(poolId, WETH_BAL_POOL_ID);
assertEq(receiver, BOB);
assertEq(needsApproval, true);
assertEq(uint8(transferType), uint8(TokenTransfer.TransferType.NONE));
}
function testSwapIntegration() public {
// Generated by the SwapEncoder - test_encode_balancer_v2
bytes memory protocolData =
hex"c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2ba100000625a3754423978a60c9317c58a424e3d5c6ee304399dbdb9c8ef030ab642b10820db8f560002000000000000000000141d96f2f6bef1202e4ce1ff6dad0c2cb002861d3e01";
hex"c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2ba100000625a3754423978a60c9317c58a424e3d5c6ee304399dbdb9c8ef030ab642b10820db8f560002000000000000000000141d96f2f6bef1202e4ce1ff6dad0c2cb002861d3e0105";
uint256 amountIn = 10 ** 18;
deal(WETH_ADDR, address(balancerV2Exposed), amountIn);