chore: cleanup tech debt from Bebop tests and the execution harness
This commit is contained in:
@@ -227,7 +227,7 @@ contract BebopExecutorTest is Constants, Permit2TestHelper, TestUtils {
|
|||||||
// Check initial ONDO balance of receiver
|
// Check initial ONDO balance of receiver
|
||||||
uint256 initialOndoBalance = ONDO.balanceOf(originalTakerAddress);
|
uint256 initialOndoBalance = ONDO.balanceOf(originalTakerAddress);
|
||||||
|
|
||||||
uint256 amountOut = bebopExecutor.swapForTest(testData.amountIn, params);
|
uint256 amountOut = bebopExecutor.swap(testData.amountIn, params);
|
||||||
|
|
||||||
// Verify results
|
// Verify results
|
||||||
assertEq(amountOut, testData.expectedAmountOut, "Incorrect amount out");
|
assertEq(amountOut, testData.expectedAmountOut, "Incorrect amount out");
|
||||||
@@ -327,7 +327,7 @@ contract BebopExecutorTest is Constants, Permit2TestHelper, TestUtils {
|
|||||||
// Check initial ONDO balance of receiver
|
// Check initial ONDO balance of receiver
|
||||||
uint256 initialOndoBalance = ONDO.balanceOf(originalTakerAddress);
|
uint256 initialOndoBalance = ONDO.balanceOf(originalTakerAddress);
|
||||||
|
|
||||||
uint256 amountOut = bebopExecutor.swapForTest(testData.amountIn, params);
|
uint256 amountOut = bebopExecutor.swap(testData.amountIn, params);
|
||||||
|
|
||||||
// Verify partial fill results
|
// Verify partial fill results
|
||||||
assertEq(
|
assertEq(
|
||||||
@@ -427,9 +427,8 @@ contract BebopExecutorTest is Constants, Permit2TestHelper, TestUtils {
|
|||||||
vm.prank(makerAddresses[1]);
|
vm.prank(makerAddresses[1]);
|
||||||
USDC.approve(BEBOP_SETTLEMENT, makerAmounts[1][0]);
|
USDC.approve(BEBOP_SETTLEMENT, makerAmounts[1][0]);
|
||||||
|
|
||||||
// ETH will be handled by the executor harness
|
// For native ETH, settlement pulls from taker; fund taker with ETH
|
||||||
// Fund the executor with ETH (like we do with ERC20 tokens in single tests)
|
vm.deal(originalTakerAddress, totalTakerAmount + 1 ether);
|
||||||
vm.deal(address(bebopExecutor), totalTakerAmount);
|
|
||||||
|
|
||||||
// Create maker signatures
|
// Create maker signatures
|
||||||
IBebopSettlement.MakerSignature[] memory signatures =
|
IBebopSettlement.MakerSignature[] memory signatures =
|
||||||
@@ -467,7 +466,7 @@ contract BebopExecutorTest is Constants, Permit2TestHelper, TestUtils {
|
|||||||
uint256 initialUsdcBalance = USDC.balanceOf(originalTakerAddress);
|
uint256 initialUsdcBalance = USDC.balanceOf(originalTakerAddress);
|
||||||
|
|
||||||
// Execute the aggregate swap with ETH value
|
// Execute the aggregate swap with ETH value
|
||||||
uint256 amountOut = bebopExecutor.swapForTest{value: totalTakerAmount}(
|
uint256 amountOut = bebopExecutor.swap{value: totalTakerAmount}(
|
||||||
totalTakerAmount, params
|
totalTakerAmount, params
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -479,11 +478,11 @@ contract BebopExecutorTest is Constants, Permit2TestHelper, TestUtils {
|
|||||||
totalMakerAmount,
|
totalMakerAmount,
|
||||||
"USDC should be at receiver"
|
"USDC should be at receiver"
|
||||||
);
|
);
|
||||||
// With pranking, settlement pulls ETH from taker; executor keeps msg.value
|
// With pranking, settlement pulls ETH from taker; executor keeps msg.value on top of initial dust
|
||||||
assertEq(
|
assertEq(
|
||||||
address(bebopExecutor).balance,
|
address(bebopExecutor).balance,
|
||||||
totalTakerAmount,
|
initialExecutorBalance + totalTakerAmount,
|
||||||
"Executor ETH balance should equal msg.value for aggregate ETH flow"
|
"Executor ETH balance should be initial + msg.value for aggregate ETH flow"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -570,9 +569,8 @@ contract BebopExecutorTest is Constants, Permit2TestHelper, TestUtils {
|
|||||||
vm.prank(makerAddresses[1]);
|
vm.prank(makerAddresses[1]);
|
||||||
USDC.approve(BEBOP_SETTLEMENT, makerAmounts[1][0]);
|
USDC.approve(BEBOP_SETTLEMENT, makerAmounts[1][0]);
|
||||||
|
|
||||||
// ETH will be handled by the executor harness
|
// For native ETH, settlement pulls from taker; fund taker with ETH
|
||||||
// Fund the executor with ETH (like we do with ERC20 tokens in single tests)
|
vm.deal(originalTakerAddress, partialFillAmount + 1 ether);
|
||||||
vm.deal(address(bebopExecutor), partialFillAmount);
|
|
||||||
|
|
||||||
// Create maker signatures
|
// Create maker signatures
|
||||||
IBebopSettlement.MakerSignature[] memory signatures =
|
IBebopSettlement.MakerSignature[] memory signatures =
|
||||||
@@ -610,7 +608,7 @@ contract BebopExecutorTest is Constants, Permit2TestHelper, TestUtils {
|
|||||||
uint256 initialUsdcBalance = USDC.balanceOf(originalTakerAddress);
|
uint256 initialUsdcBalance = USDC.balanceOf(originalTakerAddress);
|
||||||
|
|
||||||
// Execute the partial aggregate swap with ETH value
|
// Execute the partial aggregate swap with ETH value
|
||||||
uint256 amountOut = bebopExecutor.swapForTest{value: partialFillAmount}(
|
uint256 amountOut = bebopExecutor.swap{value: partialFillAmount}(
|
||||||
partialFillAmount, params
|
partialFillAmount, params
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -624,11 +622,11 @@ contract BebopExecutorTest is Constants, Permit2TestHelper, TestUtils {
|
|||||||
expectedPartialOutput,
|
expectedPartialOutput,
|
||||||
"USDC should be at receiver"
|
"USDC should be at receiver"
|
||||||
);
|
);
|
||||||
// With pranking, settlement pulls ETH from taker; executor keeps msg.value
|
// With pranking, settlement pulls ETH from taker; executor keeps msg.value on top of initial dust
|
||||||
assertEq(
|
assertEq(
|
||||||
address(bebopExecutor).balance,
|
address(bebopExecutor).balance,
|
||||||
partialFillAmount,
|
initialExecutorBalance + partialFillAmount,
|
||||||
"Executor ETH balance should equal msg.value for aggregate ETH flow"
|
"Executor ETH balance should be initial + msg.value for aggregate ETH flow"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -750,7 +748,7 @@ contract BebopExecutorTest is Constants, Permit2TestHelper, TestUtils {
|
|||||||
uint256 initialOndoBalance = ONDO.balanceOf(originalTakerAddress);
|
uint256 initialOndoBalance = ONDO.balanceOf(originalTakerAddress);
|
||||||
|
|
||||||
// Execute the swap
|
// Execute the swap
|
||||||
uint256 amountOut = bebopExecutor.swapForTest(amountIn, protocolData);
|
uint256 amountOut = bebopExecutor.swap(amountIn, protocolData);
|
||||||
|
|
||||||
// Verify results
|
// Verify results
|
||||||
assertEq(amountOut, expectedAmountOut, "Incorrect amount out");
|
assertEq(amountOut, expectedAmountOut, "Incorrect amount out");
|
||||||
@@ -884,7 +882,7 @@ contract BebopExecutorTest is Constants, Permit2TestHelper, TestUtils {
|
|||||||
|
|
||||||
// Execute the swap with native ETH
|
// Execute the swap with native ETH
|
||||||
uint256 amountOut =
|
uint256 amountOut =
|
||||||
bebopExecutor.swapForTest{value: ethAmount}(ethAmount, protocolData);
|
bebopExecutor.swap{value: ethAmount}(ethAmount, protocolData);
|
||||||
|
|
||||||
// Verify results
|
// Verify results
|
||||||
assertEq(amountOut, expAmountOut, "Incorrect amount out");
|
assertEq(amountOut, expAmountOut, "Incorrect amount out");
|
||||||
|
|||||||
@@ -249,101 +249,4 @@ contract BebopExecutorHarness is BebopExecutor, Test {
|
|||||||
|
|
||||||
// no-op; keep function end balanced
|
// no-op; keep function end balanced
|
||||||
}
|
}
|
||||||
|
|
||||||
// Special method for direct test calls that need harness behavior
|
|
||||||
function swapForTest(uint256 givenAmount, bytes calldata data)
|
|
||||||
external
|
|
||||||
payable
|
|
||||||
returns (uint256 calculatedAmount)
|
|
||||||
{
|
|
||||||
return _handleDirectTestSwap(givenAmount, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
function _handleDirectTestSwap(uint256 givenAmount, bytes calldata data)
|
|
||||||
internal
|
|
||||||
returns (uint256 calculatedAmount)
|
|
||||||
{
|
|
||||||
// Decode the packed data
|
|
||||||
(
|
|
||||||
address tokenIn,
|
|
||||||
,
|
|
||||||
TransferType transferType,
|
|
||||||
bytes memory bebopCalldata,
|
|
||||||
, // partialFillOffset not needed in test harness
|
|
||||||
uint256 originalFilledTakerAmount,
|
|
||||||
, // approvalNeeded not needed in test harness
|
|
||||||
// receiver not needed since we extract it from bebop calldata
|
|
||||||
) = _decodeData(data);
|
|
||||||
|
|
||||||
// Extract taker address, receiver, and expiry from bebop calldata
|
|
||||||
bytes4 sel = _getSelector(bebopCalldata);
|
|
||||||
address takerAddress;
|
|
||||||
address receiverAddress;
|
|
||||||
uint256 expiry;
|
|
||||||
|
|
||||||
bytes memory bebopCalldataWithoutSelector =
|
|
||||||
_stripSelector(bebopCalldata);
|
|
||||||
|
|
||||||
if (sel == SWAP_SINGLE_SELECTOR) {
|
|
||||||
(IBebopSettlement.Single memory order,,) = abi.decode(
|
|
||||||
bebopCalldataWithoutSelector,
|
|
||||||
(
|
|
||||||
IBebopSettlement.Single,
|
|
||||||
IBebopSettlement.MakerSignature,
|
|
||||||
uint256
|
|
||||||
)
|
|
||||||
);
|
|
||||||
takerAddress = order.taker_address;
|
|
||||||
receiverAddress = order.receiver;
|
|
||||||
expiry = order.expiry;
|
|
||||||
} else {
|
|
||||||
(IBebopSettlement.Aggregate memory order,,) = abi.decode(
|
|
||||||
bebopCalldataWithoutSelector,
|
|
||||||
(
|
|
||||||
IBebopSettlement.Aggregate,
|
|
||||||
IBebopSettlement.MakerSignature[],
|
|
||||||
uint256
|
|
||||||
)
|
|
||||||
);
|
|
||||||
takerAddress = order.taker_address;
|
|
||||||
receiverAddress = order.receiver;
|
|
||||||
expiry = order.expiry;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint256 actualFilledTakerAmount = originalFilledTakerAmount
|
|
||||||
> givenAmount ? givenAmount : originalFilledTakerAmount;
|
|
||||||
|
|
||||||
// For testing: transfer tokens from executor to taker address
|
|
||||||
// This simulates the taker having the tokens with approval
|
|
||||||
if (tokenIn != address(0)) {
|
|
||||||
// The executor already has the tokens from the test, just transfer to taker
|
|
||||||
IERC20(tokenIn).safeTransfer(takerAddress, actualFilledTakerAmount);
|
|
||||||
|
|
||||||
// Approve settlement from taker's perspective
|
|
||||||
// Stop any existing prank first
|
|
||||||
vm.stopPrank();
|
|
||||||
vm.startPrank(takerAddress);
|
|
||||||
IERC20(tokenIn).forceApprove(bebopSettlement, type(uint256).max);
|
|
||||||
vm.stopPrank();
|
|
||||||
} else {
|
|
||||||
vm.stopPrank();
|
|
||||||
// For native ETH, deal it to the taker address
|
|
||||||
payable(takerAddress).transfer(actualFilledTakerAmount);
|
|
||||||
}
|
|
||||||
|
|
||||||
// IMPORTANT: Prank as the taker address to pass the settlement validation
|
|
||||||
vm.stopPrank();
|
|
||||||
vm.startPrank(takerAddress);
|
|
||||||
|
|
||||||
// Set block timestamp to ensure order is valid regardless of fork block
|
|
||||||
uint256 currentTimestamp = block.timestamp;
|
|
||||||
vm.warp(expiry - 1); // Set timestamp to just before expiry
|
|
||||||
|
|
||||||
// Call the parent's internal _swap function
|
|
||||||
calculatedAmount = _swap(givenAmount, data);
|
|
||||||
|
|
||||||
// Restore original timestamp
|
|
||||||
vm.warp(currentTimestamp);
|
|
||||||
vm.stopPrank();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -875,7 +875,7 @@ impl SwapEncoder for BebopSwapEncoder {
|
|||||||
&bebop_calldata[filled_taker_amount_pos..filled_taker_amount_pos + 32],
|
&bebop_calldata[filled_taker_amount_pos..filled_taker_amount_pos + 32],
|
||||||
);
|
);
|
||||||
|
|
||||||
// Extract receiver and taker_amount from the order based on the function selector
|
// Extract taker_amount from the order based on the function selector
|
||||||
let selector = &bebop_calldata[0..4];
|
let selector = &bebop_calldata[0..4];
|
||||||
|
|
||||||
// swapSingle selector: 0x4dcebcba
|
// swapSingle selector: 0x4dcebcba
|
||||||
|
|||||||
Reference in New Issue
Block a user