1use schemars::JsonSchema;
2use serde::{Deserialize, Serialize};
3
4use crate::i128::Int128;
5use cosmwasm_std::{Addr, Timestamp, Uint128};
6use cw_storage_plus::{Item, Map};
7use tg_utils::Duration;
8pub use tg_utils::{PREAUTH_SLASHING, SLASHERS};
9
10#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)]
11pub struct Halflife {
12 pub halflife: Option<Duration>,
14
15 pub last_applied: Timestamp,
16}
17
18impl Halflife {
19 pub fn should_apply(&self, t: Timestamp) -> bool {
20 if let Some(halflife) = self.halflife {
21 halflife.after_time(self.last_applied).is_expired_time(t)
22 } else {
23 false
24 }
25 }
26}
27
28pub const SHARES_SHIFT: u8 = 32;
37
38pub const HALFLIFE: Item<Halflife> = Item::new("halflife");
39
40#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)]
41pub struct Distribution {
42 pub denom: String,
44 pub shares_per_point: Uint128,
46 pub shares_leftover: u64,
48 pub distributed_total: Uint128,
50 pub withdrawable_total: Uint128,
52}
53
54#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)]
55pub struct WithdrawAdjustment {
56 pub shares_correction: Int128,
58 pub withdrawn_rewards: Uint128,
60 pub delegated: Addr,
62}
63
64pub const DISTRIBUTION: Item<Distribution> = Item::new("distribution");
66pub const WITHDRAW_ADJUSTMENT: Map<&Addr, WithdrawAdjustment> = Map::new("withdraw_adjustment");
68
69#[cfg(test)]
70mod tests {
71 use super::*;
72
73 #[test]
74 fn halflife_should_apply() {
75 let epoch = 123456789;
76 let hf = Halflife {
77 halflife: None,
78 last_applied: Timestamp::from_seconds(epoch),
79 };
80 assert!(!hf.should_apply(Timestamp::from_seconds(epoch)));
81
82 let hf = Halflife {
83 halflife: Some(Duration::new(epoch + 1)),
84 last_applied: Timestamp::from_seconds(epoch),
85 };
86 assert!(!hf.should_apply(Timestamp::from_seconds(epoch)));
87
88 let hf = Halflife {
89 halflife: Some(Duration::new(epoch + 1)),
90 last_applied: Timestamp::from_seconds(epoch),
91 };
92 assert!(hf.should_apply(Timestamp::from_seconds(epoch * 2 + 1)));
94
95 let hf = Halflife {
96 halflife: Some(Duration::new(epoch + 1)),
97 last_applied: Timestamp::from_seconds(epoch + 2),
98 };
99 assert!(!hf.should_apply(Timestamp::from_seconds(epoch + 2)));
100
101 let hf = Halflife {
102 halflife: Some(Duration::new(epoch + 1)),
103 last_applied: Timestamp::from_seconds(epoch + 2),
104 };
105 assert!(hf.should_apply(Timestamp::from_seconds(epoch * 2 + 3)));
106 }
107}