Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support JIT orders in the trade verifier #3085

Merged
merged 44 commits into from
Dec 2, 2024
Merged
Show file tree
Hide file tree
Changes from 40 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
a423e57
Quote with JIT orders API
squadgazzz Oct 24, 2024
0bf5393
Updated description
squadgazzz Oct 24, 2024
9cc9abe
Redundant defaults
squadgazzz Oct 25, 2024
898e5e7
Redundant amount
squadgazzz Oct 25, 2024
5e1d001
Support jit orders quote
squadgazzz Oct 25, 2024
0937d4e
Address rc
squadgazzz Oct 28, 2024
e759f42
Restore the custom quote deserializer
squadgazzz Oct 28, 2024
e7b756a
Address rc
squadgazzz Oct 28, 2024
f40fafb
Serde untagged
squadgazzz Oct 28, 2024
1dddcf5
Merge branch '3082/jit-orders-quote-api' into 3082/trade-verifier-jit…
squadgazzz Oct 28, 2024
18686fe
Fixes after merge
squadgazzz Oct 28, 2024
67af897
Address rc
squadgazzz Oct 28, 2024
8bcb18a
Merge branch 'main' into 3082/trade-verifier-jit-orders-support
squadgazzz Oct 28, 2024
1ee64ba
Compute expected amounts
squadgazzz Oct 28, 2024
f676a96
Compute jit orders net changes
squadgazzz Oct 30, 2024
941647c
Combine tests
squadgazzz Oct 30, 2024
9d522d2
Avoid redundant clone
squadgazzz Oct 30, 2024
81836ec
Use checked_ceil_div
squadgazzz Oct 30, 2024
bb83789
Merge branch 'main' into 3082/trade-verifier-jit-orders-support
squadgazzz Oct 30, 2024
a37b3ac
Redundant modulus
squadgazzz Oct 30, 2024
265e598
Comment
squadgazzz Oct 30, 2024
ac2dbd4
Avoid tokens and prices duplicates
squadgazzz Oct 30, 2024
8c7503a
Tests comment
squadgazzz Oct 30, 2024
e68e0df
Encode jit orders function
squadgazzz Oct 31, 2024
0afb473
Encode fake trade function
squadgazzz Oct 31, 2024
09e6330
BigRational::neg()
squadgazzz Oct 31, 2024
2e71436
Use BigDecimal in the config
squadgazzz Oct 31, 2024
a308910
Avoid calculation with empty jit orders
squadgazzz Nov 1, 2024
3067cd9
Address comments
squadgazzz Nov 5, 2024
4a0767c
Naming
squadgazzz Nov 5, 2024
e051528
Fetch the balances in the solver contract
squadgazzz Nov 7, 2024
2bcb3ac
Refactor the unit test
squadgazzz Nov 7, 2024
bea5183
Revert balance fetching changes
squadgazzz Nov 7, 2024
7b29d96
Avoid using IR optimizer
squadgazzz Nov 7, 2024
0be2814
Revert "Revert balance fetching changes"
squadgazzz Nov 18, 2024
277b4e3
Adjust balance fetching
squadgazzz Nov 18, 2024
f1e1806
Pr comments
squadgazzz Nov 28, 2024
8718d83
Ceil div
squadgazzz Nov 28, 2024
4ec514e
Merge branch 'main' into 3082/trade-verifier-jit-orders-support
squadgazzz Nov 28, 2024
8324c32
Redundant ceil
squadgazzz Nov 28, 2024
47d2642
Merge branch 'main' into 3082/trade-verifier-jit-orders-support
squadgazzz Dec 2, 2024
9b0e906
Redundant changes
squadgazzz Dec 2, 2024
fc0ad49
Comment
squadgazzz Dec 2, 2024
ca9109d
Merge branch 'main' into 3082/trade-verifier-jit-orders-support
squadgazzz Dec 2, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/autopilot/src/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,7 @@ pub async fn run(args: Arguments) {
code_fetcher: code_fetcher.clone(),
},
)
.await
.expect("failed to initialize price estimator factory");

