debridge_solana_sdk/
flags.rs

1/*
2 * Copyright (C) 2023 debridge
3 *
4 * This file is part of debridge-solana-sdk.
5 *
6 * debridge-solana-sdk is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * debridge-solana-sdk is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with debridge-solana-sdk. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20use crate::sending::SendSubmissionParamsInput;
21pub const UNWRAP_ETH: u8 = 0;
22pub const REVERT_IF_EXTERNAL_FAIL: u8 = 1;
23pub const PROXY_WITH_SENDER: u8 = 2;
24pub const SEND_HASHED_DATA: u8 = 3;
25pub const DIRECT_WALLET_FLOW: u8 = 31;
26
27pub trait SetReservedFlag {
28    fn set_unwrap_eth(&mut self) {
29        self.set_flag::<UNWRAP_ETH>()
30    }
31    fn set_revert_if_external_call(&mut self) {
32        self.set_flag::<REVERT_IF_EXTERNAL_FAIL>()
33    }
34    fn set_proxy_with_sender(&mut self) {
35        self.set_flag::<PROXY_WITH_SENDER>()
36    }
37    fn set_send_hashed_data(&mut self) {
38        self.set_flag::<SEND_HASHED_DATA>()
39    }
40    fn set_direct_flow(&mut self) {
41        self.set_flag::<DIRECT_WALLET_FLOW>()
42    }
43
44    fn set_flag<const FLAG: u8>(&mut self);
45}
46
47impl SetReservedFlag for [u8; 32] {
48    fn set_flag<const FLAG: u8>(&mut self) {
49        self[31 - FLAG as usize / 8] |= 1 << (FLAG % 8);
50    }
51}
52
53pub trait CheckReservedFlag {
54    fn check_bit(self, bit: u8) -> bool;
55    fn check_unwrap_eth(self) -> bool;
56    fn check_revert_if_external_call(self) -> bool;
57    fn check_proxy_with_sender(self) -> bool;
58    fn check_send_hashed_data(self) -> bool;
59    fn check_direct_flow(self) -> bool;
60}
61impl CheckReservedFlag for &[u8; 32] {
62    fn check_bit(self, bit: u8) -> bool {
63        self[31 - bit as usize / 8] & (1 << (bit % 8)) == (1 << (bit % 8))
64    }
65    fn check_unwrap_eth(self) -> bool {
66        self.check_bit(UNWRAP_ETH)
67    }
68    fn check_revert_if_external_call(self) -> bool {
69        self.check_bit(REVERT_IF_EXTERNAL_FAIL)
70    }
71    fn check_proxy_with_sender(self) -> bool {
72        self.check_bit(PROXY_WITH_SENDER)
73    }
74    fn check_send_hashed_data(self) -> bool {
75        self.check_bit(SEND_HASHED_DATA)
76    }
77    fn check_direct_flow(self) -> bool {
78        self.check_bit(DIRECT_WALLET_FLOW)
79    }
80}
81impl CheckReservedFlag for &SendSubmissionParamsInput {
82    fn check_bit(self, bit: u8) -> bool {
83        self.flags.check_bit(bit)
84    }
85    fn check_unwrap_eth(self) -> bool {
86        self.flags.check_unwrap_eth()
87    }
88    fn check_revert_if_external_call(self) -> bool {
89        self.flags.check_revert_if_external_call()
90    }
91    fn check_proxy_with_sender(self) -> bool {
92        self.flags.check_proxy_with_sender()
93    }
94    fn check_send_hashed_data(self) -> bool {
95        self.flags.check_send_hashed_data()
96    }
97    fn check_direct_flow(self) -> bool {
98        self.flags.check_direct_flow()
99    }
100}
101
102#[cfg(test)]
103mod flag_test {
104    use crate::flags::{CheckReservedFlag, SetReservedFlag};
105
106    #[test]
107    fn bit_test() {
108        let expect = [
109            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
110            0, 0, 0,
111        ];
112
113        let mut actual = [0; 32];
114        actual.set_flag::<128>();
115
116        assert!(actual.check_bit(128));
117        assert_eq!(expect, actual);
118    }
119
120    #[test]
121    fn unwrap_eth_test() {
122        let expect = [
123            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
124            0, 0, 1,
125        ];
126
127        let mut actual = [0; 32];
128        actual.set_unwrap_eth();
129
130        assert_eq!(expect, actual);
131        assert!(actual.check_unwrap_eth());
132    }
133
134    #[test]
135    fn unwrap_revert_if_external_call_test() {
136        let expect = [
137            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
138            0, 0, 2,
139        ];
140
141        let mut actual = [0; 32];
142        actual.set_revert_if_external_call();
143
144        assert_eq!(expect, actual);
145        assert!(actual.check_revert_if_external_call());
146    }
147
148    #[test]
149    fn unwrap_proxy_with_sender_test() {
150        let expect = [
151            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
152            0, 0, 4,
153        ];
154
155        let mut actual = [0; 32];
156        actual.set_proxy_with_sender();
157
158        assert_eq!(expect, actual);
159        assert!(actual.check_proxy_with_sender());
160    }
161
162    #[test]
163    fn unwrap_send_hashed_data_test() {
164        let expect = [
165            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
166            0, 0, 8,
167        ];
168
169        let mut actual = [0; 32];
170        actual.set_send_hashed_data();
171
172        assert_eq!(expect, actual);
173        assert!(actual.check_send_hashed_data());
174    }
175
176    #[test]
177    fn direct_flow_test() {
178        let expect = [
179            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
180            128, 0, 0, 0,
181        ];
182
183        let mut actual = [0; 32];
184        actual.set_direct_flow();
185
186        assert_eq!(expect, actual);
187        assert!(actual.check_direct_flow());
188    }
189}