Skip to content

Commit 66aea2d

Browse files
committed
Feature flag for sell=buy
1 parent c7703ab commit 66aea2d

File tree

5 files changed

+187
-38
lines changed

5 files changed

+187
-38
lines changed

crates/e2e/tests/e2e/place_order_with_quote.rs

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@ async fn local_node_place_order_with_quote_same_token_pair() {
2929
run_test(place_order_with_quote_same_token_pair).await;
3030
}
3131

32+
#[tokio::test]
33+
#[ignore]
34+
async fn local_node_place_order_with_quote_same_token_pair_error() {
35+
run_test(place_order_with_quote_same_token_pair_error).await;
36+
}
37+
3238
async fn place_order_with_quote(web3: Web3) {
3339
let mut onchain = OnchainComponents::deploy(web3.clone()).await;
3440

@@ -121,7 +127,7 @@ async fn place_order_with_quote(web3: Web3) {
121127
assert_eq!(quote_metadata.unwrap().0, order_quote.metadata);
122128
}
123129

124-
async fn place_order_with_quote_same_token_pair(web3: Web3) {
130+
async fn place_order_with_quote_same_token_pair_error(web3: Web3) {
125131
let mut onchain = OnchainComponents::deploy(web3.clone()).await;
126132

127133
let [solver] = onchain.make_solvers(to_wei(10).into_alloy()).await;
@@ -130,7 +136,7 @@ async fn place_order_with_quote_same_token_pair(web3: Web3) {
130136
.deploy_tokens_with_weth_uni_v2_pools(to_wei(1_000), to_wei(1_000))
131137
.await;
132138

133-
token.mint(trader.address(), to_wei(10)).await;
139+
token.mint(trader.address(), eth(10)).await;
134140

135141
token
136142
.approve(onchain.contracts().allowance.into_alloy(), eth(10))
@@ -143,6 +149,58 @@ async fn place_order_with_quote_same_token_pair(web3: Web3) {
143149
let services = Services::new(&onchain).await;
144150
services.start_protocol(solver.clone()).await;
145151

152+
// Disable auto-mine so we don't accidentally mine a settlement
153+
web3.api::<TestNodeApi<_>>()
154+
.set_automine_enabled(false)
155+
.await
156+
.expect("Must be able to disable automine");
157+
158+
tracing::info!("Quoting");
159+
let quote_sell_amount = to_wei(1);
160+
let quote_request = OrderQuoteRequest {
161+
from: trader.address(),
162+
sell_token: *token.address(),
163+
buy_token: *token.address(),
164+
side: OrderQuoteSide::Sell {
165+
sell_amount: SellAmount::BeforeFee {
166+
value: NonZeroU256::try_from(quote_sell_amount).unwrap(),
167+
},
168+
},
169+
..Default::default()
170+
};
171+
assert!(services.submit_quote(&quote_request).await.is_err());
172+
}
173+
174+
async fn place_order_with_quote_same_token_pair(web3: Web3) {
175+
let mut onchain = OnchainComponents::deploy(web3.clone()).await;
176+
177+
let [solver] = onchain.make_solvers(eth(10)).await;
178+
let [trader] = onchain.make_accounts(eth(10)).await;
179+
let [token] = onchain
180+
.deploy_tokens_with_weth_uni_v2_pools(to_wei(1_000), to_wei(1_000))
181+
.await;
182+
183+
token.mint(trader.address(), eth(10)).await;
184+
185+
token
186+
.approve(onchain.contracts().allowance.into_alloy(), eth(10))
187+
.from(trader.address())
188+
.send_and_watch()
189+
.await
190+
.unwrap();
191+
192+
tracing::info!("Starting services.");
193+
let services = Services::new(&onchain).await;
194+
services
195+
.start_protocol_with_args(
196+
ExtraServiceArgs {
197+
api: vec!["--allow-same-sell-and-buy-token=true".to_string()],
198+
..Default::default()
199+
},
200+
solver.clone(),
201+
)
202+
.await;
203+
146204
// Disable auto-mine so we don't accidentally mine a settlement
147205
web3.api::<TestNodeApi<_>>()
148206
.set_automine_enabled(false)

crates/orderbook/src/api/post_order.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,13 @@ impl IntoWarpReply for PartialValidationErrorWrapper {
7272
),
7373
StatusCode::BAD_REQUEST,
7474
),
75+
PartialValidationError::SameBuyAndSellToken => with_status(
76+
error(
77+
"SameBuyAndSellToken",
78+
"Buy token is the same as the sell token.",
79+
),
80+
StatusCode::BAD_REQUEST,
81+
),
7582
PartialValidationError::UnsupportedToken { token, reason } => with_status(
7683
error(
7784
"UnsupportedToken",

crates/orderbook/src/arguments.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,10 @@ pub struct Arguments {
145145

146146
#[clap(flatten)]
147147
pub volume_fee_config: Option<VolumeFeeConfig>,
148+
149+
/// Allow same sell and buy token
150+
#[clap(long, env, action = clap::ArgAction::Set, default_value = "false")]
151+
pub allow_same_sell_and_buy_token: bool,
148152
}
149153

150154
/// Volume-based protocol fee factor to be applied to quotes.
@@ -234,6 +238,7 @@ impl std::fmt::Display for Arguments {
234238
max_gas_per_order,
235239
active_order_competition_threshold,
236240
volume_fee_config,
241+
allow_same_sell_and_buy_token,
237242
} = self;
238243

239244
write!(f, "{shared}")?;
@@ -288,6 +293,10 @@ impl std::fmt::Display for Arguments {
288293
"active_order_competition_threshold: {active_order_competition_threshold}"
289294
)?;
290295
writeln!(f, "volume_fee_config: {volume_fee_config:?}")?;
296+
writeln!(
297+
f,
298+
"allow_same_sell_and_buy_token: {allow_same_sell_and_buy_token}"
299+
)?;
291300

292301
Ok(())
293302
}

crates/orderbook/src/run.rs

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -401,25 +401,30 @@ pub async fn run(args: Arguments) {
401401
let chainalysis_oracle = ChainalysisOracle::Instance::deployed(&web3.alloy)
402402
.await
403403
.ok();
404-
let order_validator = Arc::new(OrderValidator::new(
405-
Arc::new(order_validation::banned::Users::new(
406-
chainalysis_oracle,
407-
args.banned_users,
408-
args.banned_users_max_cache_size.get().to_u64().unwrap(),
409-
)),
410-
validity_configuration,
411-
args.eip1271_skip_creation_validation,
412-
bad_token_detector.clone(),
413-
hooks_contract,
414-
optimal_quoter.clone(),
415-
balance_fetcher,
416-
signature_validator,
417-
Arc::new(postgres_write.clone()),
418-
args.max_limit_orders_per_user,
419-
code_fetcher,
420-
app_data_validator.clone(),
421-
args.max_gas_per_order,
422-
));
404+
let order_validator = Arc::new(
405+
OrderValidator::new(
406+
Arc::new(order_validation::banned::Users::new(
407+
chainalysis_oracle,
408+
args.banned_users,
409+
args.banned_users_max_cache_size.get().to_u64().unwrap(),
410+
)),
411+
validity_configuration,
412+
args.eip1271_skip_creation_validation,
413+
bad_token_detector.clone(),
414+
hooks_contract,
415+
optimal_quoter.clone(),
416+
balance_fetcher,
417+
signature_validator,
418+
Arc::new(postgres_write.clone()),
419+
args.max_limit_orders_per_user,
420+
code_fetcher,
421+
app_data_validator.clone(),
422+
args.max_gas_per_order,
423+
)
424+
.with_sell_and_buy_validation(
425+
(!args.allow_same_sell_and_buy_token).then(|| native_token.clone()),
426+
),
427+
);
423428
let ipfs = args
424429
.ipfs_gateway
425430
.map(|url| {

0 commit comments

Comments
 (0)