Skip to main content

karak_contracts/core/
contract.rs

1use std::fmt::{Debug, Display};
2
3use alloy::{
4    providers::PendingTransactionError, rpc::json_rpc::ErrorPayload, sol,
5    transports::TransportError,
6};
7use serde::{ser::SerializeStruct, Serialize};
8use Operator::{QueuedStakeUpdate, StakeUpdateRequest};
9use VaultLib::Config;
10
11use crate::{error::DecodeError, impl_decode_error};
12
13use super::library;
14
15sol!(
16    #[allow(missing_docs)]
17    #[sol(rpc)]
18    Core,
19    "abi/Core.json",
20);
21
22impl std::fmt::Debug for Core::CoreErrors {
23    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
24        match self {
25            Core::CoreErrors::AlreadyInitialized(_) => write!(f, "AlreadyInitialized"),
26            Core::CoreErrors::AssetNotAllowlisted(_) => write!(f, "AssetNotAllowlisted"),
27            Core::CoreErrors::AttemptedPauseWhileUnpausing(_) => {
28                write!(f, "AttemptedPauseWhileUnpausing")
29            }
30            Core::CoreErrors::AttemptedUnpauseWhilePausing(_) => {
31                write!(f, "AttemptedUnpauseWhilePausing")
32            }
33            Core::CoreErrors::DSSAlreadyRegistered(_) => write!(f, "DSSAlreadyRegistered"),
34            Core::CoreErrors::DSSHookCallReverted(_) => write!(f, "DSSHookCallReverted"),
35            Core::CoreErrors::DSSNotRegistered(_) => write!(f, "DSSNotRegistered"),
36            Core::CoreErrors::DuplicateSlashingVaults(_) => write!(f, "DuplicateSlashingVaults"),
37            Core::CoreErrors::EmptyArray(_) => write!(f, "EmptyArray"),
38            Core::CoreErrors::EnforcedPause(_) => write!(f, "EnforcedPause"),
39            Core::CoreErrors::EnforcedPauseFunction(_) => write!(f, "EnforcedPauseFunction"),
40            Core::CoreErrors::InvalidInitialization(_) => write!(f, "InvalidInitialization"),
41            Core::CoreErrors::InvalidSlashingCount(_) => write!(f, "InvalidSlashingCount"),
42            Core::CoreErrors::InvalidSlashingParams(_) => write!(f, "InvalidSlashingParams"),
43            Core::CoreErrors::LengthsDontMatch(_) => write!(f, "LengthsDontMatch"),
44            Core::CoreErrors::MathOverflowedMulDiv(_) => write!(f, "MathOverflowedMulDiv"),
45            Core::CoreErrors::MaxSlashPercentageWadBreached(_) => {
46                write!(f, "MaxSlashPercentageWadBreached")
47            }
48            Core::CoreErrors::MaxSlashableVaultsPerRequestBreached(_) => {
49                write!(f, "MaxSlashableVaultsPerRequestBreached")
50            }
51            Core::CoreErrors::MaxVaultCapacityReached(_) => write!(f, "MaxVaultCapacityReached"),
52            Core::CoreErrors::MinSlashingDelayNotPassed(_) => {
53                write!(f, "MinSlashingDelayNotPassed")
54            }
55            Core::CoreErrors::NewOwnerIsZeroAddress(_) => write!(f, "NewOwnerIsZeroAddress"),
56            Core::CoreErrors::NoHandoverRequest(_) => write!(f, "NoHandoverRequest"),
57            Core::CoreErrors::NotEnoughGas(_) => write!(f, "NotEnoughGas"),
58            Core::CoreErrors::NotInitializing(_) => write!(f, "NotInitializing"),
59            Core::CoreErrors::NotSmartContract(_) => write!(f, "NotSmartContract"),
60            Core::CoreErrors::OperatorNotValidatingForDSS(_) => {
61                write!(f, "OperatorNotValidatingForDSS")
62            }
63            Core::CoreErrors::Reentrancy(_) => write!(f, "Reentrancy"),
64            Core::CoreErrors::ReservedAddress(_) => write!(f, "ReservedAddress"),
65            Core::CoreErrors::SlashingCooldownNotPassed(_) => {
66                write!(f, "SlashingCooldownNotPassed")
67            }
68            Core::CoreErrors::Unauthorized(_) => write!(f, "Unauthorized"),
69            Core::CoreErrors::VaultCreationFailedAddrMismatch(mismatch) => {
70                write!(
71                    f,
72                    "VaultCreationFailedAddrMismatch {{ expected: {}, actual: {} }}",
73                    mismatch.expected, mismatch.actual
74                )
75            }
76            Core::CoreErrors::VaultImplNotAllowlisted(_) => write!(f, "VaultImplNotAllowlisted"),
77            Core::CoreErrors::VaultNotAChildVault(_) => write!(f, "VaultNotAChildVault"),
78            Core::CoreErrors::VaultNotStakedToDSS(_) => write!(f, "VaultNotStakedToDSS"),
79            Core::CoreErrors::ZeroAddress(_) => write!(f, "ZeroAddress"),
80            Core::CoreErrors::ZeroSlashPercentageWad(_) => write!(f, "ZeroSlashPercentageWad"),
81        }
82    }
83}
84
85impl Display for Core::CoreErrors {
86    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
87        match self {
88            Core::CoreErrors::AlreadyInitialized(_) => write!(f, "Already initialized"),
89            Core::CoreErrors::AssetNotAllowlisted(_) => {
90                write!(f, "Asset not allowlisted")
91            }
92            Core::CoreErrors::AttemptedPauseWhileUnpausing(_) => {
93                write!(f, "Attempted pause while unpausing")
94            }
95            Core::CoreErrors::AttemptedUnpauseWhilePausing(_) => {
96                write!(f, "Attempted unpause while pausing")
97            }
98            Core::CoreErrors::DSSAlreadyRegistered(_) => write!(f, "DSS already registered"),
99            Core::CoreErrors::DSSHookCallReverted(e) => {
100                write!(f, "DSS hook call reverted with error: {}", e.revertReason)
101            }
102            Core::CoreErrors::DSSNotRegistered(_) => write!(f, "DSS not registered"),
103            Core::CoreErrors::DuplicateSlashingVaults(_) => write!(f, "Duplicate slashing vaults"),
104            Core::CoreErrors::EmptyArray(_) => write!(f, "Empty array"),
105            Core::CoreErrors::EnforcedPause(_) => write!(f, "Enforced pause"),
106            Core::CoreErrors::EnforcedPauseFunction(_) => write!(f, "Enforced pause function"),
107            Core::CoreErrors::InvalidInitialization(_) => write!(f, "Invalid initialization"),
108            Core::CoreErrors::InvalidSlashingCount(_) => write!(f, "Invalid slashing count"),
109            Core::CoreErrors::InvalidSlashingParams(_) => write!(f, "Invalid slashing params"),
110            Core::CoreErrors::LengthsDontMatch(_) => write!(f, "Lengths don't match"),
111            Core::CoreErrors::MathOverflowedMulDiv(_) => write!(f, "Math overflowed mul div"),
112            Core::CoreErrors::MaxSlashPercentageWadBreached(_) => {
113                write!(f, "Max slash percentage wad breached")
114            }
115            Core::CoreErrors::MaxSlashableVaultsPerRequestBreached(_) => {
116                write!(f, "Max slashable vaults per request breached")
117            }
118            Core::CoreErrors::MaxVaultCapacityReached(_) => write!(f, "Max vault capacity reached"),
119            Core::CoreErrors::MinSlashingDelayNotPassed(_) => {
120                write!(f, "Min slashing delay not passed")
121            }
122            Core::CoreErrors::NewOwnerIsZeroAddress(_) => write!(f, "New owner is zero address"),
123            Core::CoreErrors::NoHandoverRequest(_) => write!(f, "No handover request"),
124            Core::CoreErrors::NotEnoughGas(_) => write!(f, "Not enough gas"),
125            Core::CoreErrors::NotInitializing(_) => write!(f, "Not initializing"),
126            Core::CoreErrors::NotSmartContract(_) => write!(f, "Not smart contract"),
127            Core::CoreErrors::OperatorNotValidatingForDSS(_) => {
128                write!(f, "Operator not validating for DSS")
129            }
130            Core::CoreErrors::Reentrancy(_) => write!(f, "Reentrancy"),
131            Core::CoreErrors::ReservedAddress(_) => write!(f, "Reserved address"),
132            Core::CoreErrors::SlashingCooldownNotPassed(_) => {
133                write!(f, "Slashing cooldown not passed")
134            }
135            Core::CoreErrors::Unauthorized(_) => write!(f, "Unauthorized"),
136            Core::CoreErrors::VaultCreationFailedAddrMismatch(e) => {
137                write!(
138                    f,
139                    "Vault creation failed address mismatch, expected {}, got {}",
140                    e.expected, e.actual
141                )
142            }
143            Core::CoreErrors::VaultImplNotAllowlisted(_) => write!(f, "Vault impl not allowlisted"),
144            Core::CoreErrors::VaultNotAChildVault(_) => write!(f, "Vault not a child vault"),
145            Core::CoreErrors::VaultNotStakedToDSS(_) => write!(f, "Vault not staked to DSS"),
146            Core::CoreErrors::ZeroAddress(_) => write!(f, "Zero address"),
147            Core::CoreErrors::ZeroSlashPercentageWad(_) => write!(f, "Zero slash percentage wad"),
148        }
149    }
150}
151
152impl_decode_error!(Core::CoreErrors);
153
154#[derive(thiserror::Error, Debug)]
155pub enum CoreError<E: std::fmt::Debug> {
156    #[error("Core error: {0}")]
157    Core(Core::CoreErrors),
158    #[error("Operator error: {0}")]
159    Operator(library::operator::Operator::OperatorErrors),
160    #[error(transparent)]
161    Inner(E),
162}
163
164impl<E: std::fmt::Debug> From<Core::CoreErrors> for CoreError<E> {
165    fn from(error: Core::CoreErrors) -> Self {
166        CoreError::Core(error)
167    }
168}
169
170impl From<ErrorPayload> for CoreError<ErrorPayload> {
171    fn from(value: ErrorPayload) -> Self {
172        match Core::CoreErrors::decode_error(&value) {
173            Some(error) => CoreError::Core(error),
174            None => match library::operator::Operator::OperatorErrors::decode_error(&value) {
175                Some(error) => CoreError::Operator(error),
176                None => CoreError::Inner(value),
177            },
178        }
179    }
180}
181
182impl From<TransportError> for CoreError<TransportError> {
183    fn from(value: TransportError) -> Self {
184        match Core::CoreErrors::decode_error(&value) {
185            Some(error) => CoreError::Core(error),
186            None => match library::operator::Operator::OperatorErrors::decode_error(&value) {
187                Some(error) => CoreError::Operator(error),
188                None => CoreError::Inner(value),
189            },
190        }
191    }
192}
193
194impl From<alloy::contract::Error> for CoreError<alloy::contract::Error> {
195    fn from(value: alloy::contract::Error) -> Self {
196        match Core::CoreErrors::decode_error(&value) {
197            Some(error) => CoreError::Core(error),
198            None => match library::operator::Operator::OperatorErrors::decode_error(&value) {
199                Some(error) => CoreError::Operator(error),
200                None => CoreError::Inner(value),
201            },
202        }
203    }
204}
205
206impl From<PendingTransactionError> for CoreError<PendingTransactionError> {
207    fn from(value: PendingTransactionError) -> Self {
208        match Core::CoreErrors::decode_error(&value) {
209            Some(error) => CoreError::Core(error),
210            None => match library::operator::Operator::OperatorErrors::decode_error(&value) {
211                Some(error) => CoreError::Operator(error),
212                None => CoreError::Inner(value),
213            },
214        }
215    }
216}
217
218impl Serialize for StakeUpdateRequest {
219    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
220    where
221        S: serde::Serializer,
222    {
223        let mut state = serializer.serialize_struct("StakeUpdateRequest", 3)?;
224        state.serialize_field("vault", &self.vault)?;
225        state.serialize_field("dss", &self.dss)?;
226        state.serialize_field("toStake", &self.toStake)?;
227        state.end()
228    }
229}
230
231impl Serialize for QueuedStakeUpdate {
232    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
233    where
234        S: serde::Serializer,
235    {
236        let mut state = serializer.serialize_struct("QueuedStakeUpdate", 4)?;
237        state.serialize_field("nonce", &self.nonce)?;
238        state.serialize_field("startTimestamp", &self.startTimestamp)?;
239        state.serialize_field("operator", &self.operator)?;
240        state.serialize_field("updateRequest", &self.updateRequest)?;
241        state.end()
242    }
243}
244
245impl Serialize for Config {
246    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
247    where
248        S: serde::Serializer,
249    {
250        let mut state = serializer.serialize_struct("VaultConfig", 5)?;
251        state.serialize_field("asset", &self.asset)?;
252        state.serialize_field("decimals", &self.decimals)?;
253        state.serialize_field("name", &self.name)?;
254        state.serialize_field("symbol", &self.symbol)?;
255        state.serialize_field("operator", &self.operator)?;
256        state.end()
257    }
258}