tempo_bench/cmd/max_tps/
dex.rs1use super::*;
2use alloy::providers::DynProvider;
3use indicatif::ProgressIterator;
4use tempo_contracts::precompiles::{IStablecoinDEX, PATH_USD_ADDRESS};
5use tempo_precompiles::tip20::U128_MAX;
6
7pub(super) async fn setup(
13 signer_providers: &[(Secp256k1Signer, 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 = IStablecoinDEX::new(STABLECOIN_DEX_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_DEX_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 =
126 IStablecoinDEXInstance::new(STABLECOIN_DEX_ADDRESS, provider.clone());
127 Box::pin(async move {
128 let tx =
129 exchange.placeFlip(token, order_amount, true, tick_under, tick_over);
130 tx.send().await
131 }) as BoxFuture<'static, _>
132 })
133 })
134 .progress_count((signer_providers.len() * user_tokens.len()) as u64),
135 max_concurrent_requests,
136 max_concurrent_transactions,
137 )
138 .await
139 .context("Failed to place flip orders")?;
140
141 Ok((*quote_token.address(), user_token_addresses))
142}
143
144async fn setup_test_token(
146 provider: DynProvider<TempoNetwork>,
147 admin: Address,
148 quote_token: Address,
149) -> eyre::Result<ITIP20Instance<DynProvider<TempoNetwork>, TempoNetwork>>
150where
151{
152 let factory = ITIP20Factory::new(TIP20_FACTORY_ADDRESS, provider.clone());
153 let salt = alloy::primitives::B256::random();
154 let receipt = factory
155 .createToken(
156 "Test".to_owned(),
157 "TEST".to_owned(),
158 "USD".to_owned(),
159 quote_token,
160 admin,
161 salt,
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 = event.token;
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}