Merge branch 'main' into router/tnl/ENG-4269-base-deployment

This commit is contained in:
Tamara
2025-02-26 13:21:04 -05:00
committed by GitHub
7 changed files with 84 additions and 57 deletions

View File

@@ -1,3 +1,7 @@
## [0.52.2](https://github.com/propeller-heads/tycho-execution/compare/0.52.1...0.52.2) (2025-02-26)
## [0.52.1](https://github.com/propeller-heads/tycho-execution/compare/0.52.0...0.52.1) (2025-02-26)
## [0.52.0](https://github.com/propeller-heads/tycho-execution/compare/0.51.2...0.52.0) (2025-02-26) ## [0.52.0](https://github.com/propeller-heads/tycho-execution/compare/0.51.2...0.52.0) (2025-02-26)

2
Cargo.lock generated
View File

@@ -4340,7 +4340,7 @@ dependencies = [
[[package]] [[package]]
name = "tycho-execution" name = "tycho-execution"
version = "0.52.0" version = "0.52.2"
dependencies = [ dependencies = [
"alloy", "alloy",
"alloy-primitives", "alloy-primitives",

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "tycho-execution" name = "tycho-execution"
version = "0.52.0" version = "0.52.2"
edition = "2021" edition = "2021"
[[bin]] [[bin]]

View File

@@ -140,19 +140,33 @@ contract TychoRouter is AccessControl, Dispatcher, Pausable, ReentrancyGuard {
uint256 nTokens, uint256 nTokens,
address receiver, address receiver,
bytes calldata swaps bytes calldata swaps
) external payable whenNotPaused nonReentrant returns (uint256 amountOut) { ) public payable whenNotPaused nonReentrant returns (uint256 amountOut) {
if (receiver == address(0)) { if (receiver == address(0)) {
revert TychoRouter__AddressZero(); revert TychoRouter__AddressZero();
} }
// Assume funds are already in the router.
// Assume funds already in our router.
if (wrapEth) { if (wrapEth) {
_wrapETH(amountIn); _wrapETH(amountIn);
tokenIn = address(_weth); tokenIn = address(_weth);
} }
uint256 initialBalance = tokenIn == address(0)
? address(this).balance
: IERC20(tokenIn).balanceOf(address(this));
amountOut = _swap(amountIn, nTokens, swaps); amountOut = _swap(amountIn, nTokens, swaps);
uint256 currentBalance = tokenIn == address(0)
? address(this).balance
: IERC20(tokenIn).balanceOf(address(this));
uint256 amountConsumed = initialBalance - currentBalance;
if (amountConsumed < amountIn) {
uint256 leftoverAmount = amountIn - amountConsumed;
revert TychoRouter__AmountInNotFullySpent(leftoverAmount);
}
if (fee > 0) { if (fee > 0) {
uint256 feeAmount = (amountOut * fee) / 10000; uint256 feeAmount = (amountOut * fee) / 10000;
amountOut -= feeAmount; amountOut -= feeAmount;
@@ -163,17 +177,6 @@ contract TychoRouter is AccessControl, Dispatcher, Pausable, ReentrancyGuard {
revert TychoRouter__NegativeSlippage(amountOut, minAmountOut); revert TychoRouter__NegativeSlippage(amountOut, minAmountOut);
} }
uint256 leftoverAmountIn;
if (tokenIn == address(0)) {
leftoverAmountIn = address(this).balance;
} else {
leftoverAmountIn = IERC20(tokenIn).balanceOf(address(this));
}
if (leftoverAmountIn > 0) {
revert TychoRouter__AmountInNotFullySpent(leftoverAmountIn);
}
if (unwrapEth) { if (unwrapEth) {
_unwrapETH(amountOut); _unwrapETH(amountOut);
} }
@@ -223,16 +226,9 @@ contract TychoRouter is AccessControl, Dispatcher, Pausable, ReentrancyGuard {
IAllowanceTransfer.PermitSingle calldata permitSingle, IAllowanceTransfer.PermitSingle calldata permitSingle,
bytes calldata signature, bytes calldata signature,
bytes calldata swaps bytes calldata swaps
) external payable whenNotPaused nonReentrant returns (uint256 amountOut) { ) external payable whenNotPaused returns (uint256 amountOut) {
if (receiver == address(0)) {
revert TychoRouter__AddressZero();
}
// For native ETH, assume funds already in our router. Else, transfer and handle approval. // For native ETH, assume funds already in our router. Else, transfer and handle approval.
if (wrapEth) { if (tokenIn != address(0)) {
_wrapETH(amountIn);
tokenIn = address(_weth);
} else if (tokenIn != address(0)) {
permit2.permit(msg.sender, permitSingle, signature); permit2.permit(msg.sender, permitSingle, signature);
permit2.transferFrom( permit2.transferFrom(
msg.sender, msg.sender,
@@ -242,37 +238,17 @@ contract TychoRouter is AccessControl, Dispatcher, Pausable, ReentrancyGuard {
); );
} }
amountOut = _swap(amountIn, nTokens, swaps); return swap(
amountIn,
if (fee > 0) { tokenIn,
uint256 feeAmount = (amountOut * fee) / 10000; tokenOut,
amountOut -= feeAmount; minAmountOut,
IERC20(tokenOut).safeTransfer(feeReceiver, feeAmount); wrapEth,
} unwrapEth,
nTokens,
if (minAmountOut > 0 && amountOut < minAmountOut) { receiver,
revert TychoRouter__NegativeSlippage(amountOut, minAmountOut); swaps
} );
uint256 leftoverAmountIn;
if (tokenIn == address(0)) {
leftoverAmountIn = address(this).balance;
} else {
leftoverAmountIn = IERC20(tokenIn).balanceOf(address(this));
}
if (leftoverAmountIn > 0) {
revert TychoRouter__AmountInNotFullySpent(leftoverAmountIn);
}
if (unwrapEth) {
_unwrapETH(amountOut);
}
if (tokenOut == address(0)) {
Address.sendValue(payable(receiver), amountOut);
} else {
IERC20(tokenOut).safeTransfer(receiver, amountOut);
}
} }
/** /**

View File

@@ -3,7 +3,15 @@ pragma solidity ^0.8.26;
import "forge-std/Test.sol"; import "forge-std/Test.sol";
contract Constants is Test { contract BaseConstants {
address BASE_USDC = 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913;
address BASE_MAG7 = 0x9E6A46f294bB67c20F1D1E7AfB0bBEf614403B55;
// uniswap v2
address USDC_MAG7_POOL = 0x739c2431670A12E2cF8e11E3603eB96e6728a789;
}
contract Constants is Test, BaseConstants {
address ADMIN = makeAddr("admin"); //admin=us address ADMIN = makeAddr("admin"); //admin=us
address BOB = makeAddr("bob"); //bob=someone!=us address BOB = makeAddr("bob"); //bob=someone!=us
address FUND_RESCUER = makeAddr("fundRescuer"); address FUND_RESCUER = makeAddr("fundRescuer");

View File

@@ -978,4 +978,26 @@ contract TychoRouterTest is TychoRouterTestSetup {
assertEq(IERC20(WBTC_ADDR).balanceOf(tychoRouterAddr), 102718); assertEq(IERC20(WBTC_ADDR).balanceOf(tychoRouterAddr), 102718);
} }
// Base Network Tests
// Make sure to set the RPC_URL to base network
function testSwapSingleBase() public {
vm.skip(true);
vm.rollFork(26857267);
uint256 amountIn = 10 * 10 ** 6;
deal(BASE_USDC, tychoRouterAddr, amountIn);
bytes memory protocolData = encodeUniswapV2Swap(
BASE_USDC, USDC_MAG7_POOL, tychoRouterAddr, true
);
bytes memory swap = encodeSwap(
uint8(0), uint8(1), uint24(0), address(usv2Executor), protocolData
);
bytes[] memory swaps = new bytes[](1);
swaps[0] = swap;
tychoRouter.exposedSwap(amountIn, 2, pleEncode(swaps));
assertGt(IERC20(BASE_MAG7).balanceOf(tychoRouterAddr), 1379830606);
}
} }

View File

@@ -156,4 +156,21 @@ contract UniswapV2ExecutorTest is UniswapV2ExecutorExposed, Test, Constants {
vm.expectRevert(UniswapV2Executor__InvalidTarget.selector); vm.expectRevert(UniswapV2Executor__InvalidTarget.selector);
uniswapV2Exposed.swap(amountIn, protocolData); uniswapV2Exposed.swap(amountIn, protocolData);
} }
// Base Network Tests
// Make sure to set the RPC_URL to base network
function testSwapBaseNetwork() public {
vm.skip(true);
vm.rollFork(26857267);
uint256 amountIn = 10 * 10 ** 6;
bool zeroForOne = true;
bytes memory protocolData =
abi.encodePacked(BASE_USDC, USDC_MAG7_POOL, BOB, zeroForOne);
deal(BASE_USDC, address(uniswapV2Exposed), amountIn);
uniswapV2Exposed.swap(amountIn, protocolData);
assertEq(IERC20(BASE_MAG7).balanceOf(BOB), 1379830606);
}
} }