Merge branch 'main' into router/tnl/ENG-4269-base-deployment
This commit is contained in:
@@ -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
2
Cargo.lock
generated
@@ -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",
|
||||||
|
|||||||
@@ -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]]
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -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");
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user