let native_price_estimator = price_estimator_factory
Expand Down
2 changes: 1 addition & 1 deletion crates/contracts/artifacts/Solver.json

Large diffs are not rendered by default.

41 changes: 32 additions & 9 deletions crates/contracts/solidity/Solver.sol
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ contract Solver {
/// @param trader - address of the order owner doing the trade
/// @param sellToken - address of the token being sold
/// @param sellAmount - amount being sold
/// @param buyToken - address of the token being bought
/// @param nativeToken - ERC20 version of the chain's token
/// @param tokens - list of tokens used in the trade
/// @param receiver - address receiving the bought tokens
/// @param settlementCall - the calldata of the `settle()` call
/// @param mockPreconditions - controls whether things like ETH wrapping
Expand All @@ -47,8 +47,8 @@ contract Solver {
address payable trader,
address sellToken,
uint256 sellAmount,
address buyToken,
address nativeToken,
address[] calldata tokens,
address payable receiver,
bytes calldata settlementCall,
bool mockPreconditions
Expand Down Expand Up @@ -76,13 +76,14 @@ contract Solver {
// contract.
receiver.call{value: 0}("");

this.storeBalance(sellToken, address(settlementContract), false);
this.storeBalance(buyToken, address(settlementContract), false);
uint256 gasStart = gasleft();
address(settlementContract).doCall(settlementCall);
gasUsed = gasStart - gasleft() - _simulationOverhead;
this.storeBalance(sellToken, address(settlementContract), false);
this.storeBalance(buyToken, address(settlementContract), false);
// Store pre-settlement balances
_storeSettlementBalances(tokens, settlementContract);

gasUsed = _executeSettlement(address(settlementContract), settlementCall);

// Store post-settlement balances
_storeSettlementBalances(tokens, settlementContract);

queriedBalances = _queriedBalances;
}

Expand All @@ -104,4 +105,26 @@ contract Solver {
_simulationOverhead += gasStart - gasleft() + 4460;
}
}

/// @dev Helper function that reads and stores the balances of the `settlementContract` for each token in `tokens`.
/// @param tokens - list of tokens used in the trade
/// @param settlementContract - the settlement contract whose balances are being read
function _storeSettlementBalances(address[] calldata tokens, ISettlement settlementContract) internal {
for (uint256 i = 0; i < tokens.length; i++) {
this.storeBalance(tokens[i], address(settlementContract), false);
}
}

/// @dev Executes the settlement and measures the gas used.
/// @param settlementContract The address of the settlement contract.
/// @param settlementCall The calldata for the settlement function.
/// @return gasUsed The amount of gas used during the settlement execution.
function _executeSettlement(
address settlementContract,
bytes calldata settlementCall
) private returns (uint256 gasUsed) {
uint256 gasStart = gasleft();
address(settlementContract).doCall(settlementCall);
gasUsed = gasStart - gasleft() - _simulationOverhead;
}
squadgazzz marked this conversation as resolved.
Show resolved Hide resolved
}
1 change: 1 addition & 0 deletions crates/e2e/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ anyhow = { workspace = true }
async-trait = { workspace = true }
autopilot = { path = "../autopilot" }
axum = { workspace = true }
bigdecimal = { workspace = true }
chrono = { workspace = true }
clap = { workspace = true }
contracts = { path = "../contracts" }
Expand Down
13 changes: 8 additions & 5 deletions crates/e2e/tests/e2e/quote_verification.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use {
bigdecimal::{BigDecimal, Zero},
e2e::setup::*,
ethcontract::H160,
ethrpc::Web3,
Expand All @@ -13,7 +14,7 @@ use {
Estimate,
Verification,
},
trade_finding::{Interaction, Trade},
trade_finding::{Interaction, LegacyTrade, TradeKind},
},
std::{str::FromStr, sync::Arc},
};
Expand Down Expand Up @@ -61,8 +62,10 @@ async fn test_bypass_verification_for_rfq_quotes(web3: Web3) {
block_stream,
onchain.contracts().gp_settlement.address(),
onchain.contracts().weth.address(),
0.0,
);
BigDecimal::zero(),
)
.await
.unwrap();

