Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/tycho-execution/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ thiserror = { workspace = true }
tokio = { workspace = true }
tycho-common = { workspace = true }
typetag = { workspace = true, optional = true }
alloy = { workspace = true, features = ["providers", "rpc-types-eth", "eip712", "signer-local", "node-bindings"], optional = true }
alloy = { workspace = true, features = ["providers", "rpc-types-eth", "eip712", "signer-local", "node-bindings", "sol-types"], optional = true }
async-trait = { workspace = true, optional = true }

[dev-dependencies]
Expand Down
2 changes: 1 addition & 1 deletion crates/tycho-execution/config/executor_addresses.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,4 @@
"vm:curve": "0xbc4d9e944ad40480a34ebaf38cd2acf6e1dc0def",
"weth": "0x13AcF9532C173753484ed1Bef86C98cBfe83Ba90"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
"eeth_address": "0x35fA164735182de50811E8e2E824cFb9B6118ac2",
"weeth_address": "0xCd5fE23C85820F7B72D0926FC9b05b43E359b7ee"
},
"lido_v3": {
"steth_address": "0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84",
"wsteth_address": "0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0"
},
"rfq:liquorice": {
"balance_manager_address": "0xb87bAE43a665EB5943A5642F81B26666bC9E5C95"
}
Expand All @@ -20,4 +24,4 @@
"native_token_address": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"
}
}
}
}
1 change: 1 addition & 0 deletions crates/tycho-execution/config/test_executor_addresses.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"weth": "0x96d3F6c20EEd2697647F543fE6C08bC2Fbf39758",
"ekubo_v3": "0x13aa49bAc059d709dd0a18D6bb63290076a702D7",
"etherfi": "0xDB25A7b768311dE128BBDa7B8426c3f9C74f3240",
"lido_v3": "0xe8dc788818033232EF9772CB2e6622F1Ec8bc840",
"rfq:liquorice": "0x3381cD18e2Fb4dB236BF0525938AB6E43Db0440f"
},
"base": {
Expand Down
7 changes: 7 additions & 0 deletions crates/tycho-execution/contracts/scripts/deploy-executors.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,13 @@ const executors_to_deploy = {
{
exchange: "WethExecutor", args: ["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"]
},
// Args: stETH address, wstETH address
{
exchange: "LidoV3Executor", args: [
"0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84",
"0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0"
]
},

// Args: Liquorice settlement, Liquorice balance manager
{
Expand Down
119 changes: 119 additions & 0 deletions crates/tycho-execution/contracts/src/executors/LidoV3Executor.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.26;

import {IExecutor} from "@interfaces/IExecutor.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {TransferManager} from "../TransferManager.sol";

error LidoV3Executor__InvalidDataLength();
error LidoV3Executor__InvalidDirection();
error LidoV3Executor__ZeroAddress();

interface IStETH is IERC20 {
function submit(address referral) external payable returns (uint256);
}

interface IWstETH is IERC20 {
function wrap(uint256 stETHAmount) external returns (uint256);
function unwrap(uint256 wstETHAmount) external returns (uint256);
}

enum LidoV3Direction {
EthToStEth,
StEthToWstEth,
WstEthToStEth
}

contract LidoV3Executor is IExecutor {
IStETH public immutable stEth;
IWstETH public immutable wstEth;

constructor(address stEthAddress, address wstEthAddress) {
if (stEthAddress == address(0) || wstEthAddress == address(0)) {
revert LidoV3Executor__ZeroAddress();
}

stEth = IStETH(stEthAddress);
wstEth = IWstETH(wstEthAddress);
}

function fundsExpectedAddress(
bytes calldata /* data */
)
external
view
returns (address receiver)
{
return msg.sender;
}

// slither-disable-next-line locked-ether
function swap(uint256 amountIn, bytes calldata data, address /* receiver */)
external
payable
{
LidoV3Direction direction = _decodeData(data);

if (direction == LidoV3Direction.EthToStEth) {
stEth.submit{value: amountIn}(address(0));
} else if (direction == LidoV3Direction.StEthToWstEth) {
wstEth.wrap(amountIn);
} else if (direction == LidoV3Direction.WstEthToStEth) {
wstEth.unwrap(amountIn);
} else {
revert LidoV3Executor__InvalidDirection();
}
}

function getTransferData(bytes calldata data)
external
payable
returns (
TransferManager.TransferType transferType,
address receiver,
address tokenIn,
address tokenOut,
bool outputToRouter
)
{
LidoV3Direction direction = _decodeData(data);

if (direction == LidoV3Direction.EthToStEth) {
transferType = TransferManager.TransferType.TransferNativeInExecutor;
receiver = msg.sender;
tokenIn = address(0);
tokenOut = address(stEth);
} else if (direction == LidoV3Direction.StEthToWstEth) {
transferType = TransferManager.TransferType.ProtocolWillDebit;
receiver = address(wstEth);
tokenIn = address(stEth);
tokenOut = address(wstEth);
} else if (direction == LidoV3Direction.WstEthToStEth) {
transferType = TransferManager.TransferType.ProtocolWillDebit;
receiver = msg.sender;
tokenIn = address(wstEth);
tokenOut = address(stEth);
} else {
revert LidoV3Executor__InvalidDirection();
}

outputToRouter = true;
}

function _decodeData(bytes calldata data)
internal
pure
returns (LidoV3Direction direction)
{
if (data.length != 1) {
revert LidoV3Executor__InvalidDataLength();
}

uint8 rawDirection = uint8(data[0]);
if (rawDirection > uint8(LidoV3Direction.WstEthToStEth)) {
revert LidoV3Executor__InvalidDirection();
}

direction = LidoV3Direction(rawDirection);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {FluidV1Executor} from "../src/executors/FluidV1Executor.sol";
import {SlipstreamsExecutor} from "../src/executors/SlipstreamsExecutor.sol";
import {RocketpoolExecutor} from "../src/executors/RocketpoolExecutor.sol";
import {ERC4626Executor} from "../src/executors/ERC4626Executor.sol";
import {LidoV3Executor} from "../src/executors/LidoV3Executor.sol";
import {WethExecutor} from "../src/executors/WethExecutor.sol";
import {LiquoriceExecutor} from "../src/executors/LiquoriceExecutor.sol";
import {AerodromeV1Executor} from "../src/executors/AerodromeV1Executor.sol";
Expand Down Expand Up @@ -112,6 +113,7 @@ contract TychoRouterTestSetup is
RocketpoolExecutor public rocketpoolExecutor;
ERC4626Executor public erc4626Executor;
WethExecutor public wethExecutor;
LidoV3Executor public lidoV3Executor;
EkuboV3Executor public ekuboV3Executor;
EtherfiExecutor public etherfiExecutor;
LiquidityPartyExecutor public liquidityPartyExecutor;
Expand Down Expand Up @@ -213,8 +215,9 @@ contract TychoRouterTestSetup is
);
liquidityPartyExecutor = new LiquidityPartyExecutor();
aerodromeV1Executor = new AerodromeV1Executor();
lidoV3Executor = new LidoV3Executor(STETH_ADDR, WSTETH_ADDR);

address[] memory executors = new address[](21);
address[] memory executors = new address[](22);
executors[0] = address(usv2Executor);
executors[1] = address(usv3Executor);
executors[2] = address(pancakev3Executor);
Expand All @@ -236,6 +239,7 @@ contract TychoRouterTestSetup is
executors[18] = address(liquoriceExecutor);
executors[19] = address(liquidityPartyExecutor);
executors[20] = address(aerodromeV1Executor);
executors[21] = address(lidoV3Executor);
return executors;
}

Expand Down
4 changes: 4 additions & 0 deletions crates/tycho-execution/contracts/test/assets/calldata.txt
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,7 @@ test_two_hop_usv4_twif_intermediary:cd914fde000000000000000000000000000000000000
test_encode_aerodrome_v1:723aef6543aece026a15662be4d3fb3424d502a9236aa50979d5f3de3bd1eeb40e81137f22ab794bd9aaec86b65d86f6a7b5b1b0c42ffa531710b6ca01
test_single_encoding_strategy_aerodrome_v1:ce25e49e000000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000236aa50979d5f3de3bd1eeb40e81137f22ab794b000000000000000000000000d9aaec86b65d86f6a7b5b1b0c42ffa531710b6ca00000000000000000000000000000000000000000000000000000000000003e8000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000511af7f588a501ea2b5bb3feefa744892aa2cf00e6723aef6543aece026a15662be4d3fb3424d502a9236aa50979d5f3de3bd1eeb40e81137f22ab794bd9aaec86b65d86f6a7b5b1b0c42ffa531710b6ca01000000000000000000000000000000
test_sequential_encoding_strategy_aerodrome_v1:6fc8683a0000000000000000000000000000000000000000000000008ac7230489e800000000000000000000000000004621b7a9c75199271f773ebd9a499dbd165c3191000000000000000000000000236aa50979d5f3de3bd1eeb40e81137f22ab794b00000000000000000000000000000000000000000000000000000000000003e8000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a600511af7f588a501ea2b5bb3feefa744892aa2cf00e60b25c51637c43decd6cc1c1e3da4518d54ddb5284621b7a9c75199271f773ebd9a499dbd165c3191d9aaec86b65d86f6a7b5b1b0c42ffa531710b6ca0100511af7f588a501ea2b5bb3feefa744892aa2cf00e6723aef6543aece026a15662be4d3fb3424d502a9d9aaec86b65d86f6a7b5b1b0c42ffa531710b6ca236aa50979d5f3de3bd1eeb40e81137f22ab794b000000000000000000000000000000000000000000000000000000
test_single_encoding_strategy_lido_v3_wrap:ce25e49e0000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe840000000000000000000000007f39c581f595b53c5cb19bd0b3f8da6c935e2ca00000000000000000000000000000000000000000000000000b1a2bc2ec500000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015e8dc788818033232ef9772cb2e6622f1ec8bc840010000000000000000000000
test_sequential_encoding_strategy_lido_v3_submit_then_wrap:6fc8683a0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007f39c581f595b53c5cb19bd0b3f8da6c935e2ca00000000000000000000000000000000000000000000000000b1a2bc2ec500000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e0015e8dc788818033232ef9772cb2e6622f1ec8bc840000015e8dc788818033232ef9772cb2e6622f1ec8bc84001000000000000000000000000000000000000
test_single_encoding_strategy_lido_v3_unwrap:ce25e49e0000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000007f39c581f595b53c5cb19bd0b3f8da6c935e2ca0000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe840000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015e8dc788818033232ef9772cb2e6622f1ec8bc840020000000000000000000000
test_single_encoding_strategy_lido_v3_submit:ce25e49e0000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe840000000000000000000000000000000000000000000000000c7d713b49da0000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015e8dc788818033232ef9772cb2e6622f1ec8bc840000000000000000000000000
Loading
Loading