revive_solc_json_interface/standard_json/output/error/
mod.rs

1//! The `solc --standard-json` output error.
2
3pub mod source_location;
4
5use std::str::FromStr;
6
7use serde::Deserialize;
8use serde::Serialize;
9
10use self::source_location::SourceLocation;
11
12/// The `solc --standard-json` output error.
13#[derive(Debug, Serialize, Deserialize, Clone)]
14#[serde(rename_all = "camelCase")]
15pub struct Error {
16    /// The component type.
17    pub component: String,
18    /// The error code.
19    pub error_code: Option<String>,
20    /// The formatted error message.
21    pub formatted_message: String,
22    /// The non-formatted error message.
23    pub message: String,
24    /// The error severity.
25    pub severity: String,
26    /// The error location data.
27    pub source_location: Option<SourceLocation>,
28    /// The error type.
29    pub r#type: String,
30}
31
32impl Error {
33    /// Returns the `ecrecover` function usage warning.
34    pub fn message_ecrecover(src: Option<&str>) -> Self {
35        let message = r#"
36Warning: It looks like you are using 'ecrecover' to validate a signature of a user account.
37Polkadot comes with native account abstraction support, therefore it is highly recommended NOT
38to rely on the fact that the account has an ECDSA private key attached to it since accounts might
39implement other signature schemes.
40"#
41        .to_owned();
42
43        Self {
44            component: "general".to_owned(),
45            error_code: None,
46            formatted_message: message.clone(),
47            message,
48            severity: "warning".to_owned(),
49            source_location: src.map(SourceLocation::from_str).and_then(Result::ok),
50            r#type: "Warning".to_owned(),
51        }
52    }
53
54    /// Returns the `<address payable>`'s `send` and `transfer` methods usage error.
55    pub fn message_send_and_transfer(src: Option<&str>) -> Self {
56        let message = r#"
57Warning: It looks like you are using '<address payable>.send/transfer(<X>)'.
58Using '<address payable>.send/transfer(<X>)' is deprecated and strongly discouraged!
59The resolc compiler uses a heuristic to detect '<address payable>.send/transfer(<X>)' calls,
60which disables call re-entrancy and supplies all remaining gas instead of the 2300 gas stipend.
61However, detection is not guaranteed. You are advised to carefully test this, employ
62re-entrancy guards or use the withdrawal pattern instead!
63Learn more on https://docs.soliditylang.org/en/latest/security-considerations.html#reentrancy
64and https://docs.soliditylang.org/en/latest/common-patterns.html#withdrawal-from-contracts
65"#
66        .to_owned();
67
68        Self {
69            component: "general".to_owned(),
70            error_code: None,
71            formatted_message: message.clone(),
72            message,
73            severity: "warning".to_owned(),
74            source_location: src.map(SourceLocation::from_str).and_then(Result::ok),
75            r#type: "Warning".to_owned(),
76        }
77    }
78
79    /// Returns the `extcodesize` instruction usage warning.
80    pub fn message_extcodesize(src: Option<&str>) -> Self {
81        let message = r#"
82Warning: Your code or one of its dependencies uses the 'extcodesize' instruction, which is
83usually needed in the following cases:
84  1. To detect whether an address belongs to a smart contract.
85  2. To detect whether the deploy code execution has finished.
86Polkadot comes with native account abstraction support (so smart contracts are just accounts
87coverned by code), and you should avoid differentiating between contracts and non-contract
88addresses.
89"#
90        .to_owned();
91
92        Self {
93            component: "general".to_owned(),
94            error_code: None,
95            formatted_message: message.clone(),
96            message,
97            severity: "warning".to_owned(),
98            source_location: src.map(SourceLocation::from_str).and_then(Result::ok),
99            r#type: "Warning".to_owned(),
100        }
101    }
102
103    /// Returns the `origin` instruction usage warning.
104    pub fn message_tx_origin(src: Option<&str>) -> Self {
105        let message = r#"
106Warning: You are checking for 'tx.origin' in your code, which might lead to unexpected behavior.
107Polkadot comes with native account abstraction support, and therefore the initiator of a
108transaction might be different from the contract calling your code. It is highly recommended NOT
109to rely on tx.origin, but use msg.sender instead.
110"#
111        .to_owned();
112
113        Self {
114            component: "general".to_owned(),
115            error_code: None,
116            formatted_message: message.clone(),
117            message,
118            severity: "warning".to_owned(),
119            source_location: src.map(SourceLocation::from_str).and_then(Result::ok),
120            r#type: "Warning".to_owned(),
121        }
122    }
123
124    /// Appends the contract path to the message..
125    pub fn push_contract_path(&mut self, path: &str) {
126        self.formatted_message
127            .push_str(format!("\n--> {path}\n").as_str());
128    }
129}
130
131impl std::fmt::Display for Error {
132    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
133        write!(f, "{}", self.formatted_message)
134    }
135}