1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
use ;
use ;
use crateEncodingError;
pub const DEFAULT_EXECUTORS_JSON: &str =
include_str!;
pub const DEFAULT_ROUTERS_JSON: &str = include_str!;
pub const PROTOCOL_SPECIFIC_CONFIG: &str =
include_str!;
/// Default router addresses keyed by chain, parsed from `config/router_addresses.json`.
pub static DEFAULT_ROUTER_ADDRESSES: = new;
/// Returns the default Tycho router address for `chain`, or an error if none is configured.
/// The address used by the TychoRouterV3 to represent native ETH.
///
/// Callers must use this address (not `address(0)`) for the `tokenIn` / `tokenOut`
/// parameters when ABI-encoding router function calls that involve native ETH.
/// The encoding pipeline's `EncodedSolution` only contains the inner swap bytes;
/// the outer function arguments — including the token addresses — are the caller's
/// responsibility.
pub static ROUTER_ETH_ADDRESS: = new;
/// The number of blocks in the future for which to fetch Angstrom Attestations
///
/// It is important to note that fetching more blocks will send more attestations to the
/// Tycho Router, resulting in a higher gas usage. Fetching fewer blocks may result in attestations
/// expiring if the transaction is not sent fast enough.
pub const ANGSTROM_DEFAULT_BLOCKS_IN_FUTURE: u64 = 5;
/// The endpoint serving Angstrom pool unlock attestations.
pub const ANGSTROM_DEFAULT_API_URL: &str =
"https://attestations.angstrom.xyz/getAttestations";
/// The size of a single Angstrom attestation, without its block number prefix.
///
/// The Uniswap V4 executor rejects attestation data that is not a whole number of
/// `8 + ANGSTROM_ATTESTATION_SIZE` byte entries.
pub const ANGSTROM_ATTESTATION_SIZE: usize = 85;
/// The shortest time Ethereum can take to produce a block, which both the refresh interval and
/// the maximum window age derive from.
///
/// Ethereum proposes at most one block every 12 seconds, and a skipped proposal only makes the
/// gap longer. Treating 12 seconds as one block therefore always overestimates how many blocks
/// have elapsed, which is the safe direction for both constants below.
const ETHEREUM_MIN_BLOCK_TIME_SECS: u64 = 12;
/// How many times per block the background prefetcher refreshes the attestation window.
///
/// The window's contents only change when a block is produced, so refreshing more than once per
/// block fetches nothing new. It is still more than once because the refresher has no block feed
/// to align to: sampling twice a block bounds how long it keeps serving the previous block's
/// window after a new one becomes available, without polling the API for the sake of it.
const ANGSTROM_ATTESTATION_REFRESHES_PER_BLOCK: u64 = 2;
/// How long the background prefetcher waits between Angstrom attestation refreshes.
pub const ANGSTROM_ATTESTATION_REFRESH_INTERVAL: Duration =
from_secs;
/// How many of the fetched window's blocks may elapse before the cache refetches while encoding.
///
/// A window fetched during block `N` covers `N` through `N + ANGSTROM_BLOCKS_IN_FUTURE`. Every
/// block that elapses before encoding spends one of those: it removes a block the transaction
/// could still have landed in, and adds an attestation the executor will skip. Keeping this at a
/// single block preserves all but one block of the caller's slack, at the price of refetching
/// inline sooner when the background refresh stalls.
const ANGSTROM_ATTESTATION_MAX_AGE_BLOCKS: u64 = 1;
/// How old a cached Angstrom attestation window may be before it is refetched while encoding.
///
/// Only reached when the background refresh has stopped keeping up: a healthy refresher replaces
/// the window every `ANGSTROM_ATTESTATION_REFRESH_INTERVAL`.
pub const ANGSTROM_ATTESTATION_MAX_AGE: Duration =
from_secs;
/// How long a single request to the Angstrom API may take before it is aborted.
///
/// Half the refresh interval, so one timed-out refresh cannot reach the encoding path: the next
/// refresh still replaces the window within `ANGSTROM_ATTESTATION_MAX_AGE` of the previous one
/// (3s aborted + 6s sleep + at most 3s for the retry). The slowest read measured against the
/// live API was 902ms, including DNS and TLS on a cold connection.
pub const ANGSTROM_API_TIMEOUT: Duration =
from_secs;
/// These protocols support the optimization of grouping swaps.
///
/// This requires special encoding to send call data of multiple swaps to a single executor,
/// as if it were a single swap. The protocol likely uses flash accounting to save gas on token
/// transfers.
pub static GROUPABLE_PROTOCOLS: = new;
/// These groupable protocols use simple concatenation instead of PLE when forming swap groups.
pub static NON_PLE_ENCODED_PROTOCOLS: = new;
/// Protocol system prefix carried by components sourced from the pAMM price level stream. The
/// venue suffix is either a configured name (e.g. `pricelevelstream:fermiswap`) or, for
/// auto-detected pAMMs, the venue address (e.g. `pricelevelstream:0x5979…`); every such protocol
/// maps to the generic `PropAMMSwapEncoder`.
pub const PRICE_LEVEL_STREAM_PREFIX: &str = "pricelevelstream:";
/// The executor-config key serving the whole price-level-stream protocol family: any
/// `pricelevelstream:{venue}` protocol without an exact entry of its own falls back to this one,
/// so a single configured executor address covers every pAMM, including auto-detected ones.
pub const PRICE_LEVEL_STREAM_KEY: &str = "pricelevelstream";