let verify_trade = |tx_origin| {
let verifier = verifier.clone();
Expand All @@ -86,7 +89,7 @@ async fn test_bypass_verification_for_rfq_quotes(web3: Web3) {
sell_token_source: SellTokenSource::Erc20,
buy_token_destination: BuyTokenDestination::Erc20,
},
Trade {
TradeKind::Legacy(LegacyTrade {
out_amount: 16380122291179526144u128.into(),
gas_estimate: Some(225000),
interactions: vec![Interaction {
Expand All @@ -98,7 +101,7 @@ async fn test_bypass_verification_for_rfq_quotes(web3: Web3) {
solver: H160::from_str("0xe3067c7c27c1038de4e8ad95a83b927d23dfbd99")
.unwrap(),
tx_origin,
},
}),
)
.await
}
Expand Down
1 change: 1 addition & 0 deletions crates/orderbook/src/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ pub async fn run(args: Arguments) {
code_fetcher: code_fetcher.clone(),
},
)
.await
.expect("failed to initialize price estimator factory");

let native_price_estimator = price_estimator_factory
Expand Down
31 changes: 18 additions & 13 deletions crates/shared/src/price_estimation/factory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,28 +73,30 @@ pub struct Components {
}

impl<'a> PriceEstimatorFactory<'a> {
pub fn new(
pub async fn new(
args: &'a Arguments,
shared_args: &'a arguments::Arguments,
network: Network,
components: Components,
) -> Result<Self> {
Ok(Self {
trade_verifier: Self::trade_verifier(args, shared_args, &network, &components),
trade_verifier: Self::trade_verifier(args, shared_args, &network, &components).await?,
args,
network,
components,
estimators: HashMap::new(),
})
}

fn trade_verifier(
async fn trade_verifier(
args: &'a Arguments,
shared_args: &arguments::Arguments,
network: &Network,
components: &Components,
) -> Option<Arc<dyn TradeVerifying>> {
let web3 = network.simulation_web3.clone()?;
) -> Result<Option<Arc<dyn TradeVerifying>>> {
let Some(web3) = network.simulation_web3.clone() else {
squadgazzz marked this conversation as resolved.
Show resolved Hide resolved
return Ok(None);
};
let web3 = ethrpc::instrumented::instrument_with_label(&web3, "simulator".into());

let tenderly = shared_args
Expand All @@ -111,14 +113,17 @@ impl<'a> PriceEstimatorFactory<'a> {
None => Arc::new(web3.clone()),
};

Some(Arc::new(TradeVerifier::new(
web3,
simulator,
components.code_fetcher.clone(),
network.block_stream.clone(),
network.settlement,
network.native_token,
args.quote_inaccuracy_limit,
Ok(Some(Arc::new(
TradeVerifier::new(
web3,
simulator,
components.code_fetcher.clone(),
network.block_stream.clone(),
network.settlement,
network.native_token,
args.quote_inaccuracy_limit.clone(),
)
.await?,
)))
}

Expand Down
3 changes: 2 additions & 1 deletion crates/shared/src/price_estimation/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use {
trade_finding::Interaction,
},
anyhow::Result,
bigdecimal::BigDecimal,
ethcontract::{H160, U256},
futures::future::BoxFuture,
itertools::Itertools,
Expand Down Expand Up @@ -192,7 +193,7 @@ pub struct Arguments {
/// E.g. a value of `0.01` means at most 1 percent of the sell or buy tokens
/// can be paid out of the settlement contract buffers.
#[clap(long, env, default_value = "1.")]
pub quote_inaccuracy_limit: f64,
pub quote_inaccuracy_limit: BigDecimal,

/// How strict quote verification should be.
#[clap(
Expand Down
Loading
Loading