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 */
1819use darkfi_sdk::error::ContractError;
2021#[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")]
26TransferMissingInputs,
2728#[error("Missing outputs in transfer call")]
29TransferMissingOutputs,
3031#[error("Clear input used non-native token")]
32TransferClearInputNonNativeToken,
3334#[error("Clear input used unauthorised pubkey")]
35TransferClearInputUnauthorised,
3637#[error("Merkle root not found in previous state")]
38TransferMerkleRootNotFound,
3940#[error("Duplicate nullifier found")]
41DuplicateNullifier,
4243#[error("Duplicate coin found")]
44DuplicateCoin,
4546#[error("Value commitment mismatch")]
47ValueMismatch,
4849#[error("Token commitment mismatch")]
50TokenMismatch,
5152#[error("Invalid number of inputs")]
53InvalidNumberOfInputs,
5455#[error("Invalid number of outputs")]
56InvalidNumberOfOutputs,
5758#[error("Spend hook is not zero")]
59SpendHookNonZero,
6061#[error("Merkle root not found in previous state")]
62SwapMerkleRootNotFound,
6364#[error("Token ID does not derive from mint authority")]
65TokenIdDoesNotDeriveFromMint,
6667#[error("Token mint is frozen")]
68TokenMintFrozen,
6970#[error("Parent call function mismatch")]
71ParentCallFunctionMismatch,
7273#[error("Parent call input mismatch")]
74ParentCallInputMismatch,
7576#[error("Child call function mismatch")]
77ChildCallFunctionMismatch,
7879#[error("Child call input mismatch")]
80ChildCallInputMismatch,
8182#[error("Call is not executed on genesis block")]
83GenesisCallNonGenesisBlock,
8485#[error("Missing nullifier in set")]
86MissingNullifier,
8788#[error("Call is executed on genesis block height")]
89PoWRewardCallOnGenesisBlock,
9091#[error("Could not retrieve last block height from db")]
92PoWRewardRetrieveLastBlockHeightError,
9394#[error("Call is not executed on next block height")]
95PoWRewardCallNotOnNextBlockHeight,
9697#[error("No inputs in fee call")]
98FeeMissingInputs,
99100#[error("Insufficient fee paid")]
101InsufficientFee,
102103// TODO: This should catch-all (TransferMerkle../SwapMerkle...)
104#[error("Coin merkle root not found")]
105CoinMerkleRootNotFound,
106107#[error("Roots value data length missmatch")]
108RootsValueDataMismatch,
109110#[error("Children indexes length missmatch")]
111ChildrenIndexesLengthMismatch,
112}
113114impl From<MoneyError> for ContractError {
115fn from(e: MoneyError) -> Self {
116match 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}