chore: implement correct native ETH support
This commit is contained in:
@@ -109,16 +109,12 @@ contract BebopExecutor is IExecutor, IExecutorErrors, RestrictTransferFrom {
|
|||||||
/// @notice The Bebop settlement contract address
|
/// @notice The Bebop settlement contract address
|
||||||
address public immutable bebopSettlement;
|
address public immutable bebopSettlement;
|
||||||
|
|
||||||
/// @notice The native ETH address representation (same as Curve)
|
|
||||||
address public immutable nativeToken;
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
address _bebopSettlement,
|
address _bebopSettlement,
|
||||||
address _nativeToken,
|
|
||||||
address _permit2
|
address _permit2
|
||||||
) RestrictTransferFrom(_permit2) {
|
) RestrictTransferFrom(_permit2) {
|
||||||
bebopSettlement = _bebopSettlement;
|
bebopSettlement = _bebopSettlement;
|
||||||
nativeToken = _nativeToken;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @notice Executes a swap through Bebop's PMM RFQ system
|
/// @notice Executes a swap through Bebop's PMM RFQ system
|
||||||
@@ -181,12 +177,12 @@ contract BebopExecutor is IExecutor, IExecutorErrors, RestrictTransferFrom {
|
|||||||
) = _decodeQuoteData(quoteData, signatureType, signature);
|
) = _decodeQuoteData(quoteData, signatureType, signature);
|
||||||
|
|
||||||
// Record balances before swap to calculate amountOut
|
// Record balances before swap to calculate amountOut
|
||||||
uint256 balanceBefore = tokenOut == nativeToken
|
uint256 balanceBefore = tokenOut == address(0)
|
||||||
? order.receiver.balance
|
? order.receiver.balance
|
||||||
: IERC20(tokenOut).balanceOf(order.receiver);
|
: IERC20(tokenOut).balanceOf(order.receiver);
|
||||||
|
|
||||||
// Handle ETH vs ERC20 execution
|
// Handle ETH vs ERC20 execution
|
||||||
if (tokenIn == nativeToken) {
|
if (tokenIn == address(0)) {
|
||||||
// For ETH input, use msg.value
|
// For ETH input, use msg.value
|
||||||
try IBebopSettlement(bebopSettlement).swapSingle{value: amountIn}(
|
try IBebopSettlement(bebopSettlement).swapSingle{value: amountIn}(
|
||||||
order, sig, amountIn
|
order, sig, amountIn
|
||||||
@@ -207,7 +203,7 @@ contract BebopExecutor is IExecutor, IExecutorErrors, RestrictTransferFrom {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Calculate actual amount received
|
// Calculate actual amount received
|
||||||
uint256 balanceAfter = tokenOut == nativeToken
|
uint256 balanceAfter = tokenOut == address(0)
|
||||||
? order.receiver.balance
|
? order.receiver.balance
|
||||||
: IERC20(tokenOut).balanceOf(order.receiver);
|
: IERC20(tokenOut).balanceOf(order.receiver);
|
||||||
|
|
||||||
|
|||||||
@@ -32,9 +32,8 @@ contract MockToken is ERC20 {
|
|||||||
contract BebopExecutorExposed is BebopExecutor {
|
contract BebopExecutorExposed is BebopExecutor {
|
||||||
constructor(
|
constructor(
|
||||||
address _bebopSettlement,
|
address _bebopSettlement,
|
||||||
address _nativeToken,
|
|
||||||
address _permit2
|
address _permit2
|
||||||
) BebopExecutor(_bebopSettlement, _nativeToken, _permit2) {}
|
) BebopExecutor(_bebopSettlement, _permit2) {}
|
||||||
|
|
||||||
function decodeParams(bytes calldata data)
|
function decodeParams(bytes calldata data)
|
||||||
external
|
external
|
||||||
@@ -66,7 +65,7 @@ contract MockBebopSettlement is Test, Constants {
|
|||||||
require(filledTakerAmount <= order.taker_amount, "Exceeds order amount");
|
require(filledTakerAmount <= order.taker_amount, "Exceeds order amount");
|
||||||
|
|
||||||
// Mock implementation handles input tokens
|
// Mock implementation handles input tokens
|
||||||
if (order.taker_token == ETH_ADDR_FOR_CURVE) {
|
if (order.taker_token == address(0)) {
|
||||||
// For ETH input, validate msg.value
|
// For ETH input, validate msg.value
|
||||||
require(msg.value >= filledTakerAmount, "Insufficient ETH sent");
|
require(msg.value >= filledTakerAmount, "Insufficient ETH sent");
|
||||||
} else {
|
} else {
|
||||||
@@ -80,11 +79,9 @@ contract MockBebopSettlement is Test, Constants {
|
|||||||
filledMakerAmount =
|
filledMakerAmount =
|
||||||
(filledTakerAmount * order.maker_amount) / order.taker_amount;
|
(filledTakerAmount * order.maker_amount) / order.taker_amount;
|
||||||
|
|
||||||
// Send output tokens to receiver, or back to sender if receiver is zero
|
address recipient = order.receiver;
|
||||||
address recipient =
|
|
||||||
order.receiver != address(0) ? order.receiver : msg.sender;
|
|
||||||
|
|
||||||
if (order.maker_token == ETH_ADDR_FOR_CURVE) {
|
if (order.maker_token == address(0)) {
|
||||||
// For ETH output, send ETH directly
|
// For ETH output, send ETH directly
|
||||||
vm.deal(recipient, recipient.balance + filledMakerAmount);
|
vm.deal(recipient, recipient.balance + filledMakerAmount);
|
||||||
} else {
|
} else {
|
||||||
@@ -129,7 +126,6 @@ contract BebopExecutorTest is Constants, Permit2TestHelper, TestUtils {
|
|||||||
// Deploy Bebop executor
|
// Deploy Bebop executor
|
||||||
bebopExecutor = new BebopExecutorExposed(
|
bebopExecutor = new BebopExecutorExposed(
|
||||||
address(mockBebopSettlement),
|
address(mockBebopSettlement),
|
||||||
ETH_ADDR_FOR_CURVE, // Native token address
|
|
||||||
PERMIT2_ADDRESS
|
PERMIT2_ADDRESS
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -242,7 +238,7 @@ contract BebopExecutorTest is Constants, Permit2TestHelper, TestUtils {
|
|||||||
taker_address: address(0), // Any taker
|
taker_address: address(0), // Any taker
|
||||||
maker_address: address(mockBebopSettlement),
|
maker_address: address(mockBebopSettlement),
|
||||||
maker_nonce: 1,
|
maker_nonce: 1,
|
||||||
taker_token: ETH_ADDR_FOR_CURVE, // ETH input
|
taker_token: address(0), // ETH input
|
||||||
maker_token: USDC_ADDR,
|
maker_token: USDC_ADDR,
|
||||||
taker_amount: amountIn,
|
taker_amount: amountIn,
|
||||||
maker_amount: expectedAmountOut,
|
maker_amount: expectedAmountOut,
|
||||||
@@ -256,7 +252,7 @@ contract BebopExecutorTest is Constants, Permit2TestHelper, TestUtils {
|
|||||||
bytes memory signature = hex"aabbccdd"; // Mock signature
|
bytes memory signature = hex"aabbccdd"; // Mock signature
|
||||||
|
|
||||||
bytes memory params = abi.encodePacked(
|
bytes memory params = abi.encodePacked(
|
||||||
ETH_ADDR_FOR_CURVE, // ETH input
|
address(0), // ETH input
|
||||||
USDC_ADDR,
|
USDC_ADDR,
|
||||||
uint8(RestrictTransferFrom.TransferType.None), // ETH comes via msg.value
|
uint8(RestrictTransferFrom.TransferType.None), // ETH comes via msg.value
|
||||||
uint8(0), // OrderType.Single
|
uint8(0), // OrderType.Single
|
||||||
@@ -292,7 +288,7 @@ contract BebopExecutorTest is Constants, Permit2TestHelper, TestUtils {
|
|||||||
maker_address: address(mockBebopSettlement),
|
maker_address: address(mockBebopSettlement),
|
||||||
maker_nonce: 1,
|
maker_nonce: 1,
|
||||||
taker_token: USDC_ADDR,
|
taker_token: USDC_ADDR,
|
||||||
maker_token: ETH_ADDR_FOR_CURVE, // ETH output
|
maker_token: address(0), // ETH output
|
||||||
taker_amount: amountIn,
|
taker_amount: amountIn,
|
||||||
maker_amount: expectedAmountOut,
|
maker_amount: expectedAmountOut,
|
||||||
receiver: address(bebopExecutor), // Output should go to executor
|
receiver: address(bebopExecutor), // Output should go to executor
|
||||||
@@ -306,7 +302,7 @@ contract BebopExecutorTest is Constants, Permit2TestHelper, TestUtils {
|
|||||||
|
|
||||||
bytes memory params = abi.encodePacked(
|
bytes memory params = abi.encodePacked(
|
||||||
USDC_ADDR,
|
USDC_ADDR,
|
||||||
ETH_ADDR_FOR_CURVE, // ETH output
|
address(0), // ETH output
|
||||||
uint8(RestrictTransferFrom.TransferType.Transfer),
|
uint8(RestrictTransferFrom.TransferType.Transfer),
|
||||||
uint8(0), // OrderType.Single
|
uint8(0), // OrderType.Single
|
||||||
uint32(quoteData.length),
|
uint32(quoteData.length),
|
||||||
|
|||||||
Reference in New Issue
Block a user