Merge branch 'refs/heads/main' into hooks/dc/ENG-4624-pass-hook-data
# Conflicts: # foundry/test/assets/calldata.txt Took 9 minutes
This commit is contained in:
@@ -44,7 +44,7 @@ module.exports = {
|
||||
},
|
||||
|
||||
tenderly: {
|
||||
project: "project",
|
||||
project: "tycho",
|
||||
username: "tvinagre",
|
||||
privateVerification: false,
|
||||
},
|
||||
|
||||
@@ -2,15 +2,15 @@
|
||||
pragma solidity ^0.8.26;
|
||||
|
||||
import {IFlashAccountant} from "./IFlashAccountant.sol";
|
||||
import {EkuboPoolKey} from "../types/poolKey.sol";
|
||||
import {PoolKey} from "../types/poolKey.sol";
|
||||
import {SqrtRatio} from "../types/sqrtRatio.sol";
|
||||
|
||||
interface ICore is IFlashAccountant {
|
||||
function swap_611415377(
|
||||
EkuboPoolKey memory poolKey,
|
||||
PoolKey memory poolKey,
|
||||
int128 amount,
|
||||
bool isToken1,
|
||||
SqrtRatio sqrtRatioLimit,
|
||||
uint256 skipAhead
|
||||
) external payable returns (int128 delta0, int128 delta1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,17 @@ interface IPayer {
|
||||
}
|
||||
|
||||
interface IFlashAccountant {
|
||||
// Forward the lock from the current locker to the given address
|
||||
// Any additional calldata is also passed through to the forwardee, with no additional encoding
|
||||
// In addition, any data returned from IForwardee#forwarded is also returned from this function exactly as is, i.e. with no additional encoding or decoding
|
||||
// Reverts are also bubbled up
|
||||
function forward(address to) external;
|
||||
|
||||
// Withdraws a token amount from the accountant to the given recipient.
|
||||
// The contract must be locked, as it tracks the withdrawn amount against the current locker's delta.
|
||||
function withdraw(address token, address recipient, uint128 amount) external;
|
||||
function withdraw(
|
||||
address token,
|
||||
address recipient,
|
||||
uint128 amount
|
||||
) external;
|
||||
}
|
||||
|
||||
@@ -1,12 +1,21 @@
|
||||
// SPDX-License-Identifier: UNLICENSED
|
||||
pragma solidity ^0.8.26;
|
||||
|
||||
using {extension} for Config global;
|
||||
|
||||
// address (20 bytes) | fee (8 bytes) | tickSpacing (4 bytes)
|
||||
type Config is bytes32;
|
||||
|
||||
// Each pool has its own state associated with this key
|
||||
struct EkuboPoolKey {
|
||||
struct PoolKey {
|
||||
address token0;
|
||||
address token1;
|
||||
Config config;
|
||||
}
|
||||
|
||||
function extension(Config config) pure returns (address e) {
|
||||
// slither-disable-next-line assembly
|
||||
assembly ("memory-safe") {
|
||||
e := shr(96, config)
|
||||
}
|
||||
}
|
||||
|
||||
3793
foundry/package-lock.json
generated
3793
foundry/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -9,7 +9,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@nomicfoundation/hardhat-foundry": "^1.1.3",
|
||||
"ethers": "^5.0.0",
|
||||
"@safe-global/api-kit": "^1.1.0",
|
||||
"@safe-global/protocol-kit": "^1.0.1",
|
||||
"ethers": "^5.8.0",
|
||||
"prompt-sync": "^4.2.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,4 +53,36 @@ For each of the following, you must select one of `tenderly_ethereum`, `tenderly
|
||||
|
||||
1. If you set a new executor for the same protocol, you need to remove the old one.
|
||||
2. Run: `npx hardhat run scripts/remove-executor.js --network NETWORK`
|
||||
3. There will be a prompt for you to insert the executor address you want to remove.
|
||||
3. There will be a prompt for you to insert the executor address you want to remove.
|
||||
|
||||
### Revoke roles
|
||||
|
||||
1. If you wish to revoke a role for a certain address, run: `npx hardhat run scripts/revoke-role.js --network NETWORK`
|
||||
2. There will be a prompt for you to insert the role hash and the address you want to revoke it for.
|
||||
|
||||
### Safe wallet
|
||||
|
||||
1. If the wallet that has the role, is a Gnosis Safe, you need to set the `SAFE_ADDRESS` env var.
|
||||
2. The scripts deploy-executors, remove-executor, set-roles and revoke-role all support this.
|
||||
1. If `SAFE_ADDRESS` is set, then it will propose a transaction to the safe wallet and later on it needs to be
|
||||
approved in their UI to execute on chain.
|
||||
2. If it's not set, it will submit the transaction directly to the chain.
|
||||
|
||||
## Deploy Uniswap X filler
|
||||
|
||||
The current script deploys an Uniswap X filler and verifies it in the corresponding blockchain explorer.
|
||||
|
||||
Make sure to run `unset HISTFILE` in your terminal before setting the private key. This will prevent the private key
|
||||
from being stored in the shell history.
|
||||
|
||||
1. Set the following environment variables:
|
||||
|
||||
```
|
||||
export RPC_URL=<chain-rpc-url>
|
||||
export PRIVATE_KEY=<deploy-wallet-private-key>
|
||||
export BLOCKCHAIN_EXPLORER_API_KEY=<blockchain-explorer-api-key>
|
||||
```
|
||||
|
||||
2. Confirm that the variables `tychoRouter`, `uniswapXReactor` and `nativeToken` are correctly set in the script. Make
|
||||
sure that the Uniswap X Reactor address matches the reactor you are targeting.
|
||||
3. Run `npx hardhat run scripts/deploy-uniswap-x-filler.js --network NETWORK`.
|
||||
|
||||
@@ -57,10 +57,11 @@ const executors_to_deploy = {
|
||||
},
|
||||
// Args: Permit2
|
||||
{exchange: "BalancerV2Executor", args: ["0x000000000022D473030F116dDEE9F6B43aC78BA3"]},
|
||||
// Args: Ekubo core contract, Permit2
|
||||
// Args: Ekubo core contract, mev resist, Permit2
|
||||
{
|
||||
exchange: "EkuboExecutor", args: [
|
||||
"0xe0e0e08A6A4b9Dc7bD67BCB7aadE5cF48157d444",
|
||||
"0x553a2EFc570c9e104942cEC6aC1c18118e54C091",
|
||||
"0x000000000022D473030F116dDEE9F6B43aC78BA3"
|
||||
]
|
||||
},
|
||||
@@ -78,6 +79,8 @@ const executors_to_deploy = {
|
||||
"0x000000000022D473030F116dDEE9F6B43aC78BA3"
|
||||
]
|
||||
},
|
||||
// Args: Permit2
|
||||
{exchange: "BalancerV3Executor", args: ["0x000000000022D473030F116dDEE9F6B43aC78BA3"]},
|
||||
],
|
||||
"base": [
|
||||
// Args: Factory, Pool Init Code Hash, Permit2, Fee BPS
|
||||
|
||||
63
foundry/scripts/deploy-uniswap-x-filler.js
Normal file
63
foundry/scripts/deploy-uniswap-x-filler.js
Normal file
@@ -0,0 +1,63 @@
|
||||
require('dotenv').config();
|
||||
const {ethers} = require("hardhat");
|
||||
const hre = require("hardhat");
|
||||
const path = require("path");
|
||||
const fs = require("fs");
|
||||
|
||||
async function main() {
|
||||
const network = hre.network.name;
|
||||
let uniswapXReactor;
|
||||
let nativeToken;
|
||||
if (network === "ethereum") {
|
||||
uniswapXReactor = "0x00000011F84B9aa48e5f8aA8B9897600006289Be";
|
||||
nativeToken = "0x0000000000000000000000000000000000000000";
|
||||
} else if (network === "base") {
|
||||
uniswapXReactor = "0x000000001Ec5656dcdB24D90DFa42742738De729";
|
||||
nativeToken = "0x0000000000000000000000000000000000000000";
|
||||
} else if (network === "unichain") {
|
||||
uniswapXReactor = "0x00000006021a6Bce796be7ba509BBBA71e956e37";
|
||||
nativeToken = "0x0000000000000000000000000000000000000000";
|
||||
} else {
|
||||
throw new Error(`Unsupported network: ${network}`);
|
||||
}
|
||||
|
||||
const routerAddressesFilePath = path.join(__dirname, "../../config/router_addresses.json");
|
||||
const tychoRouter = JSON.parse(fs.readFileSync(routerAddressesFilePath, "utf8"))[network];
|
||||
|
||||
console.log(`Deploying Uniswap X filler to ${network} with:`);
|
||||
console.log(`- Tycho router: ${tychoRouter}`);
|
||||
console.log(`- Uniswap X reactor: ${uniswapXReactor}`);
|
||||
console.log(`- Native token: ${nativeToken}`);
|
||||
|
||||
const [deployer] = await ethers.getSigners();
|
||||
console.log(`Deploying with account: ${deployer.address}`);
|
||||
console.log(`Account balance: ${ethers.utils.formatEther(await deployer.getBalance())} ETH`);
|
||||
|
||||
const UniswapXFiller = await ethers.getContractFactory("UniswapXFiller");
|
||||
const filler = await UniswapXFiller.deploy(tychoRouter, uniswapXReactor, nativeToken);
|
||||
|
||||
await filler.deployed();
|
||||
console.log(`Uniswap X Filler deployed to: ${filler.address}`);
|
||||
|
||||
console.log("Waiting for 1 minute before verifying the contract on the blockchain explorer...");
|
||||
await new Promise(resolve => setTimeout(resolve, 60000));
|
||||
|
||||
// Verify on Etherscan
|
||||
try {
|
||||
await hre.run("verify:verify", {
|
||||
address: filler.address,
|
||||
constructorArguments: [tychoRouter, uniswapXReactor, nativeToken],
|
||||
});
|
||||
console.log(`Uniswap X filler verified successfully on blockchain explorer!`);
|
||||
} catch (error) {
|
||||
console.error(`Error during blockchain explorer verification:`, error);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
main()
|
||||
.then(() => process.exit(0))
|
||||
.catch((error) => {
|
||||
console.error("Deployment failed:", error);
|
||||
process.exit(1);
|
||||
});
|
||||
@@ -1,16 +1,22 @@
|
||||
require('dotenv').config();
|
||||
const {ethers} = require("hardhat");
|
||||
const hre = require("hardhat");
|
||||
const {proposeOrSendTransaction} = require("./utils");
|
||||
const prompt = require('prompt-sync')();
|
||||
|
||||
async function main() {
|
||||
const network = hre.network.name;
|
||||
const routerAddress = process.env.ROUTER_ADDRESS;
|
||||
console.log(`Removing executors on TychoRouter at ${routerAddress} on ${network}`);
|
||||
const safeAddress = process.env.SAFE_ADDRESS;
|
||||
if (!routerAddress) {
|
||||
throw new Error("Missing ROUTER_ADDRESS");
|
||||
}
|
||||
|
||||
const [deployer] = await ethers.getSigners();
|
||||
console.log(`Removing executors with account: ${deployer.address}`);
|
||||
console.log(`Account balance: ${ethers.utils.formatEther(await deployer.getBalance())} ETH`);
|
||||
console.log(`Removing executor on TychoRouter at ${routerAddress} on ${network}`);
|
||||
|
||||
const [signer] = await ethers.getSigners();
|
||||
console.log(`Removing executors with account: ${signer.address}`);
|
||||
console.log(`Account balance: ${ethers.utils.formatEther(await signer.getBalance())} ETH`);
|
||||
|
||||
const TychoRouter = await ethers.getContractFactory("TychoRouter");
|
||||
const router = TychoRouter.attach(routerAddress);
|
||||
@@ -22,12 +28,15 @@ async function main() {
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Remove executor
|
||||
const tx = await router.removeExecutor(executorAddress, {
|
||||
const txData = {
|
||||
to: router.address,
|
||||
data: router.interface.encodeFunctionData("removeExecutor", [executorAddress]),
|
||||
value: "0",
|
||||
gasLimit: 50000
|
||||
});
|
||||
await tx.wait(); // Wait for the transaction to be mined
|
||||
console.log(`Executor removed at transaction: ${tx.hash}`);
|
||||
};
|
||||
|
||||
const txHash = await proposeOrSendTransaction(safeAddress, txData, signer, "removeExecutor");
|
||||
console.log(`TX hash: ${txHash}`);
|
||||
}
|
||||
|
||||
main()
|
||||
|
||||
51
foundry/scripts/revoke-role.js
Normal file
51
foundry/scripts/revoke-role.js
Normal file
@@ -0,0 +1,51 @@
|
||||
require('dotenv').config();
|
||||
const {ethers} = require("hardhat");
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const hre = require("hardhat");
|
||||
const {proposeOrSendTransaction} = require("./utils");
|
||||
const prompt = require('prompt-sync')();
|
||||
|
||||
async function main() {
|
||||
const network = hre.network.name;
|
||||
const routerAddress = process.env.ROUTER_ADDRESS;
|
||||
const safeAddress = process.env.SAFE_ADDRESS;
|
||||
if (!routerAddress) {
|
||||
throw new Error("Missing ROUTER_ADDRESS");
|
||||
}
|
||||
|
||||
console.log(`Revoking role on TychoRouter at ${routerAddress} on ${network}`);
|
||||
|
||||
const [signer] = await ethers.getSigners();
|
||||
console.log(`Setting roles with account: ${signer.address}`);
|
||||
console.log(`Account balance: ${ethers.utils.formatEther(await signer.getBalance())} ETH`);
|
||||
const TychoRouter = await ethers.getContractFactory("TychoRouter");
|
||||
const router = TychoRouter.attach(routerAddress);
|
||||
|
||||
const roleHash = prompt("Enter role hash to be removed: ");
|
||||
const address = prompt("Enter the address to remove: ");
|
||||
|
||||
|
||||
if (!roleHash || !address) {
|
||||
console.error("Please provide the executorAddress as an argument.");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log(`Revoking ${roleHash} to the following address:`, address);
|
||||
|
||||
const txData = {
|
||||
to: router.address,
|
||||
data: router.interface.encodeFunctionData("revokeRole", [roleHash, address]),
|
||||
value: "0",
|
||||
};
|
||||
|
||||
const txHash = await proposeOrSendTransaction(safeAddress, txData, signer, "revokeRole");
|
||||
console.log(`TX hash: ${txHash}`);
|
||||
}
|
||||
|
||||
main()
|
||||
.then(() => process.exit(0))
|
||||
.catch((error) => {
|
||||
console.error("Error setting roles:", error);
|
||||
process.exit(1);
|
||||
});
|
||||
@@ -1,44 +1,50 @@
|
||||
{
|
||||
"ethereum": {
|
||||
"EXECUTOR_SETTER_ROLE": [
|
||||
"0x58Dc7Bf9eD1f4890A7505D5bE4E4252978eAF655"
|
||||
"0x06e580B872a37402764f909FCcAb0Eb5bb38fe23"
|
||||
],
|
||||
"PAUSER_ROLE": [
|
||||
"0x58Dc7Bf9eD1f4890A7505D5bE4E4252978eAF655"
|
||||
"0xB279A562C726F9F3011c1945c9c23Fe1FB631B59",
|
||||
"0xAC3649A6DFBBB230632604f2fc43773977ec6E67"
|
||||
],
|
||||
"UNPAUSER_ROLE": [
|
||||
"0x58Dc7Bf9eD1f4890A7505D5bE4E4252978eAF655"
|
||||
"0xB279A562C726F9F3011c1945c9c23Fe1FB631B59",
|
||||
"0xAC3649A6DFBBB230632604f2fc43773977ec6E67"
|
||||
],
|
||||
"FUND_RESCUER_ROLE": [
|
||||
"0x58Dc7Bf9eD1f4890A7505D5bE4E4252978eAF655"
|
||||
"0xF621770E96bcf1335150faecf77D757faf7ca4A9"
|
||||
]
|
||||
},
|
||||
"base": {
|
||||
"EXECUTOR_SETTER_ROLE": [
|
||||
"0x58Dc7Bf9eD1f4890A7505D5bE4E4252978eAF655"
|
||||
"0x06e580B872a37402764f909FCcAb0Eb5bb38fe23"
|
||||
],
|
||||
"PAUSER_ROLE": [
|
||||
"0x58Dc7Bf9eD1f4890A7505D5bE4E4252978eAF655"
|
||||
"0xB279A562C726F9F3011c1945c9c23Fe1FB631B59",
|
||||
"0xAC3649A6DFBBB230632604f2fc43773977ec6E67"
|
||||
],
|
||||
"UNPAUSER_ROLE": [
|
||||
"0x58Dc7Bf9eD1f4890A7505D5bE4E4252978eAF655"
|
||||
"0xB279A562C726F9F3011c1945c9c23Fe1FB631B59",
|
||||
"0xAC3649A6DFBBB230632604f2fc43773977ec6E67"
|
||||
],
|
||||
"FUND_RESCUER_ROLE": [
|
||||
"0x58Dc7Bf9eD1f4890A7505D5bE4E4252978eAF655"
|
||||
"0xF621770E96bcf1335150faecf77D757faf7ca4A9"
|
||||
]
|
||||
},
|
||||
"unichain": {
|
||||
"EXECUTOR_SETTER_ROLE": [
|
||||
"0x58Dc7Bf9eD1f4890A7505D5bE4E4252978eAF655"
|
||||
"0x06e580B872a37402764f909FCcAb0Eb5bb38fe23"
|
||||
],
|
||||
"PAUSER_ROLE": [
|
||||
"0x58Dc7Bf9eD1f4890A7505D5bE4E4252978eAF655"
|
||||
"0xB279A562C726F9F3011c1945c9c23Fe1FB631B59",
|
||||
"0xAC3649A6DFBBB230632604f2fc43773977ec6E67"
|
||||
],
|
||||
"UNPAUSER_ROLE": [
|
||||
"0x58Dc7Bf9eD1f4890A7505D5bE4E4252978eAF655"
|
||||
"0xB279A562C726F9F3011c1945c9c23Fe1FB631B59",
|
||||
"0xAC3649A6DFBBB230632604f2fc43773977ec6E67"
|
||||
],
|
||||
"FUND_RESCUER_ROLE": [
|
||||
"0x58Dc7Bf9eD1f4890A7505D5bE4E4252978eAF655"
|
||||
"0xF621770E96bcf1335150faecf77D757faf7ca4A9"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,25 @@
|
||||
require('dotenv').config();
|
||||
const {ethers} = require("hardhat");
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const hre = require("hardhat");
|
||||
const path = require('path');
|
||||
const {proposeOrSendTransaction} = require("./utils");
|
||||
const prompt = require('prompt-sync')();
|
||||
|
||||
async function main() {
|
||||
const network = hre.network.name;
|
||||
const routerAddress = process.env.ROUTER_ADDRESS;
|
||||
const safeAddress = process.env.SAFE_ADDRESS;
|
||||
if (!routerAddress) {
|
||||
throw new Error("Missing ROUTER_ADDRESS");
|
||||
}
|
||||
|
||||
console.log(`Setting executors on TychoRouter at ${routerAddress} on ${network}`);
|
||||
|
||||
const [deployer] = await ethers.getSigners();
|
||||
console.log(`Setting executors with account: ${deployer.address}`);
|
||||
console.log(`Account balance: ${ethers.utils.formatEther(await deployer.getBalance())} ETH`);
|
||||
const [signer] = await ethers.getSigners();
|
||||
const balance = await signer.getBalance();
|
||||
|
||||
console.log(`Using signer: ${signer.address}`);
|
||||
console.log(`Account balance: ${ethers.utils.formatEther(balance)} ETH`);
|
||||
|
||||
const TychoRouter = await ethers.getContractFactory("TychoRouter");
|
||||
const router = TychoRouter.attach(routerAddress);
|
||||
@@ -48,13 +55,16 @@ async function main() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Set executors
|
||||
const executorAddresses = executorsToSet.map(executor => executor.executor);
|
||||
const tx = await router.setExecutors(executorAddresses, {
|
||||
gasLimit: 300000 // should be around 50k per executor
|
||||
});
|
||||
await tx.wait(); // Wait for the transaction to be mined
|
||||
console.log(`Executors set at transaction: ${tx.hash}`);
|
||||
const executorAddresses = executorsToSet.map(({executor}) => executor);
|
||||
const txData = {
|
||||
to: router.address,
|
||||
data: router.interface.encodeFunctionData("setExecutors", [executorAddresses]),
|
||||
value: "0",
|
||||
gasLimit: 300000
|
||||
};
|
||||
|
||||
const txHash = await proposeOrSendTransaction(safeAddress, txData, signer, "setExecutors");
|
||||
console.log(`TX hash: ${txHash}`);
|
||||
}
|
||||
|
||||
main()
|
||||
|
||||
@@ -3,15 +3,21 @@ const {ethers} = require("hardhat");
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const hre = require("hardhat");
|
||||
const {proposeOrSendTransaction} = require("./utils");
|
||||
|
||||
async function main() {
|
||||
const network = hre.network.name;
|
||||
const routerAddress = process.env.ROUTER_ADDRESS;
|
||||
const safeAddress = process.env.SAFE_ADDRESS;
|
||||
if (!routerAddress) {
|
||||
throw new Error("Missing ROUTER_ADDRESS");
|
||||
}
|
||||
|
||||
console.log(`Setting roles on TychoRouter at ${routerAddress} on ${network}`);
|
||||
|
||||
const [deployer] = await ethers.getSigners();
|
||||
console.log(`Setting roles with account: ${deployer.address}`);
|
||||
console.log(`Account balance: ${ethers.utils.formatEther(await deployer.getBalance())} ETH`);
|
||||
const [signer] = await ethers.getSigners();
|
||||
console.log(`Setting roles with account: ${signer.address}`);
|
||||
console.log(`Account balance: ${ethers.utils.formatEther(await signer.getBalance())} ETH`);
|
||||
const TychoRouter = await ethers.getContractFactory("TychoRouter");
|
||||
const router = TychoRouter.attach(routerAddress);
|
||||
|
||||
@@ -20,7 +26,6 @@ async function main() {
|
||||
|
||||
const roles = {
|
||||
EXECUTOR_SETTER_ROLE: "0x6a1dd52dcad5bd732e45b6af4e7344fa284e2d7d4b23b5b09cb55d36b0685c87",
|
||||
FEE_SETTER_ROLE: "0xe6ad9a47fbda1dc18de1eb5eeb7d935e5e81b4748f3cfc61e233e64f88182060",
|
||||
PAUSER_ROLE: "0x65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a",
|
||||
UNPAUSER_ROLE: "0x427da25fe773164f88948d3e215c94b6554e2ed5e5f203a821c9f2f6131cf75a",
|
||||
FUND_RESCUER_ROLE: "0x912e45d663a6f4cc1d0491d8f046e06c616f40352565ea1cdb86a0e1aaefa41b"
|
||||
@@ -31,9 +36,15 @@ async function main() {
|
||||
const addresses = rolesDict[network][roleName];
|
||||
if (addresses && addresses.length > 0) {
|
||||
console.log(`Granting ${roleName} to the following addresses:`, addresses);
|
||||
const tx = await router.batchGrantRole(roleHash, addresses);
|
||||
await tx.wait(); // Wait for the transaction to be mined
|
||||
console.log(`Role ${roleName} granted at transaction: ${tx.hash}`);
|
||||
|
||||
const txData = {
|
||||
to: router.address,
|
||||
data: router.interface.encodeFunctionData("batchGrantRole", [roleHash, addresses]),
|
||||
value: "0",
|
||||
};
|
||||
|
||||
const txHash = await proposeOrSendTransaction(safeAddress, txData, signer, "batchGrantRole");
|
||||
console.log(`Role ${roleName} granted at TX hash: ${txHash}`);
|
||||
} else {
|
||||
console.log(`No addresses found for role ${roleName}`);
|
||||
}
|
||||
|
||||
66
foundry/scripts/utils.js
Normal file
66
foundry/scripts/utils.js
Normal file
@@ -0,0 +1,66 @@
|
||||
const {ethers} = require("hardhat");
|
||||
const Safe = require('@safe-global/protocol-kit').default;
|
||||
const {EthersAdapter} = require('@safe-global/protocol-kit');
|
||||
const {default: SafeApiKit} = require("@safe-global/api-kit");
|
||||
|
||||
const txServiceUrls = {
|
||||
mainnet: "https://safe-transaction-mainnet.safe.global",
|
||||
base: "https://safe-transaction-base.safe.global",
|
||||
unichain: "https://safe-transaction-unichain.safe.global",
|
||||
};
|
||||
|
||||
const txServiceUrl = txServiceUrls[hre.network.name];
|
||||
|
||||
async function proposeOrSendTransaction(safeAddress, txData, signer, methodName) {
|
||||
if (safeAddress) {
|
||||
return proposeTransaction(safeAddress, txData, signer, methodName);
|
||||
} else {
|
||||
console.log(`Executing the transaction directly`);
|
||||
const tx = await signer.sendTransaction(txData);
|
||||
await tx.wait();
|
||||
return tx.hash;
|
||||
}
|
||||
}
|
||||
|
||||
async function proposeTransaction(safeAddress, txData, signer, methodName) {
|
||||
const signerAddress = await signer.getAddress();
|
||||
console.log(`Proposing transaction to Safe: ${safeAddress} with account: ${signerAddress}`);
|
||||
|
||||
const ethAdapter = new EthersAdapter({
|
||||
ethers,
|
||||
signerOrProvider: signer,
|
||||
});
|
||||
|
||||
const safeService = new SafeApiKit({txServiceUrl, ethAdapter});
|
||||
|
||||
const safeSdk = await Safe.create({
|
||||
ethAdapter,
|
||||
safeAddress,
|
||||
});
|
||||
let next_nonce = await safeService.getNextNonce(safeAddress);
|
||||
const safeTransaction = await safeSdk.createTransaction({
|
||||
safeTransactionData: {
|
||||
...txData,
|
||||
nonce: next_nonce
|
||||
}
|
||||
});
|
||||
const safeTxHash = await safeSdk.getTransactionHash(safeTransaction);
|
||||
const senderSignature = await safeSdk.signTransactionHash(safeTxHash);
|
||||
|
||||
const proposeArgs = {
|
||||
safeAddress,
|
||||
safeTransactionData: safeTransaction.data,
|
||||
safeTxHash,
|
||||
senderAddress: signerAddress,
|
||||
senderSignature: senderSignature.data,
|
||||
origin: `Proposed from hardhat: ${methodName}`,
|
||||
nonce: next_nonce,
|
||||
};
|
||||
|
||||
await safeService.proposeTransaction(proposeArgs);
|
||||
return safeTxHash;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
proposeOrSendTransaction
|
||||
}
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
VaultSwapParams
|
||||
} from "@balancer-labs/v3-interfaces/contracts/vault/VaultTypes.sol";
|
||||
import {RestrictTransferFrom} from "../RestrictTransferFrom.sol";
|
||||
import {ICallback} from "../../interfaces/ICallback.sol";
|
||||
import {ICallback} from "@interfaces/ICallback.sol";
|
||||
|
||||
error BalancerV3Executor__InvalidDataLength();
|
||||
error BalancerV3Executor__SenderIsNotVault(address sender);
|
||||
|
||||
@@ -9,8 +9,12 @@ import {ILocker, IPayer} from "@ekubo/interfaces/IFlashAccountant.sol";
|
||||
import {NATIVE_TOKEN_ADDRESS} from "@ekubo/math/constants.sol";
|
||||
import {SafeTransferLib} from "@solady/utils/SafeTransferLib.sol";
|
||||
import {LibBytes} from "@solady/utils/LibBytes.sol";
|
||||
import {Config, EkuboPoolKey} from "@ekubo/types/poolKey.sol";
|
||||
import {MAX_SQRT_RATIO, MIN_SQRT_RATIO} from "@ekubo/types/sqrtRatio.sol";
|
||||
import {Config, PoolKey} from "@ekubo/types/poolKey.sol";
|
||||
import {
|
||||
MAX_SQRT_RATIO,
|
||||
MIN_SQRT_RATIO,
|
||||
SqrtRatio
|
||||
} from "@ekubo/types/sqrtRatio.sol";
|
||||
import {RestrictTransferFrom} from "../RestrictTransferFrom.sol";
|
||||
import "@openzeppelin/contracts/utils/Address.sol";
|
||||
|
||||
@@ -21,11 +25,13 @@ contract EkuboExecutor is
|
||||
ICallback,
|
||||
RestrictTransferFrom
|
||||
{
|
||||
error EkuboExecutor__AddressZero();
|
||||
error EkuboExecutor__InvalidDataLength();
|
||||
error EkuboExecutor__CoreOnly();
|
||||
error EkuboExecutor__UnknownCallback();
|
||||
|
||||
ICore immutable core;
|
||||
address immutable mevResist;
|
||||
|
||||
uint256 constant POOL_DATA_OFFSET = 57;
|
||||
uint256 constant HOP_BYTE_LEN = 52;
|
||||
@@ -33,12 +39,19 @@ contract EkuboExecutor is
|
||||
bytes4 constant LOCKED_SELECTOR = 0xb45a3c0e; // locked(uint256)
|
||||
bytes4 constant PAY_CALLBACK_SELECTOR = 0x599d0714; // payCallback(uint256,address)
|
||||
|
||||
uint256 constant SKIP_AHEAD = 0;
|
||||
|
||||
using SafeERC20 for IERC20;
|
||||
|
||||
constructor(address _core, address _permit2)
|
||||
constructor(address _core, address _mevResist, address _permit2)
|
||||
RestrictTransferFrom(_permit2)
|
||||
{
|
||||
core = ICore(_core);
|
||||
|
||||
if (_mevResist == address(0)) {
|
||||
revert EkuboExecutor__AddressZero();
|
||||
}
|
||||
mevResist = _mevResist;
|
||||
}
|
||||
|
||||
function swap(uint256 amountIn, bytes calldata data)
|
||||
@@ -141,19 +154,40 @@ contract EkuboExecutor is
|
||||
Config poolConfig =
|
||||
Config.wrap(LibBytes.loadCalldata(swapData, offset + 20));
|
||||
|
||||
(address token0, address token1, bool isToken1) = nextTokenIn
|
||||
> nextTokenOut
|
||||
? (nextTokenOut, nextTokenIn, true)
|
||||
: (nextTokenIn, nextTokenOut, false);
|
||||
(
|
||||
address token0,
|
||||
address token1,
|
||||
bool isToken1,
|
||||
SqrtRatio sqrtRatioLimit
|
||||
) = nextTokenIn > nextTokenOut
|
||||
? (nextTokenOut, nextTokenIn, true, MAX_SQRT_RATIO)
|
||||
: (nextTokenIn, nextTokenOut, false, MIN_SQRT_RATIO);
|
||||
|
||||
// slither-disable-next-line calls-loop
|
||||
(int128 delta0, int128 delta1) = core.swap_611415377(
|
||||
EkuboPoolKey(token0, token1, poolConfig),
|
||||
nextAmountIn,
|
||||
isToken1,
|
||||
isToken1 ? MAX_SQRT_RATIO : MIN_SQRT_RATIO,
|
||||
0
|
||||
);
|
||||
PoolKey memory pk = PoolKey(token0, token1, poolConfig);
|
||||
|
||||
int128 delta0;
|
||||
int128 delta1;
|
||||
|
||||
if (poolConfig.extension() == mevResist) {
|
||||
(delta0, delta1) = abi.decode(
|
||||
_forward(
|
||||
mevResist,
|
||||
abi.encode(
|
||||
pk,
|
||||
nextAmountIn,
|
||||
isToken1,
|
||||
sqrtRatioLimit,
|
||||
SKIP_AHEAD
|
||||
)
|
||||
),
|
||||
(int128, int128)
|
||||
);
|
||||
} else {
|
||||
// slither-disable-next-line calls-loop
|
||||
(delta0, delta1) = core.swap_611415377(
|
||||
pk, nextAmountIn, isToken1, sqrtRatioLimit, SKIP_AHEAD
|
||||
);
|
||||
}
|
||||
|
||||
nextTokenIn = nextTokenOut;
|
||||
nextAmountIn = -(isToken1 ? delta0 : delta1);
|
||||
@@ -166,6 +200,45 @@ contract EkuboExecutor is
|
||||
return nextAmountIn;
|
||||
}
|
||||
|
||||
function _forward(address to, bytes memory data)
|
||||
internal
|
||||
returns (bytes memory result)
|
||||
{
|
||||
address target = address(core);
|
||||
|
||||
// slither-disable-next-line assembly
|
||||
assembly ("memory-safe") {
|
||||
// We will store result where the free memory pointer is now, ...
|
||||
result := mload(0x40)
|
||||
|
||||
// But first use it to store the calldata
|
||||
|
||||
// Selector of forward(address)
|
||||
mstore(result, shl(224, 0x101e8952))
|
||||
mstore(add(result, 4), to)
|
||||
|
||||
// We only copy the data, not the length, because the length is read from the calldata size
|
||||
let len := mload(data)
|
||||
mcopy(add(result, 36), add(data, 32), len)
|
||||
|
||||
// If the call failed, pass through the revert
|
||||
if iszero(call(gas(), target, 0, result, add(36, len), 0, 0)) {
|
||||
returndatacopy(result, 0, returndatasize())
|
||||
revert(result, returndatasize())
|
||||
}
|
||||
|
||||
// Copy the entire return data into the space where the result is pointing
|
||||
mstore(result, returndatasize())
|
||||
returndatacopy(add(result, 32), 0, returndatasize())
|
||||
|
||||
// Update the free memory pointer to be after the end of the data, aligned to the next 32 byte word
|
||||
mstore(
|
||||
0x40,
|
||||
and(add(add(result, add(32, returndatasize())), 31), not(31))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
function _pay(address token, uint128 amount, TransferType transferType)
|
||||
internal
|
||||
{
|
||||
|
||||
31
foundry/src/uniswap_x/IReactor.sol
Normal file
31
foundry/src/uniswap_x/IReactor.sol
Normal file
@@ -0,0 +1,31 @@
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
pragma solidity ^0.8.26;
|
||||
|
||||
import {SignedOrder} from "./IStructs.sol";
|
||||
import {IReactorCallback} from "./IReactorCallback.sol";
|
||||
|
||||
/// @notice Interface for order execution reactors
|
||||
interface IReactor {
|
||||
/// @notice Execute a single order
|
||||
/// @param order The order definition and valid signature to execute
|
||||
function execute(SignedOrder calldata order) external payable;
|
||||
|
||||
/// @notice Execute a single order using the given callback data
|
||||
/// @param order The order definition and valid signature to execute
|
||||
function executeWithCallback(
|
||||
SignedOrder calldata order,
|
||||
bytes calldata callbackData
|
||||
) external payable;
|
||||
|
||||
/// @notice Execute the given orders at once
|
||||
/// @param orders The order definitions and valid signatures to execute
|
||||
function executeBatch(SignedOrder[] calldata orders) external payable;
|
||||
|
||||
/// @notice Execute the given orders at once using a callback with the given callback data
|
||||
/// @param orders The order definitions and valid signatures to execute
|
||||
/// @param callbackData The callbackData to pass to the callback
|
||||
function executeBatchWithCallback(
|
||||
SignedOrder[] calldata orders,
|
||||
bytes calldata callbackData
|
||||
) external payable;
|
||||
}
|
||||
16
foundry/src/uniswap_x/IReactorCallback.sol
Normal file
16
foundry/src/uniswap_x/IReactorCallback.sol
Normal file
@@ -0,0 +1,16 @@
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
pragma solidity ^0.8.26;
|
||||
|
||||
import "./IStructs.sol";
|
||||
|
||||
/// @notice Callback for executing orders through a reactor.
|
||||
interface IReactorCallback {
|
||||
/// @notice Called by the reactor during the execution of an order
|
||||
/// @param resolvedOrders Has inputs and outputs
|
||||
/// @param fillData The fillData specified for an order execution
|
||||
/// @dev Must have approved each token and amount in outputs to the msg.sender
|
||||
function reactorCallback(
|
||||
ResolvedOrder[] memory resolvedOrders,
|
||||
bytes memory fillData
|
||||
) external;
|
||||
}
|
||||
114
foundry/src/uniswap_x/IStructs.sol
Normal file
114
foundry/src/uniswap_x/IStructs.sol
Normal file
@@ -0,0 +1,114 @@
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
pragma solidity ^0.8.26;
|
||||
|
||||
/// @dev external struct including a generic encoded order and swapper signature
|
||||
/// The order bytes will be parsed and mapped to a ResolvedOrder in the concrete reactor contract
|
||||
struct SignedOrder {
|
||||
bytes order;
|
||||
bytes sig;
|
||||
}
|
||||
|
||||
struct OrderInfo {
|
||||
// The address of the reactor that this order is targeting
|
||||
// Note that this must be included in every order so the swapper
|
||||
// signature commits to the specific reactor that they trust to fill their order properly
|
||||
address reactor;
|
||||
// The address of the user which created the order
|
||||
// Note that this must be included so that order hashes are unique by swapper
|
||||
address swapper;
|
||||
// The nonce of the order, allowing for signature replay protection and cancellation
|
||||
uint256 nonce;
|
||||
// The timestamp after which this order is no longer valid
|
||||
uint256 deadline;
|
||||
// Custom validation contract
|
||||
address additionalValidationContract;
|
||||
// Encoded validation params for additionalValidationContract
|
||||
bytes additionalValidationData;
|
||||
}
|
||||
|
||||
/// @dev tokens that need to be sent from the swapper in order to satisfy an order
|
||||
struct InputToken {
|
||||
address token;
|
||||
uint256 amount;
|
||||
// Needed for dutch decaying inputs
|
||||
uint256 maxAmount;
|
||||
}
|
||||
|
||||
/// @dev tokens that need to be received by the recipient in order to satisfy an order
|
||||
struct OutputToken {
|
||||
address token;
|
||||
uint256 amount;
|
||||
address recipient;
|
||||
}
|
||||
|
||||
/// @dev generic concrete order that specifies exact tokens which need to be sent and received
|
||||
struct ResolvedOrder {
|
||||
OrderInfo info;
|
||||
InputToken input;
|
||||
OutputToken[] outputs;
|
||||
bytes sig;
|
||||
bytes32 hash;
|
||||
}
|
||||
|
||||
struct DutchOutput {
|
||||
address token;
|
||||
uint256 startAmount;
|
||||
uint256 endAmount;
|
||||
address recipient;
|
||||
}
|
||||
|
||||
struct DutchInput {
|
||||
address token;
|
||||
uint256 startAmount;
|
||||
uint256 endAmount;
|
||||
}
|
||||
|
||||
struct ExclusiveDutchOrder {
|
||||
OrderInfo info;
|
||||
uint256 decayStartTime;
|
||||
uint256 decayEndTime;
|
||||
address exclusiveFiller;
|
||||
uint256 exclusivityOverrideBps;
|
||||
DutchInput input;
|
||||
DutchOutput[] outputs;
|
||||
}
|
||||
|
||||
struct DutchOrder {
|
||||
OrderInfo info;
|
||||
uint256 decayStartTime;
|
||||
uint256 decayEndTime;
|
||||
address exclusiveFiller;
|
||||
uint256 exclusivityOverrideBps;
|
||||
DutchInput input;
|
||||
DutchOutput[] outputs;
|
||||
}
|
||||
|
||||
struct CosignerData {
|
||||
// The time at which the DutchOutputs start decaying
|
||||
uint256 decayStartTime;
|
||||
// The time at which price becomes static
|
||||
uint256 decayEndTime;
|
||||
// The address who has exclusive rights to the order until decayStartTime
|
||||
address exclusiveFiller;
|
||||
// The amount in bps that a non-exclusive filler needs to improve the outputs by to be able to fill the order
|
||||
uint256 exclusivityOverrideBps;
|
||||
// The tokens that the swapper will provide when settling the order
|
||||
uint256 inputAmount;
|
||||
// The tokens that must be received to satisfy the order
|
||||
uint256[] outputAmounts;
|
||||
}
|
||||
|
||||
struct V2DutchOrder {
|
||||
// generic order information
|
||||
OrderInfo info;
|
||||
// The address which must cosign the full order
|
||||
address cosigner;
|
||||
// The tokens that the swapper will provide when settling the order
|
||||
DutchInput baseInput;
|
||||
// The tokens that must be received to satisfy the order
|
||||
DutchOutput[] baseOutputs;
|
||||
// signed over by the cosigner
|
||||
CosignerData cosignerData;
|
||||
// signature from the cosigner over (orderHash || cosignerData)
|
||||
bytes cosignature;
|
||||
}
|
||||
164
foundry/src/uniswap_x/UniswapXFiller.sol
Normal file
164
foundry/src/uniswap_x/UniswapXFiller.sol
Normal file
@@ -0,0 +1,164 @@
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
pragma solidity ^0.8.26;
|
||||
|
||||
import "./IReactor.sol";
|
||||
import "./IReactorCallback.sol";
|
||||
import {
|
||||
SafeERC20,
|
||||
IERC20
|
||||
} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
|
||||
import "@openzeppelin/contracts/access/AccessControl.sol";
|
||||
import "@openzeppelin/contracts/utils/Address.sol";
|
||||
import {TychoRouter} from "../TychoRouter.sol";
|
||||
|
||||
error UniswapXFiller__AddressZero();
|
||||
error UniswapXFiller__BatchExecutionNotSupported();
|
||||
|
||||
contract UniswapXFiller is AccessControl, IReactorCallback {
|
||||
using SafeERC20 for IERC20;
|
||||
|
||||
// UniswapX V2DutchOrder Reactor
|
||||
IReactor public immutable reactor;
|
||||
address public immutable tychoRouter;
|
||||
address public immutable nativeAddress;
|
||||
|
||||
// keccak256("NAME_OF_ROLE") : save gas on deployment
|
||||
bytes32 public constant REACTOR_ROLE =
|
||||
0x39dd1d7269516fc1f719706a5e9b05cdcb1644978808b171257d9a8eab55dd57;
|
||||
bytes32 public constant EXECUTOR_ROLE =
|
||||
0xd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e63;
|
||||
|
||||
event Withdrawal(
|
||||
address indexed token, uint256 amount, address indexed receiver
|
||||
);
|
||||
|
||||
constructor(
|
||||
address _tychoRouter,
|
||||
address _reactor,
|
||||
address _native_address
|
||||
) {
|
||||
if (_tychoRouter == address(0)) revert UniswapXFiller__AddressZero();
|
||||
if (_reactor == address(0)) revert UniswapXFiller__AddressZero();
|
||||
|
||||
_grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
|
||||
_grantRole(REACTOR_ROLE, address(_reactor));
|
||||
tychoRouter = _tychoRouter;
|
||||
reactor = IReactor(_reactor);
|
||||
|
||||
// slither-disable-next-line missing-zero-check
|
||||
nativeAddress = _native_address;
|
||||
}
|
||||
|
||||
function execute(SignedOrder calldata order, bytes calldata callbackData)
|
||||
external
|
||||
onlyRole(EXECUTOR_ROLE)
|
||||
{
|
||||
reactor.executeWithCallback(order, callbackData);
|
||||
}
|
||||
|
||||
function reactorCallback(
|
||||
ResolvedOrder[] calldata resolvedOrders,
|
||||
bytes calldata callbackData
|
||||
) external onlyRole(REACTOR_ROLE) {
|
||||
require(
|
||||
resolvedOrders.length == 1,
|
||||
UniswapXFiller__BatchExecutionNotSupported()
|
||||
);
|
||||
|
||||
ResolvedOrder memory order = resolvedOrders[0];
|
||||
|
||||
bool tokenInApprovalNeeded = bool(uint8(callbackData[0]) == 1);
|
||||
bool tokenOutApprovalNeeded = bool(uint8(callbackData[1]) == 1);
|
||||
bytes calldata tychoCalldata = bytes(callbackData[2:]);
|
||||
|
||||
// The TychoRouter will take the input tokens from the filler
|
||||
if (tokenInApprovalNeeded) {
|
||||
// Native ETH input is not supported by UniswapX
|
||||
IERC20(order.input.token).forceApprove(
|
||||
tychoRouter, type(uint256).max
|
||||
);
|
||||
}
|
||||
|
||||
// slither-disable-next-line low-level-calls
|
||||
(bool success, bytes memory result) = tychoRouter.call(tychoCalldata);
|
||||
|
||||
if (!success) {
|
||||
revert(
|
||||
string(
|
||||
result.length > 0
|
||||
? result
|
||||
: abi.encodePacked("Execution failed")
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (tokenOutApprovalNeeded) {
|
||||
// Multiple outputs are possible when taking fees - but token itself should
|
||||
// not change.
|
||||
OutputToken memory output = order.outputs[0];
|
||||
if (output.token != nativeAddress) {
|
||||
IERC20 token = IERC20(output.token);
|
||||
token.forceApprove(address(reactor), type(uint256).max);
|
||||
} else {
|
||||
// With native ETH - the filler is responsible for transferring back
|
||||
// to the reactor.
|
||||
Address.sendValue(payable(address(reactor)), output.amount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Allows granting roles to multiple accounts in a single call.
|
||||
*/
|
||||
function batchGrantRole(bytes32 role, address[] memory accounts)
|
||||
external
|
||||
onlyRole(DEFAULT_ADMIN_ROLE)
|
||||
{
|
||||
for (uint256 i = 0; i < accounts.length; i++) {
|
||||
_grantRole(role, accounts[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Allows withdrawing any ERC20 funds.
|
||||
*/
|
||||
function withdraw(IERC20[] memory tokens, address receiver)
|
||||
external
|
||||
onlyRole(DEFAULT_ADMIN_ROLE)
|
||||
{
|
||||
if (receiver == address(0)) revert UniswapXFiller__AddressZero();
|
||||
|
||||
for (uint256 i = 0; i < tokens.length; i++) {
|
||||
// slither-disable-next-line calls-loop
|
||||
uint256 tokenBalance = tokens[i].balanceOf(address(this));
|
||||
if (tokenBalance > 0) {
|
||||
emit Withdrawal(address(tokens[i]), tokenBalance, receiver);
|
||||
tokens[i].safeTransfer(receiver, tokenBalance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Allows withdrawing any NATIVE funds.
|
||||
*/
|
||||
function withdrawNative(address receiver)
|
||||
external
|
||||
onlyRole(DEFAULT_ADMIN_ROLE)
|
||||
{
|
||||
if (receiver == address(0)) revert UniswapXFiller__AddressZero();
|
||||
|
||||
uint256 amount = address(this).balance;
|
||||
if (amount > 0) {
|
||||
emit Withdrawal(address(0), amount, receiver);
|
||||
Address.sendValue(payable(receiver), amount);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Allows this contract to receive native token with empty msg.data from contracts
|
||||
*/
|
||||
// slither-disable-next-line locked-ether
|
||||
receive() external payable {
|
||||
require(msg.sender.code.length != 0);
|
||||
}
|
||||
}
|
||||
@@ -77,6 +77,7 @@ contract Constants is Test, BaseConstants {
|
||||
|
||||
// Uniswap v3
|
||||
address DAI_WETH_USV3 = 0xC2e9F25Be6257c210d7Adf0D4Cd6E3E881ba25f8;
|
||||
address DAI_USDT_USV3 = 0x48DA0965ab2d2cbf1C17C09cFB5Cbe67Ad5B1406;
|
||||
address USDC_WETH_USV3 = 0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640; // 0.05% fee
|
||||
address USDC_WETH_USV3_2 = 0x8ad599c3A0ff1De082011EFDDc58f1908eb6e6D8; // 0.3% fee
|
||||
|
||||
|
||||
@@ -96,7 +96,6 @@ contract TychoRouterTest is TychoRouterTestSetup {
|
||||
}
|
||||
|
||||
vm.startPrank(FUND_RESCUER);
|
||||
|
||||
tychoRouter.withdraw(tokens, FUND_RESCUER);
|
||||
|
||||
// Check balances after withdrawing
|
||||
|
||||
@@ -114,6 +114,7 @@ contract TychoRouterTestSetup is Constants, Permit2TestHelper, TestUtils {
|
||||
bytes32 initCodePancakeV3 = PANCAKEV3_POOL_CODE_INIT_HASH;
|
||||
address poolManagerAddress = 0x000000000004444c5dc75cB358380D2e3dE08A90;
|
||||
address ekuboCore = 0xe0e0e08A6A4b9Dc7bD67BCB7aadE5cF48157d444;
|
||||
address ekuboMevResist = 0x553a2EFc570c9e104942cEC6aC1c18118e54C091;
|
||||
|
||||
IPoolManager poolManager = IPoolManager(poolManagerAddress);
|
||||
usv2Executor =
|
||||
@@ -125,7 +126,8 @@ contract TychoRouterTestSetup is Constants, Permit2TestHelper, TestUtils {
|
||||
factoryPancakeV3, initCodePancakeV3, PERMIT2_ADDRESS
|
||||
);
|
||||
balancerv2Executor = new BalancerV2Executor(PERMIT2_ADDRESS);
|
||||
ekuboExecutor = new EkuboExecutor(ekuboCore, PERMIT2_ADDRESS);
|
||||
ekuboExecutor =
|
||||
new EkuboExecutor(ekuboCore, ekuboMevResist, PERMIT2_ADDRESS);
|
||||
curveExecutor = new CurveExecutor(ETH_ADDR_FOR_CURVE, PERMIT2_ADDRESS);
|
||||
maverickv2Executor =
|
||||
new MaverickV2Executor(MAVERICK_V2_FACTORY, PERMIT2_ADDRESS);
|
||||
|
||||
@@ -3,33 +3,34 @@ test_single_encoding_strategy_ekubo:5c4b639c000000000000000000000000000000000000
|
||||
test_uniswap_v3_uniswap_v3:e21dd0d30000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000d600692e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc22260fac5e5542a773aa44fbcfedf7c193bc2c599000bb83ede3eca2a72b3aecc820e955b36f38437d01395cbcdf9626bc03e24f779434178a73a0b4bad62ed000000692e234dae75c793f67a35089c9d99245e1c58470b2260fac5e5542a773aa44fbcfedf7c193bc2c599a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000bb8cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc299ac8ca7087fa4a2a1fb6357269965a2014abc35010100000000000000000000
|
||||
test_balancer_v2_uniswap_v2:e21dd0d30000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000c80072c7183455a4c133ae270771860664b6b7ec320bb1c02aaa39b223fe8d0a0e5c4f27ead9083c756cc22260fac5e5542a773aa44fbcfedf7c193bc2c599a6f548df93de924d73be7d25dc02554c6bd66db500020000000000000000000e004375dff511095cc5a197a54140a24efef3a416010000525615deb798bb3e4dfa0139dfa1b3d433cc23b72f2260fac5e5542a773aa44fbcfedf7c193bc2c599004375dff511095cc5a197a54140a24efef3a416cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20102000000000000000000000000000000000000000000000000
|
||||
test_sequential_swap_strategy_encoder_no_permit2:e21dd0d30000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000a800525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2bb2b8038a1640196fbe3e38816f3e67cba72d940004375dff511095cc5a197a54140a24efef3a416000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72f2260fac5e5542a773aa44fbcfedf7c193bc2c599004375dff511095cc5a197a54140a24efef3a416cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20102000000000000000000000000000000000000000000000000
|
||||
test_single_encoding_strategy_usv4_grouped_swap:30ace1b1000000000000000000000000000000000000000000000000000000003b9aca00000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000006982508145454ce325ddbe47a25d4ec3d23119330000000000000000000000000000000000000000005064ff624d54346285543f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000000000000000000000000000000000003b9aca00000000000000000000000000000000000000000000000000000000006880f5c700000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068596fcf00000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041c4cbbfa526fdc8da41a6bd03a58365bceecee48a98a0d3748596615854b6a0173244dbe5371ba516092fdd94ff7b57929782bcc25214f473522f97a6d01c10281c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009cf62849f9a0b5bf2913b396098f7c7019b51a820aa0b86991c6218b36c1d19d4a2e9eb0ce3606eb486982508145454ce325ddbe47a25d4ec3d23119330000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000000000000000000000000bb800003c001a6982508145454ce325ddbe47a25d4ec3d23119330061a80001f400000000
|
||||
test_single_encoding_strategy_usv4_eth_out:30ace1b100000000000000000000000000000000000000000000000000000000b2d05e00000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f81490b4f29aade00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000b2d05e00000000000000000000000000000000000000000000000000000000006880f5c700000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068596fcf00000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000004141834cb6f31447a97a42587522f6bd70c9661678f0fde1350a2d063ec4a6fa547b25d0b81d13b57f02d5f7987490f886b182379c2f24404e9eeba945c95026a11b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080f62849f9a0b5bf2913b396098f7c7019b51a820aa0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000000000000000000000000bb800003c
|
||||
test_sequential_swap_strategy_encoder:51bcc7b60000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000006880f5c800000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068596fd000000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000411d4790c58f29180e53b2043be583c77b00ae13951ac5d2134fe152c41ca8ce1e36489614de5090266bf2ac137f6989fc93ef0df5e33fbbaebb77f88f63054bf91c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a800525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2bb2b8038a1640196fbe3e38816f3e67cba72d940004375dff511095cc5a197a54140a24efef3a416000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72f2260fac5e5542a773aa44fbcfedf7c193bc2c599004375dff511095cc5a197a54140a24efef3a416cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20102000000000000000000000000000000000000000000000000
|
||||
test_single_encoding_strategy_usv4_grouped_swap:30ace1b1000000000000000000000000000000000000000000000000000000003b9aca00000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000006982508145454ce325ddbe47a25d4ec3d23119330000000000000000000000000000000000000000005064ff624d54346285543f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000000000000000000000000000000000003b9aca000000000000000000000000000000000000000000000000000000000068a7452c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000000000000000000000000000000000000687fbf3400000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041aa05dfce0bca6785026b114e751b149b0e1ef2649598455bbc013893d1a241c546ccd30a543e261c8bb565c673b9c7fcc28f72325d9d059e7fc4e31a299c895a1b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086f62849f9a0b5bf2913b396098f7c7019b51a820aa0b86991c6218b36c1d19d4a2e9eb0ce3606eb486982508145454ce325ddbe47a25d4ec3d23119330000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000bb800003c6982508145454ce325ddbe47a25d4ec3d23119330061a80001f40000000000000000000000000000000000000000000000000000
|
||||
test_single_encoding_strategy_usv4_eth_out:30ace1b100000000000000000000000000000000000000000000000000000000b2d05e00000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f81490b4f29aade00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000b2d05e000000000000000000000000000000000000000000000000000000000068a7452c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000000000000000000000000000000000000687fbf3400000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041dacc6c754032bb9de8d264c64a46f2b309335b01f837b2f5b8b7b68bfa920a4537220bab168a5b0f3b84469365c91e0013d3950aca01664b993b3c18c291545b1b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006cf62849f9a0b5bf2913b396098f7c7019b51a820aa0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000bb800003c0000000000000000000000000000000000000000
|
||||
test_sequential_swap_strategy_encoder:51bcc7b60000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000068a7452c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000000000000000000000000000000000000687fbf3400000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041ca1a9b5e5aef9624ec8e786ff0fb16fc4ed0758a421d99754184430aa95833b223eee4e65bcbf835f5f2ea2bdc2046231f6befb919298bfeb7d0271d0ce27f391c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a800525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2bb2b8038a1640196fbe3e38816f3e67cba72d940004375dff511095cc5a197a54140a24efef3a416000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72f2260fac5e5542a773aa44fbcfedf7c193bc2c599004375dff511095cc5a197a54140a24efef3a416cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20102000000000000000000000000000000000000000000000000
|
||||
test_single_swap_strategy_encoder_no_permit2:5c4b639c0000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000000000000000000000000058e7926ee858a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb11cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000
|
||||
test_single_swap_strategy_encoder_no_transfer_in:5c4b639c0000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000000000000000000000000058e7926ee858a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb11cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200010000000000000000000000000000
|
||||
test_single_encoding_strategy_usv4_eth_in:30ace1b10000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006982508145454ce325ddbe47a25d4ec3d23119330000000000000000000000000000000000000000007e0a55d4322a6e93c2379c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000006880f5c700000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068596fcf00000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000004171bd5e50eb1f6509d7ea85dcd69039787fc989f5fc98fbbeaa1dcd6e90d5c42608d3b134cad016d9751f51ab69031c83e17525c7b38fbc3a0591a1caa1d9020d1c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080f62849f9a0b5bf2913b396098f7c7019b51a820a00000000000000000000000000000000000000006982508145454ce325ddbe47a25d4ec3d23119330102cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000006982508145454ce325ddbe47a25d4ec3d23119330061a80001f4
|
||||
test_sequential_strategy_cyclic_swap:51bcc7b60000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005ec8f6e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000000000000000000000000000000000006880f5c800000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068596fd000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000004194a2a77939d54575730a79858b5ed5ef2bc53fc4443f0082c2e430e6eaa3019a18f78449bc10dc25a957fe296280b7ebc349784d94da323e553e95807c4db5661b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d600692e234dae75c793f67a35089c9d99245e1c58470ba0b86991c6218b36c1d19d4a2e9eb0ce3606eb48c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20001f43ede3eca2a72b3aecc820e955b36f38437d0139588e6a0c2ddd26feeb64f039a2c41296fcb3f5640010000692e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000bb8cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc28ad599c3a0ff1de082011efddc58f1908eb6e6d8000100000000000000000000
|
||||
test_single_encoding_strategy_usv4_eth_in:30ace1b10000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006982508145454ce325ddbe47a25d4ec3d23119330000000000000000000000000000000000000000007e0a55d4322a6e93c2379c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000068a7452c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000000000000000000000000000000000000687fbf3400000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000413b7112285f6b953c073324f6563a055155581aacaa2df8bc92cc21619fda72aa25c386899fe9af623d0419095b7b8f4f9af2466e1eebb4d2724dc4e9097d0b111c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006cf62849f9a0b5bf2913b396098f7c7019b51a820a00000000000000000000000000000000000000006982508145454ce325ddbe47a25d4ec3d23119330102cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc26982508145454ce325ddbe47a25d4ec3d23119330061a80001f40000000000000000000000000000000000000000
|
||||
test_sequential_strategy_cyclic_swap:51bcc7b60000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005ec8f6e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005f5e1000000000000000000000000000000000000000000000000000000000068a7452c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000000000000000000000000000000000000687fbf3400000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000415eb48a5bb3d9854bd934b6524f5f568228c9946b22c1f6fd96e3f54ba6d57ce53a9bd5038f43dff33737b1c3f9294336bb9750e8f6c81d3e56b9e087845657c91c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d600692e234dae75c793f67a35089c9d99245e1c58470ba0b86991c6218b36c1d19d4a2e9eb0ce3606eb48c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20001f43ede3eca2a72b3aecc820e955b36f38437d0139588e6a0c2ddd26feeb64f039a2c41296fcb3f5640010000692e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000bb8cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc28ad599c3a0ff1de082011efddc58f1908eb6e6d8000100000000000000000000
|
||||
test_single_encoding_strategy_curve_st_eth:5c4b639c0000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe84000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000691d1499e622d69689cdf9004d05ec547d650ff211eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeae7ab96520de3a18e5e111b5eaab095312d7fe84dc24316b9ae028f1497c275eb9192a3ea0f670220100010002cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000
|
||||
test_single
|
||||
test_encode_uniswap_v4_sequential_swap:4c9edd5852cd905f086c759e8383e09bff1e68b32260fac5e5542a773aa44fbcfedf7c193bc2c5990101cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7000064000001001a2260fac5e5542a773aa44fbcfedf7c193bc2c599000bb800003c
|
||||
test_encode_uniswap_v4_sequential_swap:4c9edd5852cd905f086c759e8383e09bff1e68b32260fac5e5542a773aa44fbcfedf7c193bc2c5990101cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2dac17f958d2ee523a2206206994597c13d831ec70000640000012260fac5e5542a773aa44fbcfedf7c193bc2c599000bb800003c
|
||||
6d70b85442ed96492800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000006869398600000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d01395000000000000000000000000000000000000000000000000000000006841b38e00000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041752ca399237fc5086ef89d5f6dabecfb4b43c0753ecfb7020a6a86045db423fd3be9565f79b511fe93f55f76f61b1ac8d786b04051110ca6cbe10bbf69901b871c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb11cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000
|
||||
test_single_encoding_strategy_curve:5c4b639c0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000055c08ca52497e2f1534b59e2917bf524d4765257000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000691d1499e622d69689cdf9004d05ec547d650ff21155c08ca52497e2f1534b59e2917bf524d4765257c02aaa39b223fe8d0a0e5c4f27ead9083c756cc277146b0a1d08b6844376df6d9da99ba7f1b19e710201000100cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000
|
||||
test_single_swap_strategy_encoder_unwrap:30ace1b10000000000000000000000000000000000000000000000a2a15d09519be000000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f0000000000000000000000000000000000000000000000a2a15d09519be00000000000000000000000000000000000000000000000000000000000006880f5c900000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068596fd100000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041fd9aec9b11fd06d7b9354c7d536af531e4aeb15e0a649b0916d06bb2b60d1858048232393ab20171925e560adeb7d7be93eb3cc66e7568417c4906ebaff388931c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72f6b175474e89094c44da98b954eedeac495271d0fa478c2975ab1ea89e8196811f51a7b7ade33eb113ede3eca2a72b3aecc820e955b36f38437d0139501000000000000000000000000000000
|
||||
test_single_swap_strategy_encoder_wrap:30ace1b10000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000000000000000000000000059fb7d3830e6fc064b00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000006880f5c900000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068596fd100000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041d81384f3eea5db7a09afe5126788555cfef72a084d8b124851f99f4f2a08510959c8fb93042e154563f6bcb95fbed6bfa8f2a3e853b09fe6dd75cb30a6bc1f481b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb11cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200010000000000000000000000000000
|
||||
test_split_output_cyclic_swap:7c5538460000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005e703f4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000000000000000000000000000000000006880f5c900000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068596fd10000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000000414602b0f66daeb285fda8d3e2d68046ca8ae4ee3898923742b84020d3fb4d99227021760217b657f4bca96e64721a5a1c45aec23a04aec8fd3d6b41a1638799af1c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000139005700010000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48b4e16d0168e52d35cacd2c6185b44281ec28c9dc3ede3eca2a72b3aecc820e955b36f38437d013950100006e01009999992e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480001f4cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc288e6a0c2ddd26feeb64f039a2c41296fcb3f56400001006e01000000002e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000bb8cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc28ad599c3a0ff1de082011efddc58f1908eb6e6d8000100000000000000
|
||||
test_split_input_cyclic_swap:7c5538460000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005ef619b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000000000000000000000000000000000006880f5c900000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068596fd10000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000000414602b0f66daeb285fda8d3e2d68046ca8ae4ee3898923742b84020d3fb4d99227021760217b657f4bca96e64721a5a1c45aec23a04aec8fd3d6b41a1638799af1c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000139006e00019999992e234dae75c793f67a35089c9d99245e1c58470ba0b86991c6218b36c1d19d4a2e9eb0ce3606eb48c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20001f43ede3eca2a72b3aecc820e955b36f38437d0139588e6a0c2ddd26feeb64f039a2c41296fcb3f56400100006e00010000002e234dae75c793f67a35089c9d99245e1c58470ba0b86991c6218b36c1d19d4a2e9eb0ce3606eb48c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000bb83ede3eca2a72b3aecc820e955b36f38437d013958ad599c3a0ff1de082011efddc58f1908eb6e6d80100005701000000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2b4e16d0168e52d35cacd2c6185b44281ec28c9dccd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000100000000000000
|
||||
test_split_swap_strategy_encoder:7c5538460000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000006880f5c900000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068596fd100000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000004133513df7889736193c90e980405812c09e90901e4a6aa0c91ce6df1db13812157fadc761eaab59f84c5e135c4fde745836d626ca56390aed4d385538733b00db1b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000164005700028000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb113ede3eca2a72b3aecc820e955b36f38437d013950000005700010000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2bb2b8038a1640196fbe3e38816f3e67cba72d9403ede3eca2a72b3aecc820e955b36f38437d013950000005702030000005615deb798bb3e4dfa0139dfa1b3d433cc23b72f6b175474e89094c44da98b954eedeac495271d0fae461ca67b15dc8dc81ce7615e0320da1a9ab8d5cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20101005701030000005615deb798bb3e4dfa0139dfa1b3d433cc23b72f2260fac5e5542a773aa44fbcfedf7c193bc2c599004375dff511095cc5a197a54140a24efef3a416cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2010100000000000000000000000000000000000000000000000000000000
|
||||
test_single_swap_strategy_encoder_unwrap:30ace1b10000000000000000000000000000000000000000000000a2a15d09519be000000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f0000000000000000000000000000000000000000000000a2a15d09519be000000000000000000000000000000000000000000000000000000000000068a7452d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000000000000000000000000000000000000687fbf3500000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000416cf5d0fb75c24a379e1988e7ffa76de4e9573ecd42f79a380566f720734698e56cbb6034bd9cf713e6c4a89c4a57f768a360fc83df588fed402be248e2291cc51c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72f6b175474e89094c44da98b954eedeac495271d0fa478c2975ab1ea89e8196811f51a7b7ade33eb113ede3eca2a72b3aecc820e955b36f38437d0139501000000000000000000000000000000
|
||||
test_single_swap_strategy_encoder_wrap:30ace1b10000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000000000000000000000000059fb7d3830e6fc064b00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000068a7452d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000000000000000000000000000000000000687fbf3500000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041e3abc1917a9102020e3a8e5f3c9cd8c95088f0f54315938b0fc21d9c74d33ca969bea7ea4cc8889cc403f3940e51b55ee56a5b918e649b5a147d2e47b68411fc1b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb11cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200010000000000000000000000000000
|
||||
test_split_output_cyclic_swap:7c5538460000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005e703f4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005f5e1000000000000000000000000000000000000000000000000000000000068a7452e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000000000000000000000000000000000000687fbf360000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000000416619afeffa8f49edde843d038e64e278de064d24586a84d3f6fc592d0e9e263e1f59599118eb7b25a8d4c1362b52728b076997b99ce7fd780b77ddf9ee674bb71c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000139005700010000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48b4e16d0168e52d35cacd2c6185b44281ec28c9dc3ede3eca2a72b3aecc820e955b36f38437d013950100006e01009999992e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480001f4cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc288e6a0c2ddd26feeb64f039a2c41296fcb3f56400001006e01000000002e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000bb8cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc28ad599c3a0ff1de082011efddc58f1908eb6e6d8000100000000000000
|
||||
test_split_input_cyclic_swap:7c5538460000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005ef619b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005f5e1000000000000000000000000000000000000000000000000000000000068a7452e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000000000000000000000000000000000000687fbf360000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000000416619afeffa8f49edde843d038e64e278de064d24586a84d3f6fc592d0e9e263e1f59599118eb7b25a8d4c1362b52728b076997b99ce7fd780b77ddf9ee674bb71c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000139006e00019999992e234dae75c793f67a35089c9d99245e1c58470ba0b86991c6218b36c1d19d4a2e9eb0ce3606eb48c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20001f43ede3eca2a72b3aecc820e955b36f38437d0139588e6a0c2ddd26feeb64f039a2c41296fcb3f56400100006e00010000002e234dae75c793f67a35089c9d99245e1c58470ba0b86991c6218b36c1d19d4a2e9eb0ce3606eb48c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000bb83ede3eca2a72b3aecc820e955b36f38437d013958ad599c3a0ff1de082011efddc58f1908eb6e6d80100005701000000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2b4e16d0168e52d35cacd2c6185b44281ec28c9dccd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000100000000000000
|
||||
test_split_swap_strategy_encoder:7c5538460000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000068a7452e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000000000000000000000000000000000000687fbf36000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000041c742469c49e8a03a8285ba3328e786a99b8a792c642fd9e409bc06f3baee04ea6589bdb0bd195122e9af08c8296f9841fff7a32be8b3afd44a586ee65ed684151b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000164005700028000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb113ede3eca2a72b3aecc820e955b36f38437d013950000005700010000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2bb2b8038a1640196fbe3e38816f3e67cba72d9403ede3eca2a72b3aecc820e955b36f38437d013950000005702030000005615deb798bb3e4dfa0139dfa1b3d433cc23b72f6b175474e89094c44da98b954eedeac495271d0fae461ca67b15dc8dc81ce7615e0320da1a9ab8d5cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20101005701030000005615deb798bb3e4dfa0139dfa1b3d433cc23b72f2260fac5e5542a773aa44fbcfedf7c193bc2c599004375dff511095cc5a197a54140a24efef3a416cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2010100000000000000000000000000000000000000000000000000000000
|
||||
test_uniswap_v3_curve:e21dd0d30000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000d600692e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc22260fac5e5542a773aa44fbcfedf7c193bc2c599000bb83ede3eca2a72b3aecc820e955b36f38437d01395cbcdf9626bc03e24f779434178a73a0b4bad62ed000000691d1499e622d69689cdf9004d05ec547d650ff2112260fac5e5542a773aa44fbcfedf7c193bc2c599dac17f958d2ee523a2206206994597c13d831ec7d51a44d3fae010294c616388b506acda1bfaae460301000102cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000
|
||||
test_multi_protocol:51bcc7b600000000000000000000000000000000000000000000005150ae84a8cdf000000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a2958f36da71a9200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000005150ae84a8cdf00000000000000000000000000000000000000000000000000000000000006880f5c600000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068596fce00000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000004125a37e4e8921f2f34b6264af82e02176c4efa11c3956088cd0dffc923b3406581eb6696baebf6e2b0d2e3b6a6402fea0e314f2ba8d9434b704dc2272a63cf0831b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022800525615deb798bb3e4dfa0139dfa1b3d433cc23b72f6b175474e89094c44da98b954eedeac495271d0fa478c2975ab1ea89e8196811f51a7b7ade33eb113ede3eca2a72b3aecc820e955b36f38437d0139501000072c7183455a4c133ae270771860664b6b7ec320bb1c02aaa39b223fe8d0a0e5c4f27ead9083c756cc22260fac5e5542a773aa44fbcfedf7c193bc2c599a6f548df93de924d73be7d25dc02554c6bd66db500020000000000000000000e3ede3eca2a72b3aecc820e955b36f38437d01395010200691d1499e622d69689cdf9004d05ec547d650ff2112260fac5e5542a773aa44fbcfedf7c193bc2c599dac17f958d2ee523a2206206994597c13d831ec7d51a44d3fae010294c616388b506acda1bfaae4603010001023ede3eca2a72b3aecc820e955b36f38437d013950071a0cb889707d426a7a386870a03bc70d1b0697598013ede3eca2a72b3aecc820e955b36f38437d01395dac17f958d2ee523a2206206994597c13d831ec7a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000001a36e2eb1c432000000320080f62849f9a0b5bf2913b396098f7c7019b51a820aa0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000001cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000000000000000000000000bb800003c000000000000000000000000000000000000000000000000
|
||||
test_multi_protocol:51bcc7b600000000000000000000000000000000000000000000005150ae84a8cdf000000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a2958f36da71a9200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000005150ae84a8cdf000000000000000000000000000000000000000000000000000000000000068a7452b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000000000000000000000000000000000000687fbf3300000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000417fa6c0b85fb91e2737e39084c4530258c41c99f16a2796ea7400494d6486496525c653898965dde735537ef4b7ee93a79b5c6f11196a35b79e6d00f0b34811ac1b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000021400525615deb798bb3e4dfa0139dfa1b3d433cc23b72f6b175474e89094c44da98b954eedeac495271d0fa478c2975ab1ea89e8196811f51a7b7ade33eb113ede3eca2a72b3aecc820e955b36f38437d0139501000072c7183455a4c133ae270771860664b6b7ec320bb1c02aaa39b223fe8d0a0e5c4f27ead9083c756cc22260fac5e5542a773aa44fbcfedf7c193bc2c599a6f548df93de924d73be7d25dc02554c6bd66db500020000000000000000000e3ede3eca2a72b3aecc820e955b36f38437d01395010200691d1499e622d69689cdf9004d05ec547d650ff2112260fac5e5542a773aa44fbcfedf7c193bc2c599dac17f958d2ee523a2206206994597c13d831ec7d51a44d3fae010294c616388b506acda1bfaae4603010001023ede3eca2a72b3aecc820e955b36f38437d013950071a0cb889707d426a7a386870a03bc70d1b0697598013ede3eca2a72b3aecc820e955b36f38437d01395dac17f958d2ee523a2206206994597c13d831ec7a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000001a36e2eb1c43200000032006cf62849f9a0b5bf2913b396098f7c7019b51a820aa0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000001cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000bb800003c000000000000000000000000
|
||||
test_encode_balancer_v2:c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2ba100000625a3754423978a60c9317c58a424e3d5c6ee304399dbdb9c8ef030ab642b10820db8f560002000000000000000000141d96f2f6bef1202e4ce1ff6dad0c2cb002861d3e0102
|
||||
test_ekubo_encode_swap_multi:01ca4f73fe97d0b987a0d12b39bbd562c779bab6f60000000000000000000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4851d02a5948496a67827242eabc5725531342527c000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000000000000000000000001a36e2eb1c43200000032
|
||||
test_encode_uniswap_v4_sequential_swap:4c9edd5852cd905f086c759e8383e09bff1e68b32260fac5e5542a773aa44fbcfedf7c193bc2c5990101cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7000064000001001a2260fac5e5542a773aa44fbcfedf7c193bc2c599000bb800003c
|
||||
test_encode_uniswap_v4_simple_swap:4c9edd5852cd905f086c759e8383e09bff1e68b3dac17f958d2ee523a2206206994597c13d831ec70101cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7000064000001
|
||||
test_encode_uniswap_v4_sequential_swap:4c9edd5852cd905f086c759e8383e09bff1e68b32260fac5e5542a773aa44fbcfedf7c193bc2c5990101cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2dac17f958d2ee523a2206206994597c13d831ec70000640000012260fac5e5542a773aa44fbcfedf7c193bc2c599000bb800003c
|
||||
test_encode_uniswap_v4_simple_swap:4c9edd5852cd905f086c759e8383e09bff1e68b3dac17f958d2ee523a2206206994597c13d831ec70101cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2dac17f958d2ee523a2206206994597c13d831ec7000064000001
|
||||
test_single_encoding_strategy_maverick:5c4b639c0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000040d16fc0246ad3160ccc09b8d0d3a2cd28ae6c2f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000000003e800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000051a4ad4f68d0b91cfd19687c881e50f3a00242828c40d16fc0246ad3160ccc09b8d0d3a2cd28ae6c2f14cf6d2fe3e1b326114b07d22a6f6bb59e346c67cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000
|
||||
test_encode_maverick_v2:40d16fc0246ad3160ccc09b8d0d3a2cd28ae6c2f14cf6d2fe3e1b326114b07d22a6f6bb59e346c671d96f2f6bef1202e4ce1ff6dad0c2cb002861d3e01
|
||||
test_encode_uniswap_v2:c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb111d96f2f6bef1202e4ce1ff6dad0c2cb002861d3e0001
|
||||
test_encode_balancer_v3:7bc3485026ac48b6cf9baf0a377477fff5703af8c71ea051a5f82c67adcf634c36ffe6334793d24c85b2b559bc2d21104c4defdd6efca8a20343361d011d96f2f6bef1202e4ce1ff6dad0c2cb002861d3e
|
||||
test_single_encoding_strategy_balancer_v3:5c4b639c0000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000097ffedb80d4b2ca6105a07a4d90eb739c45a66600000000000000000000000030881baa943777f92dc934d53d3bfdf33382cab300000000000000000000000000000000000000000000000000000000000003e800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000006503a6a84cd762d9707a21605b548aaab891562aab097ffedb80d4b2ca6105a07a4d90eb739c45a66630881baa943777f92dc934d53d3bfdf33382cab3f028ac624074d6793c36dc8a06ecec0f5a39a71800cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000000000000000000000000000000000
|
||||
test_uniswap_v3_balancer_v3:e21dd0d3000000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000004a220e6096b25eadb88358cb44068a324825467500000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000d200692e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc22260fac5e5542a773aa44fbcfedf7c193bc2c599000bb83ede3eca2a72b3aecc820e955b36f38437d01395cbcdf9626bc03e24f779434178a73a0b4bad62ed0000006503a6a84cd762d9707a21605b548aaab891562aab2260fac5e5542a773aa44fbcfedf7c193bc2c5994a220e6096b25eadb88358cb44068a3248254675571bea0e99e139cd0b6b7d9352ca872dfe0d72dd01cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000
|
||||
test_single_swap_strategy_encoder:30ace1b10000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000006d70b85442ed96492800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000006880f5c900000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068596fd100000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000004133513df7889736193c90e980405812c09e90901e4a6aa0c91ce6df1db13812157fadc761eaab59f84c5e135c4fde745836d626ca56390aed4d385538733b00db1b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb11cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000
|
||||
test_single_swap_strategy_encoder:30ace1b10000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000006d70b85442ed96492800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000068a7452d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000000000000000000000000000000000000687fbf3500000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000004154d32a9cdc3955c1e9ba8767bb29c3a197c7497bf87aba59eb050278f39a999a609510cf1aa2535142e67b07ce9755f926877ff618c5ffaa684c0bcc310fdd7d1c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb11cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000
|
||||
test_sequential_swap_usx:0101e21dd0d300000000000000000000000000000000000000000000006c6b935b8bbd4000000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000000000000000000000000000000000000769cfd80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006d9da78b6a5bedca287aa5d49613ba36b90c15c40000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000d600692e234dae75c793f67a35089c9d99245e1c58470b6b175474e89094c44da98b954eedeac495271d0fa0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000643ede3eca2a72b3aecc820e955b36f38437d013955777d92f208679db4b9778590fa3cab3ac9e2168010000692e234dae75c793f67a35089c9d99245e1c58470ba0b86991c6218b36c1d19d4a2e9eb0ce3606eb48dac17f958d2ee523a2206206994597c13d831ec70000646d9da78b6a5bedca287aa5d49613ba36b90c15c43416cf6c708da44db2624d63ea0aaef7113527c6010100000000000000000000
|
||||
|
||||
@@ -19,22 +19,29 @@ contract EkuboExecutorTest is Constants, TestUtils {
|
||||
IERC20 USDT = IERC20(USDT_ADDR);
|
||||
|
||||
address constant CORE_ADDRESS = 0xe0e0e08A6A4b9Dc7bD67BCB7aadE5cF48157d444;
|
||||
address constant MEV_RESIST_ADDRESS =
|
||||
0x553a2EFc570c9e104942cEC6aC1c18118e54C091;
|
||||
|
||||
bytes32 constant ORACLE_CONFIG =
|
||||
0x51d02a5948496a67827242eabc5725531342527c000000000000000000000000;
|
||||
|
||||
function setUp() public {
|
||||
vm.createSelectFork(vm.rpcUrl("mainnet"), 22082754);
|
||||
// 0.01% fee and 0.02% tick spacing
|
||||
bytes32 constant MEV_RESIST_POOL_CONFIG =
|
||||
0x553a2EFc570c9e104942cEC6aC1c18118e54C09100068db8bac710cb000000c8;
|
||||
|
||||
modifier setUpFork(uint256 blockNumber) {
|
||||
vm.createSelectFork(vm.rpcUrl("mainnet"), blockNumber);
|
||||
|
||||
deployCodeTo(
|
||||
"executors/EkuboExecutor.sol",
|
||||
abi.encode(CORE_ADDRESS, PERMIT2_ADDRESS),
|
||||
abi.encode(CORE_ADDRESS, MEV_RESIST_ADDRESS, PERMIT2_ADDRESS),
|
||||
EXECUTOR_ADDRESS
|
||||
);
|
||||
executor = EkuboExecutor(payable(EXECUTOR_ADDRESS));
|
||||
_;
|
||||
}
|
||||
|
||||
function testSingleSwapEth() public {
|
||||
function testSingleSwapEth() public setUpFork(22722989) {
|
||||
uint256 amountIn = 1 ether;
|
||||
|
||||
deal(address(executor), amountIn);
|
||||
@@ -71,7 +78,7 @@ contract EkuboExecutorTest is Constants, TestUtils {
|
||||
);
|
||||
}
|
||||
|
||||
function testSingleSwapERC20() public {
|
||||
function testSingleSwapERC20() public setUpFork(22722989) {
|
||||
uint256 amountIn = 1_000_000_000;
|
||||
|
||||
deal(USDC_ADDR, address(executor), amountIn);
|
||||
@@ -108,6 +115,43 @@ contract EkuboExecutorTest is Constants, TestUtils {
|
||||
);
|
||||
}
|
||||
|
||||
function testMevResist() public setUpFork(22722989) {
|
||||
uint256 amountIn = 1_000_000_000;
|
||||
|
||||
deal(USDC_ADDR, address(executor), amountIn);
|
||||
|
||||
uint256 usdcBalanceBeforeCore = USDC.balanceOf(CORE_ADDRESS);
|
||||
uint256 usdcBalanceBeforeExecutor = USDC.balanceOf(address(executor));
|
||||
|
||||
uint256 ethBalanceBeforeCore = CORE_ADDRESS.balance;
|
||||
uint256 ethBalanceBeforeExecutor = address(executor).balance;
|
||||
|
||||
bytes memory data = abi.encodePacked(
|
||||
uint8(RestrictTransferFrom.TransferType.Transfer), // transferNeeded (transfer from executor to core)
|
||||
address(executor), // receiver
|
||||
USDC_ADDR, // tokenIn
|
||||
NATIVE_TOKEN_ADDRESS, // tokenOut
|
||||
MEV_RESIST_POOL_CONFIG // config
|
||||
);
|
||||
|
||||
uint256 gasBefore = gasleft();
|
||||
uint256 amountOut = executor.swap(amountIn, data);
|
||||
console.log(gasBefore - gasleft());
|
||||
|
||||
console.log(amountOut);
|
||||
|
||||
assertEq(USDC.balanceOf(CORE_ADDRESS), usdcBalanceBeforeCore + amountIn);
|
||||
assertEq(
|
||||
USDC.balanceOf(address(executor)),
|
||||
usdcBalanceBeforeExecutor - amountIn
|
||||
);
|
||||
|
||||
assertEq(CORE_ADDRESS.balance, ethBalanceBeforeCore - amountOut);
|
||||
assertEq(
|
||||
address(executor).balance, ethBalanceBeforeExecutor + amountOut
|
||||
);
|
||||
}
|
||||
|
||||
// Expects input that encodes the same test case as swap_encoder::tests::ekubo::test_encode_swap_multi
|
||||
function multiHopSwap(bytes memory data) internal {
|
||||
uint256 amountIn = 1 ether;
|
||||
@@ -139,7 +183,7 @@ contract EkuboExecutorTest is Constants, TestUtils {
|
||||
}
|
||||
|
||||
// Same test case as in swap_encoder::tests::ekubo::test_encode_swap_multi
|
||||
function testMultiHopSwap() public {
|
||||
function testMultiHopSwap() public setUpFork(22082754) {
|
||||
bytes memory data = abi.encodePacked(
|
||||
uint8(RestrictTransferFrom.TransferType.Transfer), // transferNeeded (transfer from executor to core)
|
||||
address(executor), // receiver
|
||||
@@ -155,7 +199,7 @@ contract EkuboExecutorTest is Constants, TestUtils {
|
||||
}
|
||||
|
||||
// Data is generated by test case in swap_encoder::tests::ekubo::test_encode_swap_multi
|
||||
function testMultiHopSwapIntegration() public {
|
||||
function testMultiHopSwapIntegration() public setUpFork(22082754) {
|
||||
multiHopSwap(loadCallDataFromFile("test_ekubo_encode_swap_multi"));
|
||||
}
|
||||
}
|
||||
|
||||
302
foundry/test/uniswap_x/UniswapXFiller.t.sol
Normal file
302
foundry/test/uniswap_x/UniswapXFiller.t.sol
Normal file
@@ -0,0 +1,302 @@
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
pragma solidity ^0.8.26;
|
||||
|
||||
import "forge-std/Test.sol";
|
||||
import "@src/uniswap_x/UniswapXFiller.sol";
|
||||
import "../TychoRouterTestSetup.sol";
|
||||
|
||||
contract UniswapXFillerTest is Test, TychoRouterTestSetup {
|
||||
address EXECUTOR = address(0xCe79b081c0c924cb67848723ed3057234d10FC6b);
|
||||
address REACTOR = address(0x00000011F84B9aa48e5f8aA8B9897600006289Be);
|
||||
|
||||
UniswapXFiller filler;
|
||||
address fillerAddr;
|
||||
|
||||
event CallbackVerifierSet(address indexed callbackVerifier);
|
||||
event Withdrawal(
|
||||
address indexed token, uint256 amount, address indexed receiver
|
||||
);
|
||||
|
||||
function getForkBlock() public pure override returns (uint256) {
|
||||
return 22880493;
|
||||
}
|
||||
|
||||
function fillerSetup() public {
|
||||
vm.startPrank(ADMIN);
|
||||
filler = new UniswapXFiller(tychoRouterAddr, REACTOR, address(0));
|
||||
fillerAddr = address(filler);
|
||||
filler.grantRole(keccak256("EXECUTOR_ROLE"), EXECUTOR);
|
||||
vm.stopPrank();
|
||||
}
|
||||
|
||||
function testTychoAddressZeroTychoRouter() public {
|
||||
vm.expectRevert(UniswapXFiller__AddressZero.selector);
|
||||
filler = new UniswapXFiller(address(0), REACTOR, address(0));
|
||||
}
|
||||
|
||||
function testTychoAddressZeroReactor() public {
|
||||
vm.expectRevert(UniswapXFiller__AddressZero.selector);
|
||||
filler = new UniswapXFiller(tychoRouterAddr, address(0), address(0));
|
||||
}
|
||||
|
||||
function testCallback() public {
|
||||
fillerSetup();
|
||||
uint256 amountIn = 10 ** 18;
|
||||
uint256 amountOut = 1847751195973566072891;
|
||||
bool zeroForOne = false;
|
||||
bytes memory protocolData = abi.encodePacked(
|
||||
WETH_ADDR,
|
||||
WETH_DAI_POOL,
|
||||
address(filler),
|
||||
zeroForOne,
|
||||
RestrictTransferFrom.TransferType.TransferFrom
|
||||
);
|
||||
|
||||
bytes memory swap =
|
||||
encodeSingleSwap(address(usv2Executor), protocolData);
|
||||
|
||||
bytes memory tychoRouterData = abi.encodeWithSelector(
|
||||
tychoRouter.singleSwap.selector,
|
||||
amountIn,
|
||||
WETH_ADDR,
|
||||
DAI_ADDR,
|
||||
2008817438608734439722,
|
||||
false,
|
||||
false,
|
||||
address(filler),
|
||||
true,
|
||||
swap
|
||||
);
|
||||
|
||||
bytes memory callbackData =
|
||||
abi.encodePacked(true, true, tychoRouterData);
|
||||
|
||||
deal(WETH_ADDR, address(filler), amountIn);
|
||||
|
||||
ResolvedOrder[] memory orders = new ResolvedOrder[](1);
|
||||
OutputToken[] memory outputs = new OutputToken[](1);
|
||||
outputs[0] = OutputToken({
|
||||
token: address(DAI_ADDR),
|
||||
amount: 1847751195973566072891,
|
||||
recipient: BOB
|
||||
});
|
||||
// Irrelevant fields for this test - we only need token output
|
||||
// info for the sake of testing.
|
||||
orders[0] = ResolvedOrder({
|
||||
info: OrderInfo({
|
||||
reactor: address(0),
|
||||
swapper: address(0),
|
||||
nonce: 0,
|
||||
deadline: 0,
|
||||
additionalValidationContract: address(0),
|
||||
additionalValidationData: ""
|
||||
}),
|
||||
input: InputToken({
|
||||
token: address(WETH_ADDR),
|
||||
amount: amountIn,
|
||||
maxAmount: amountIn
|
||||
}),
|
||||
outputs: outputs,
|
||||
sig: "",
|
||||
hash: ""
|
||||
});
|
||||
|
||||
vm.startPrank(REACTOR);
|
||||
filler.reactorCallback(orders, callbackData);
|
||||
vm.stopPrank();
|
||||
|
||||
// Check that the funds are in the filler at the end of the function call
|
||||
uint256 finalBalance = IERC20(DAI_ADDR).balanceOf(address(filler));
|
||||
assertGe(finalBalance, amountOut);
|
||||
|
||||
// Check that the proper approval was set
|
||||
vm.startPrank(REACTOR);
|
||||
IERC20(DAI_ADDR).transferFrom(address(filler), BOB, amountOut);
|
||||
vm.stopPrank();
|
||||
assertGe(IERC20(DAI_ADDR).balanceOf(BOB), amountOut);
|
||||
}
|
||||
|
||||
function testExecuteIntegration() public {
|
||||
fillerSetup();
|
||||
|
||||
// Set to time with no more penalty for not being exclusive filler
|
||||
vm.warp(1752050415);
|
||||
|
||||
deal(
|
||||
DAI_ADDR,
|
||||
address(0xD213e6F6dCB2DBaC03FA28b893F6dA1BD822e852),
|
||||
2000 ether
|
||||
);
|
||||
|
||||
uint256 amountIn = 2000000000000000000000;
|
||||
|
||||
vm.startPrank(address(0xD213e6F6dCB2DBaC03FA28b893F6dA1BD822e852));
|
||||
// Approve Permit2
|
||||
IERC20(DAI_ADDR).approve(
|
||||
address(0x000000000022D473030F116dDEE9F6B43aC78BA3), amountIn
|
||||
);
|
||||
vm.stopPrank();
|
||||
|
||||
// Tx 0x005d7b150017ba1b59d2f99395ccae7bda9b739938ade4e509817e32760aaf9d
|
||||
// Calldata generated using rust test `test_sequential_swap_usx`
|
||||
|
||||
SignedOrder memory order = SignedOrder({
|
||||
order: hex"000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001000000000000000000000000004449cd34d1eb1fedcf02a1be3834ffde8e6a61800000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000006c6b935b8bbd40000000000000000000000000000000000000000000000000006c6b935b8bbd40000000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000038000000000000000000000000000000011f84b9aa48e5f8aa8b9897600006289be000000000000000000000000d213e6f6dcb2dbac03fa28b893f6da1bd822e8520468320351debb1ddbfb032a239d699e3d54e3ce2b6e1037cd836a784c80b60100000000000000000000000000000000000000000000000000000000686e2bf9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec70000000000000000000000000000000000000000000000000000000076f9f4870000000000000000000000000000000000000000000000000000000076566300000000000000000000000000d213e6f6dcb2dbac03fa28b893f6da1bd822e85200000000000000000000000000000000000000000000000000000000686e2aee00000000000000000000000000000000000000000000000000000000686e2b2a000000000000000000000000ce79b081c0c924cb67848723ed3057234d10fc6b0000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000007727b5f40000000000000000000000000000000000000000000000000000000000000041a2d261cd4c8930428260f18b55e3036024bac68d58cb2ee6161e6395b0984b827104158713d44ddc4e14d852b48d93d95a4e60b8d5be1ef431c1e82d2f76a4111b00000000000000000000000000000000000000000000000000000000000000",
|
||||
sig: hex"f4cc5734820e4ee08519045c83a25b75687756053b3d6c0fda2141380dfa6ef17b40f64d9279f237e96982c6ba53a202e01a4358fd66e027c9bdf200d5626f441c"
|
||||
});
|
||||
|
||||
bytes memory callbackData =
|
||||
loadCallDataFromFile("test_sequential_swap_usx");
|
||||
|
||||
vm.startPrank(EXECUTOR);
|
||||
filler.execute(order, callbackData);
|
||||
vm.stopPrank();
|
||||
}
|
||||
|
||||
function testExecute() public {
|
||||
fillerSetup();
|
||||
|
||||
// Set to time with no more penalty for not being exclusive filler
|
||||
vm.warp(1752050415);
|
||||
|
||||
// tx: 0x005d7b150017ba1b59d2f99395ccae7bda9b739938ade4e509817e32760aaf9d
|
||||
// DAI ──> USDT
|
||||
SignedOrder memory order = SignedOrder({
|
||||
order: hex"000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001000000000000000000000000004449cd34d1eb1fedcf02a1be3834ffde8e6a61800000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000006c6b935b8bbd40000000000000000000000000000000000000000000000000006c6b935b8bbd40000000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000038000000000000000000000000000000011f84b9aa48e5f8aa8b9897600006289be000000000000000000000000d213e6f6dcb2dbac03fa28b893f6da1bd822e8520468320351debb1ddbfb032a239d699e3d54e3ce2b6e1037cd836a784c80b60100000000000000000000000000000000000000000000000000000000686e2bf9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec70000000000000000000000000000000000000000000000000000000076f9f4870000000000000000000000000000000000000000000000000000000076566300000000000000000000000000d213e6f6dcb2dbac03fa28b893f6da1bd822e85200000000000000000000000000000000000000000000000000000000686e2aee00000000000000000000000000000000000000000000000000000000686e2b2a000000000000000000000000ce79b081c0c924cb67848723ed3057234d10fc6b0000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000007727b5f40000000000000000000000000000000000000000000000000000000000000041a2d261cd4c8930428260f18b55e3036024bac68d58cb2ee6161e6395b0984b827104158713d44ddc4e14d852b48d93d95a4e60b8d5be1ef431c1e82d2f76a4111b00000000000000000000000000000000000000000000000000000000000000",
|
||||
sig: hex"f4cc5734820e4ee08519045c83a25b75687756053b3d6c0fda2141380dfa6ef17b40f64d9279f237e96982c6ba53a202e01a4358fd66e027c9bdf200d5626f441c"
|
||||
});
|
||||
|
||||
uint256 amountIn = 2000000000000000000000;
|
||||
bool zeroForOne = true;
|
||||
uint24 fee = 100;
|
||||
bytes memory protocolData = abi.encodePacked(
|
||||
DAI_ADDR,
|
||||
USDT_ADDR,
|
||||
fee,
|
||||
fillerAddr,
|
||||
DAI_USDT_USV3,
|
||||
zeroForOne,
|
||||
RestrictTransferFrom.TransferType.TransferFrom
|
||||
);
|
||||
|
||||
bytes memory swap =
|
||||
encodeSingleSwap(address(usv3Executor), protocolData);
|
||||
|
||||
bytes memory tychoRouterData = abi.encodeWithSelector(
|
||||
tychoRouter.singleSwap.selector,
|
||||
amountIn,
|
||||
DAI_ADDR,
|
||||
USDT_ADDR,
|
||||
1,
|
||||
false,
|
||||
false,
|
||||
fillerAddr,
|
||||
true,
|
||||
swap
|
||||
);
|
||||
|
||||
bytes memory callbackData = abi.encodePacked(
|
||||
true, // tokenIn approval needed
|
||||
true, // tokenOut approval needed
|
||||
tychoRouterData
|
||||
);
|
||||
|
||||
vm.startPrank(address(filler));
|
||||
IERC20(WBTC_ADDR).approve(tychoRouterAddr, amountIn);
|
||||
vm.stopPrank();
|
||||
|
||||
vm.startPrank(EXECUTOR);
|
||||
filler.execute(order, callbackData);
|
||||
vm.stopPrank();
|
||||
}
|
||||
|
||||
function testWithdrawNative() public {
|
||||
fillerSetup();
|
||||
vm.startPrank(ADMIN);
|
||||
// Send 100 ether to filler
|
||||
assertEq(fillerAddr.balance, 0);
|
||||
assertEq(ADMIN.balance, 0);
|
||||
vm.deal(fillerAddr, 100 ether);
|
||||
vm.expectEmit();
|
||||
emit Withdrawal(address(0), 100 ether, ADMIN);
|
||||
filler.withdrawNative(ADMIN);
|
||||
assertEq(fillerAddr.balance, 0);
|
||||
assertEq(ADMIN.balance, 100 ether);
|
||||
vm.stopPrank();
|
||||
}
|
||||
|
||||
function testWithdrawNativeAddressZero() public {
|
||||
fillerSetup();
|
||||
vm.deal(fillerAddr, 100 ether);
|
||||
vm.startPrank(ADMIN);
|
||||
vm.expectRevert(UniswapXFiller__AddressZero.selector);
|
||||
filler.withdrawNative(address(0));
|
||||
vm.stopPrank();
|
||||
}
|
||||
|
||||
function testWithdrawNativeMissingRole() public {
|
||||
fillerSetup();
|
||||
vm.deal(fillerAddr, 100 ether);
|
||||
// Not role ADMIN
|
||||
vm.startPrank(BOB);
|
||||
vm.expectRevert();
|
||||
filler.withdrawNative(ADMIN);
|
||||
vm.stopPrank();
|
||||
}
|
||||
|
||||
function testWithdrawERC20Tokens() public {
|
||||
fillerSetup();
|
||||
|
||||
IERC20[] memory tokens = new IERC20[](2);
|
||||
tokens[0] = IERC20(WETH_ADDR);
|
||||
tokens[1] = IERC20(USDC_ADDR);
|
||||
for (uint256 i = 0; i < tokens.length; i++) {
|
||||
deal(address(tokens[i]), fillerAddr, 100 ether);
|
||||
}
|
||||
|
||||
vm.startPrank(ADMIN);
|
||||
filler.withdraw(tokens, ADMIN);
|
||||
|
||||
// Check balances after withdrawing
|
||||
for (uint256 i = 0; i < tokens.length; i++) {
|
||||
// slither-disable-next-line calls-loop
|
||||
assertEq(tokens[i].balanceOf(fillerAddr), 0);
|
||||
// slither-disable-next-line calls-loop
|
||||
assertEq(tokens[i].balanceOf(ADMIN), 100 ether);
|
||||
}
|
||||
vm.stopPrank();
|
||||
}
|
||||
|
||||
function testWithdrawERC20TokensAddressZero() public {
|
||||
fillerSetup();
|
||||
|
||||
IERC20[] memory tokens = new IERC20[](2);
|
||||
tokens[0] = IERC20(WETH_ADDR);
|
||||
tokens[1] = IERC20(USDC_ADDR);
|
||||
for (uint256 i = 0; i < tokens.length; i++) {
|
||||
deal(address(tokens[i]), fillerAddr, 100 ether);
|
||||
}
|
||||
|
||||
vm.startPrank(ADMIN);
|
||||
vm.expectRevert(UniswapXFiller__AddressZero.selector);
|
||||
filler.withdraw(tokens, address(0));
|
||||
vm.stopPrank();
|
||||
}
|
||||
|
||||
function testWithdrawERC20TokensAddressMissingRole() public {
|
||||
fillerSetup();
|
||||
|
||||
IERC20[] memory tokens = new IERC20[](2);
|
||||
tokens[0] = IERC20(WETH_ADDR);
|
||||
tokens[1] = IERC20(USDC_ADDR);
|
||||
for (uint256 i = 0; i < tokens.length; i++) {
|
||||
deal(address(tokens[i]), fillerAddr, 100 ether);
|
||||
}
|
||||
|
||||
// Not role ADMIN
|
||||
vm.startPrank(BOB);
|
||||
vm.expectRevert();
|
||||
filler.withdraw(tokens, ADMIN);
|
||||
vm.stopPrank();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user