-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathbids.rs
More file actions
100 lines (89 loc) · 2.99 KB
/
bids.rs
File metadata and controls
100 lines (89 loc) · 2.99 KB
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
use crate::{auction::AuctionParams, config::BidParams, registry::PlannedBid};
use alloy::primitives::U256;
use tracing::warn;
pub fn align_price_to_tick(price: U256, params: &AuctionParams) -> U256 {
let floor = params.floor_price;
let spacing = params.tick_spacing;
let cap = params.max_bid_price;
if price >= cap {
return cap;
}
if price <= floor {
return floor;
}
let offset = price - floor;
let rem = offset % spacing;
if rem.is_zero() {
return price.min(cap);
}
let down = price - rem;
let up = down + spacing;
let choose_up = rem > spacing - rem;
let candidate = if choose_up { up } else { down };
candidate.min(cap)
}
pub fn preprocess_bids(bids: &[BidParams], params: &AuctionParams) -> Vec<PlannedBid> {
bids.iter()
.cloned()
.map(|mut bid| {
let aligned = align_price_to_tick(bid.max_bid, params);
if aligned != bid.max_bid {
warn!(
owner = ?bid.owner,
original = %bid.max_bid,
adjusted = %aligned,
"max bid adjusted to nearest tick"
);
bid.max_bid = aligned;
}
PlannedBid::new(bid)
})
.collect()
}
#[cfg(test)]
mod tests {
use super::align_price_to_tick;
use crate::auction::AuctionParams;
use alloy::primitives::U256;
fn params() -> AuctionParams {
use std::str::FromStr;
AuctionParams {
contributor_period_end_block: U256::ZERO,
max_purchase_limit: U256::ZERO,
floor_price: U256::from_str("753956294022871543408300").unwrap(),
tick_spacing: U256::from_str("7539562940228715434083").unwrap(),
max_bid_price: U256::from_str("217900404829510685459725614601655060836").unwrap(),
end_block: U256::ZERO,
total_purchased: U256::ZERO,
has_any_token: true,
}
}
#[test]
fn keeps_aligned_prices() {
let params = params();
use std::str::FromStr;
let aligned = vec![
U256::from_str("19807042548578993971286201723").unwrap(),
U256::from_str("784114545783786405144632").unwrap(),
U256::from_str("1839653357415806565916252").unwrap(),
];
for price in aligned {
assert_eq!(align_price_to_tick(price, ¶ms), price);
}
}
#[test]
fn snaps_to_nearest_tick() {
let params = params();
let spacing = params.tick_spacing;
let floor = params.floor_price;
let price = floor + spacing * U256::from(10) + spacing / U256::from(3);
let expected = floor + spacing * U256::from(10);
assert_eq!(align_price_to_tick(price, ¶ms), expected);
}
#[test]
fn clamps_above_cap() {
let params = params();
let price = params.max_bid_price + U256::from(1);
assert_eq!(align_price_to_tick(price, ¶ms), params.max_bid_price);
}
}