tempo_bench/cmd/max_tps/
dex.rs1use super::*;
2use alloy::providers::DynProvider;
3use indicatif::ProgressIterator;
4use tempo_contracts::precompiles::{IStablecoinExchange, PATH_USD_ADDRESS};
5use tempo_precompiles::tip20::U128_MAX;
6
7pub(super) async fn setup(
13 signer_providers: &[(PrivateKeySigner, DynProvider<TempoNetwork>)],
14 user_tokens: usize,
15 max_concurrent_requests: usize,
16 max_concurrent_transactions: usize,
17) -> eyre::Result<(Address, Vec<Address>)> {
18 let (signer, provider) = signer_providers
20 .first()
21 .ok_or_eyre("No signer providers found")?;
22 let caller = signer.address();
23
24 info!(user_tokens, "Creating TIP-20 tokens");
25 let progress = ProgressBar::new(user_tokens as u64 + 1);
26 let quote_token = setup_test_token(provider.clone(), caller, PATH_USD_ADDRESS).await?;
28 progress.inc(1);
29 let user_tokens = stream::iter((0..user_tokens).progress_with(progress))
31 .map(|_| setup_test_token(provider.clone(), caller, *quote_token.address()))
32 .buffered(max_concurrent_requests)
33 .try_collect::<Vec<_>>()
34 .await?;
35
36 let user_token_addresses = user_tokens
37 .iter()
38 .map(|token| *token.address())
39 .collect::<Vec<_>>();
40 let all_tokens = user_tokens
41 .iter()
42 .cloned()
43 .chain(std::iter::once(quote_token.clone()))
44 .collect::<Vec<_>>();
45 let all_token_addresses = all_tokens
46 .iter()
47 .map(|token| *token.address())
48 .collect::<Vec<_>>();
49
50 info!("Creating exchange pairs");
52 let exchange = IStablecoinExchange::new(STABLECOIN_EXCHANGE_ADDRESS, provider.clone());
53 join_all(
54 user_token_addresses
55 .iter()
56 .copied()
57 .map(|token| {
58 let exchange = exchange.clone();
59 Box::pin(async move {
60 let tx = exchange.createPair(token);
61 tx.send().await
62 }) as BoxFuture<'static, _>
63 })
64 .progress(),
65 max_concurrent_requests,
66 max_concurrent_transactions,
67 )
68 .await
69 .context("Failed to create exchange pairs")?;
70
71 let mint_amount = U128_MAX / U256::from(signer_providers.len());
73 info!(%mint_amount, "Minting TIP-20 tokens");
74 join_all(
75 signer_providers
76 .iter()
77 .map(|(signer, _)| signer.address())
78 .flat_map(|signer| {
79 all_tokens.iter().map(move |token| {
80 let token = token.clone();
81 Box::pin(async move {
82 let tx = token.mint(signer, mint_amount);
83 tx.send().await
84 }) as BoxFuture<'static, _>
85 })
86 })
87 .progress_count((signer_providers.len() * all_tokens.len()) as u64),
88 max_concurrent_requests,
89 max_concurrent_transactions,
90 )
91 .await
92 .context("Failed to mint TIP-20 tokens")?;
93
94 info!("Approving tokens");
96 join_all(
97 signer_providers
98 .iter()
99 .flat_map(|(_, provider)| {
100 all_token_addresses.iter().copied().map(move |token| {
101 let token = ITIP20Instance::new(token, provider.clone());
102 Box::pin(async move {
103 let tx = token.approve(STABLECOIN_EXCHANGE_ADDRESS, U256::MAX);
104 tx.send().await
105 }) as BoxFuture<'static, _>
106 })
107 })
108 .progress_count((signer_providers.len() * all_tokens.len()) as u64),
109 max_concurrent_requests,
110 max_concurrent_transactions,
111 )
112 .await
113 .context("Failed to approve TIP-20 tokens")?;
114
115 let order_amount = 1000000000000u128;
117 let tick_over = exchange.priceToTick(100010).call().await?;
118 let tick_under = exchange.priceToTick(99990).call().await?;
119 info!(order_amount, tick_over, tick_under, "Placing flip orders");
120 join_all(
121 signer_providers
122 .iter()
123 .flat_map(|(_, provider)| {
124 user_token_addresses.iter().copied().map(move |token| {
125 let exchange = IStablecoinExchangeInstance::new(
126 STABLECOIN_EXCHANGE_ADDRESS,
127 provider.clone(),
128 );
129 Box::pin(async move {
130 let tx =
131 exchange.placeFlip(token, order_amount, true, tick_under, tick_over);
132 tx.send().await
133 }) as BoxFuture<'static, _>
134 })
135 })
136 .progress_count((signer_providers.len() * user_tokens.len()) as u64),
137 max_concurrent_requests,
138 max_concurrent_transactions,
139 )
140 .await
141 .context("Failed to place flip orders")?;
142
143 Ok((*quote_token.address(), user_token_addresses))
144}
145
146async fn setup_test_token(
148 provider: DynProvider<TempoNetwork>,
149 admin: Address,
150 quote_token: Address,
151) -> eyre::Result<ITIP20Instance<DynProvider<TempoNetwork>, TempoNetwork>>
152where
153{
154 let factory = ITIP20Factory::new(TIP20_FACTORY_ADDRESS, provider.clone());
155 let receipt = factory
156 .createToken(
157 "Test".to_owned(),
158 "TEST".to_owned(),
159 "USD".to_owned(),
160 quote_token,
161 admin,
162 )
163 .send()
164 .await?
165 .get_receipt()
166 .await?;
167 let event = receipt
168 .decoded_log::<ITIP20Factory::TokenCreated>()
169 .ok_or_eyre("Token creation event not found")?;
170 assert_receipt(receipt)
171 .await
172 .context("Failed to create TIP-20 token")?;
173
174 let token_addr = token_id_to_address(event.tokenId.to());
175 let token = ITIP20::new(token_addr, provider.clone());
176 let roles = IRolesAuth::new(*token.address(), provider);
177 let grant_role_receipt = roles
178 .grantRole(*ISSUER_ROLE, admin)
179 .send()
180 .await?
181 .get_receipt()
182 .await?;
183 assert_receipt(grant_role_receipt)
184 .await
185 .context("Failed to grant issuer role")?;
186
187 Ok(token)
188}