darkfi_money_contract/
error.rs

1/* This file is part of DarkFi (https://dark.fi)
2 *
3 * Copyright (C) 2020-2025 Dyne.org foundation
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Affero General Public License as
7 * published by the Free Software Foundation, either version 3 of the
8 * License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU Affero General Public License for more details.
14 *
15 * You should have received a copy of the GNU Affero General Public License
16 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
17 */
18
19use darkfi_sdk::error::ContractError;
20
21#[derive(Debug, Clone, thiserror::Error)]
22// TODO: Make generic contract common errors like
23// ParentCallFunctionMismatch
24pub enum MoneyError {
25    #[error("Missing inputs in transfer call")]
26    TransferMissingInputs,
27
28    #[error("Missing outputs in transfer call")]
29    TransferMissingOutputs,
30
31    #[error("Clear input used non-native token")]
32    TransferClearInputNonNativeToken,
33
34    #[error("Clear input used unauthorised pubkey")]
35    TransferClearInputUnauthorised,
36
37    #[error("Merkle root not found in previous state")]
38    TransferMerkleRootNotFound,
39
40    #[error("Duplicate nullifier found")]
41    DuplicateNullifier,
42
43    #[error("Duplicate coin found")]
44    DuplicateCoin,
45
46    #[error("Value commitment mismatch")]
47    ValueMismatch,
48
49    #[error("Token commitment mismatch")]
50    TokenMismatch,
51
52    #[error("Invalid number of inputs")]
53    InvalidNumberOfInputs,
54
55    #[error("Invalid number of outputs")]
56    InvalidNumberOfOutputs,
57
58    #[error("Spend hook is not zero")]
59    SpendHookNonZero,
60
61    #[error("Merkle root not found in previous state")]
62    SwapMerkleRootNotFound,
63
64    #[error("Token ID does not derive from mint authority")]
65    TokenIdDoesNotDeriveFromMint,
66
67    #[error("Token mint is frozen")]
68    TokenMintFrozen,
69
70    #[error("Parent call function mismatch")]
71    ParentCallFunctionMismatch,
72
73    #[error("Parent call input mismatch")]
74    ParentCallInputMismatch,
75
76    #[error("Child call function mismatch")]
77    ChildCallFunctionMismatch,
78
79    #[error("Child call input mismatch")]
80    ChildCallInputMismatch,
81
82    #[error("Call is not executed on genesis block")]
83    GenesisCallNonGenesisBlock,
84
85    #[error("Missing nullifier in set")]
86    MissingNullifier,
87
88    #[error("Call is executed on genesis block height")]
89    PoWRewardCallOnGenesisBlock,
90
91    #[error("Could not retrieve last block height from db")]
92    PoWRewardRetrieveLastBlockHeightError,
93
94    #[error("Call is not executed on next block height")]
95    PoWRewardCallNotOnNextBlockHeight,
96
97    #[error("No inputs in fee call")]
98    FeeMissingInputs,
99
100    #[error("Insufficient fee paid")]
101    InsufficientFee,
102
103    // TODO: This should catch-all (TransferMerkle../SwapMerkle...)
104    #[error("Coin merkle root not found")]
105    CoinMerkleRootNotFound,
106
107    #[error("Roots value data length missmatch")]
108    RootsValueDataMismatch,
109
110    #[error("Children indexes length missmatch")]
111    ChildrenIndexesLengthMismatch,
112}
113
114impl From<MoneyError> for ContractError {
115    fn from(e: MoneyError) -> Self {
116        match e {
117            MoneyError::TransferMissingInputs => Self::Custom(1),
118            MoneyError::TransferMissingOutputs => Self::Custom(2),
119            MoneyError::TransferClearInputNonNativeToken => Self::Custom(3),
120            MoneyError::TransferClearInputUnauthorised => Self::Custom(4),
121            MoneyError::TransferMerkleRootNotFound => Self::Custom(5),
122            MoneyError::DuplicateNullifier => Self::Custom(6),
123            MoneyError::DuplicateCoin => Self::Custom(7),
124            MoneyError::ValueMismatch => Self::Custom(8),
125            MoneyError::TokenMismatch => Self::Custom(9),
126            MoneyError::InvalidNumberOfInputs => Self::Custom(10),
127            MoneyError::InvalidNumberOfOutputs => Self::Custom(11),
128            MoneyError::SpendHookNonZero => Self::Custom(12),
129            MoneyError::SwapMerkleRootNotFound => Self::Custom(13),
130            MoneyError::TokenIdDoesNotDeriveFromMint => Self::Custom(14),
131            MoneyError::TokenMintFrozen => Self::Custom(15),
132            MoneyError::ParentCallFunctionMismatch => Self::Custom(16),
133            MoneyError::ParentCallInputMismatch => Self::Custom(17),
134            MoneyError::ChildCallFunctionMismatch => Self::Custom(18),
135            MoneyError::ChildCallInputMismatch => Self::Custom(19),
136            MoneyError::GenesisCallNonGenesisBlock => Self::Custom(20),
137            MoneyError::MissingNullifier => Self::Custom(21),
138            MoneyError::PoWRewardCallOnGenesisBlock => Self::Custom(22),
139            MoneyError::PoWRewardRetrieveLastBlockHeightError => Self::Custom(23),
140            MoneyError::PoWRewardCallNotOnNextBlockHeight => Self::Custom(24),
141            MoneyError::FeeMissingInputs => Self::Custom(25),
142            MoneyError::InsufficientFee => Self::Custom(26),
143            MoneyError::CoinMerkleRootNotFound => Self::Custom(27),
144            MoneyError::RootsValueDataMismatch => Self::Custom(28),
145            MoneyError::ChildrenIndexesLengthMismatch => Self::Custom(29),
146        }
147    }
148}