1use ethers::prelude::*;
4use hex_literal::hex;
5use serde::{Deserialize, Serialize};
6use std::sync::Arc;
7
8use hopr_bindings::hopr_announcements::HoprAnnouncements;
9use hopr_bindings::hopr_channels::HoprChannels;
10use hopr_bindings::hopr_dummy_proxy_for_network_registry::HoprDummyProxyForNetworkRegistry;
11use hopr_bindings::hopr_network_registry::HoprNetworkRegistry;
12use hopr_bindings::hopr_node_management_module::HoprNodeManagementModule;
13use hopr_bindings::hopr_node_safe_registry::HoprNodeSafeRegistry;
14use hopr_bindings::hopr_node_stake_factory::HoprNodeStakeFactory;
15use hopr_bindings::hopr_safe_proxy_for_network_registry::HoprSafeProxyForNetworkRegistry;
16use hopr_bindings::hopr_ticket_price_oracle::HoprTicketPriceOracle;
17use hopr_bindings::hopr_token::HoprToken;
18use hopr_bindings::hopr_winning_probability_oracle::HoprWinningProbabilityOracle;
19
20use ethers::abi::Token;
21use hopr_crypto_types::keypairs::{ChainKeypair, Keypair};
22use hopr_primitive_types::primitives::Address;
23use std::str::FromStr;
24
25pub mod actions;
26pub mod chain_events;
27
28pub mod utils;
30
31pub use ethers::core::types::transaction::eip2718::TypedTransaction;
32
33lazy_static::lazy_static! {
34 pub static ref ERC_1820_REGISTRY_DEPLOY_CODE: [u8; 2619] = hex!("f90a388085174876e800830c35008080b909e5608060405234801561001057600080fd5b506109c5806100206000396000f3fe608060405234801561001057600080fd5b50600436106100a5576000357c010000000000000000000000000000000000000000000000000000000090048063a41e7d5111610078578063a41e7d51146101d4578063aabbb8ca1461020a578063b705676514610236578063f712f3e814610280576100a5565b806329965a1d146100aa5780633d584063146100e25780635df8122f1461012457806365ba36c114610152575b600080fd5b6100e0600480360360608110156100c057600080fd5b50600160a060020a038135811691602081013591604090910135166102b6565b005b610108600480360360208110156100f857600080fd5b5035600160a060020a0316610570565b60408051600160a060020a039092168252519081900360200190f35b6100e06004803603604081101561013a57600080fd5b50600160a060020a03813581169160200135166105bc565b6101c26004803603602081101561016857600080fd5b81019060208101813564010000000081111561018357600080fd5b82018360208201111561019557600080fd5b803590602001918460018302840111640100000000831117156101b757600080fd5b5090925090506106b3565b60408051918252519081900360200190f35b6100e0600480360360408110156101ea57600080fd5b508035600160a060020a03169060200135600160e060020a0319166106ee565b6101086004803603604081101561022057600080fd5b50600160a060020a038135169060200135610778565b61026c6004803603604081101561024c57600080fd5b508035600160a060020a03169060200135600160e060020a0319166107ef565b604080519115158252519081900360200190f35b61026c6004803603604081101561029657600080fd5b508035600160a060020a03169060200135600160e060020a0319166108aa565b6000600160a060020a038416156102cd57836102cf565b335b9050336102db82610570565b600160a060020a031614610339576040805160e560020a62461bcd02815260206004820152600f60248201527f4e6f7420746865206d616e616765720000000000000000000000000000000000604482015290519081900360640190fd5b6103428361092a565b15610397576040805160e560020a62461bcd02815260206004820152601a60248201527f4d757374206e6f7420626520616e204552433136352068617368000000000000604482015290519081900360640190fd5b600160a060020a038216158015906103b85750600160a060020a0382163314155b156104ff5760405160200180807f455243313832305f4143434550545f4d4147494300000000000000000000000081525060140190506040516020818303038152906040528051906020012082600160a060020a031663249cb3fa85846040518363ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018083815260200182600160a060020a0316600160a060020a031681526020019250505060206040518083038186803b15801561047e57600080fd5b505afa158015610492573d6000803e3d6000fd5b505050506040513d60208110156104a857600080fd5b5051146104ff576040805160e560020a62461bcd02815260206004820181905260248201527f446f6573206e6f7420696d706c656d656e742074686520696e74657266616365604482015290519081900360640190fd5b600160a060020a03818116600081815260208181526040808320888452909152808220805473ffffffffffffffffffffffffffffffffffffffff19169487169485179055518692917f93baa6efbd2244243bfee6ce4cfdd1d04fc4c0e9a786abd3a41313bd352db15391a450505050565b600160a060020a03818116600090815260016020526040812054909116151561059a5750806105b7565b50600160a060020a03808216600090815260016020526040902054165b919050565b336105c683610570565b600160a060020a031614610624576040805160e560020a62461bcd02815260206004820152600f60248201527f4e6f7420746865206d616e616765720000000000000000000000000000000000604482015290519081900360640190fd5b81600160a060020a031681600160a060020a0316146106435780610646565b60005b600160a060020a03838116600081815260016020526040808220805473ffffffffffffffffffffffffffffffffffffffff19169585169590951790945592519184169290917f605c2dbf762e5f7d60a546d42e7205dcb1b011ebc62a61736a57c9089d3a43509190a35050565b600082826040516020018083838082843780830192505050925050506040516020818303038152906040528051906020012090505b92915050565b6106f882826107ef565b610703576000610705565b815b600160a060020a03928316600081815260208181526040808320600160e060020a031996909616808452958252808320805473ffffffffffffffffffffffffffffffffffffffff19169590971694909417909555908152600284528181209281529190925220805460ff19166001179055565b600080600160a060020a038416156107905783610792565b335b905061079d8361092a565b156107c357826107ad82826108aa565b6107b85760006107ba565b815b925050506106e8565b600160a060020a0390811660009081526020818152604080832086845290915290205416905092915050565b6000808061081d857f01ffc9a70000000000000000000000000000000000000000000000000000000061094c565b909250905081158061082d575080155b1561083d576000925050506106e8565b61084f85600160e060020a031961094c565b909250905081158061086057508015155b15610870576000925050506106e8565b61087a858561094c565b909250905060018214801561088f5750806001145b1561089f576001925050506106e8565b506000949350505050565b600160a060020a0382166000908152600260209081526040808320600160e060020a03198516845290915281205460ff1615156108f2576108eb83836107ef565b90506106e8565b50600160a060020a03808316600081815260208181526040808320600160e060020a0319871684529091529020549091161492915050565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff161590565b6040517f01ffc9a7000000000000000000000000000000000000000000000000000000008082526004820183905260009182919060208160248189617530fa90519096909550935050505056fea165627a7a72305820377f4a2d4301ede9949f163f319021a6e9c687c292a5e2b2c4734c126b524e6c00291ba01820182018201820182018201820182018201820182018201820182018201820a01820182018201820182018201820182018201820182018201820182018201820");
35}
36
37pub fn create_eip1559_transaction() -> TypedTransaction {
39 TypedTransaction::Eip1559(Eip1559TransactionRequest::new())
40}
41
42#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize, Default)]
44pub struct ContractAddresses {
45 pub token: Address,
47 pub channels: Address,
49 pub announcements: Address,
51 pub network_registry: Address,
53 pub network_registry_proxy: Address,
55 pub safe_registry: Address,
57 pub price_oracle: Address,
59 pub win_prob_oracle: Address,
61 pub stake_factory: Address,
63 pub module_implementation: Address,
65}
66
67#[derive(Debug, Clone)]
68pub enum NetworkRegistryProxy<M: Middleware> {
69 Dummy(HoprDummyProxyForNetworkRegistry<M>),
70 Safe(HoprSafeProxyForNetworkRegistry<M>),
71}
72
73impl<M: Middleware> NetworkRegistryProxy<M> {
74 pub fn address(&self) -> Address {
75 match self {
76 NetworkRegistryProxy::Dummy(c) => c.address().into(),
77 NetworkRegistryProxy::Safe(c) => c.address().into(),
78 }
79 }
80}
81
82#[derive(Debug)]
84pub struct ContractInstances<M: Middleware> {
85 pub token: HoprToken<M>,
86 pub channels: HoprChannels<M>,
87 pub announcements: HoprAnnouncements<M>,
88 pub network_registry: HoprNetworkRegistry<M>,
89 pub network_registry_proxy: NetworkRegistryProxy<M>,
90 pub safe_registry: HoprNodeSafeRegistry<M>,
91 pub price_oracle: HoprTicketPriceOracle<M>,
92 pub win_prob_oracle: HoprWinningProbabilityOracle<M>,
93 pub stake_factory: HoprNodeStakeFactory<M>,
94 pub module_implementation: HoprNodeManagementModule<M>,
95}
96
97impl<M: Middleware> Clone for ContractInstances<M> {
98 fn clone(&self) -> Self {
99 let client = self.token.client();
101 Self {
102 token: HoprToken::new(self.token.address(), client.clone()),
103 channels: HoprChannels::new(self.channels.address(), client.clone()),
104 announcements: HoprAnnouncements::new(self.announcements.address(), client.clone()),
105 network_registry: HoprNetworkRegistry::new(self.network_registry.address(), client.clone()),
106 network_registry_proxy: match &self.network_registry_proxy {
107 NetworkRegistryProxy::Dummy(nr) => {
108 NetworkRegistryProxy::Dummy(HoprDummyProxyForNetworkRegistry::new(nr.address(), client.clone()))
109 }
110 NetworkRegistryProxy::Safe(nr) => {
111 NetworkRegistryProxy::Safe(HoprSafeProxyForNetworkRegistry::new(nr.address(), client.clone()))
112 }
113 },
114 safe_registry: HoprNodeSafeRegistry::new(self.safe_registry.address(), client.clone()),
115 price_oracle: HoprTicketPriceOracle::new(self.price_oracle.address(), client.clone()),
116 win_prob_oracle: HoprWinningProbabilityOracle::new(self.win_prob_oracle.address(), client.clone()),
117 stake_factory: HoprNodeStakeFactory::new(self.stake_factory.address(), client.clone()),
118 module_implementation: HoprNodeManagementModule::new(self.module_implementation.address(), client.clone()),
119 }
120 }
121}
122
123impl<M: Middleware> ContractInstances<M> {
124 pub fn new(contract_addresses: &ContractAddresses, provider: Arc<M>, use_dummy_nr: bool) -> Self {
125 Self {
126 token: HoprToken::new(contract_addresses.token, provider.clone()),
127 channels: HoprChannels::new(contract_addresses.channels, provider.clone()),
128 announcements: HoprAnnouncements::new(contract_addresses.announcements, provider.clone()),
129 network_registry: HoprNetworkRegistry::new(contract_addresses.network_registry, provider.clone()),
130 network_registry_proxy: if use_dummy_nr {
131 NetworkRegistryProxy::Dummy(HoprDummyProxyForNetworkRegistry::new(
132 contract_addresses.network_registry_proxy,
133 provider.clone(),
134 ))
135 } else {
136 NetworkRegistryProxy::Safe(HoprSafeProxyForNetworkRegistry::new(
137 contract_addresses.network_registry_proxy,
138 provider.clone(),
139 ))
140 },
141 safe_registry: HoprNodeSafeRegistry::new(contract_addresses.safe_registry, provider.clone()),
142 price_oracle: HoprTicketPriceOracle::new(contract_addresses.price_oracle, provider.clone()),
143 win_prob_oracle: HoprWinningProbabilityOracle::new(contract_addresses.win_prob_oracle, provider.clone()),
144 stake_factory: HoprNodeStakeFactory::new(contract_addresses.stake_factory, provider.clone()),
145 module_implementation: HoprNodeManagementModule::new(
146 contract_addresses.module_implementation,
147 provider.clone(),
148 ),
149 }
150 }
151
152 pub async fn deploy_for_testing(provider: Arc<M>, deployer: &ChainKeypair) -> Result<Self, ContractError<M>> {
154 {
155 let mut tx = Eip1559TransactionRequest::new();
157 tx = tx.to(H160::from_str(crate::utils::ERC_1820_DEPLOYER).expect("deployer address should be valid"));
158 tx = tx.value(crate::utils::ETH_VALUE_FOR_ERC1820_DEPLOYER);
159
160 provider
161 .send_transaction(tx, None)
162 .await
163 .map_err(|e| ContractError::MiddlewareError { e })?
164 .await?;
165
166 provider
167 .send_raw_transaction(Bytes::from_static(&*ERC_1820_REGISTRY_DEPLOY_CODE))
168 .await
169 .map_err(|e| ContractError::MiddlewareError { e })?
170 .await?;
171 }
172
173 let self_address: types::Address = deployer.public().to_address().into();
175
176 let stake_factory = HoprNodeStakeFactory::deploy(provider.clone(), ())?.send().await?;
177 let module_implementation = HoprNodeManagementModule::deploy(provider.clone(), ())?.send().await?;
178 let safe_registry = HoprNodeSafeRegistry::deploy(provider.clone(), ())?.send().await?;
179 let price_oracle = HoprTicketPriceOracle::deploy(
180 provider.clone(),
181 (self_address, ethers::types::U256::from(100000000000000000_u128)),
182 )?
183 .send()
184 .await?;
185 let win_prob_oracle = HoprWinningProbabilityOracle::deploy(
186 provider.clone(),
187 (self_address, ethers::types::U256::from(72057594037927935_u128)), )?
189 .send()
190 .await?;
191 let token = HoprToken::deploy(provider.clone(), ())?.send().await?;
192 let network_registry_proxy = HoprDummyProxyForNetworkRegistry::deploy(provider.clone(), self_address)?
193 .send()
194 .await?;
195 let channels = HoprChannels::deploy(
196 provider.clone(),
197 Token::Tuple(vec![
198 Token::Address(token.address()),
199 Token::Uint(1_u32.into()),
200 Token::Address(safe_registry.address()),
201 ]),
202 )?
203 .send()
204 .await?;
205 let announcements = HoprAnnouncements::deploy(provider.clone(), Token::Address(safe_registry.address()))?
206 .send()
207 .await?;
208 let network_registry = HoprNetworkRegistry::deploy(
209 provider.clone(),
210 (
211 ethers::types::Address::from(network_registry_proxy.address()),
212 self_address,
213 self_address,
214 ),
215 )?
216 .send()
217 .await?;
218
219 network_registry.disable_registry().send().await?.await?;
221
222 Ok(Self {
223 token,
224 channels,
225 announcements,
226 network_registry,
227 network_registry_proxy: NetworkRegistryProxy::Dummy(network_registry_proxy),
228 safe_registry,
229 price_oracle,
230 win_prob_oracle,
231 stake_factory,
232 module_implementation,
233 })
234 }
235}
236
237impl<M: Middleware> From<&ContractInstances<M>> for ContractAddresses {
238 fn from(value: &ContractInstances<M>) -> Self {
239 Self {
240 token: value.token.address().into(),
241 channels: value.channels.address().into(),
242 announcements: value.announcements.address().into(),
243 network_registry: value.network_registry.address().into(),
244 network_registry_proxy: value.network_registry_proxy.address(),
245 safe_registry: value.safe_registry.address().into(),
246 price_oracle: value.price_oracle.address().into(),
247 win_prob_oracle: value.win_prob_oracle.address().into(),
248 stake_factory: value.stake_factory.address().into(),
249 module_implementation: value.module_implementation.address().into(),
250 }
251 }
252}
253
254pub fn create_anvil(block_time: Option<std::time::Duration>) -> ethers::utils::AnvilInstance {
259 let mut anvil = ethers::utils::Anvil::new();
261
262 if let Some(bt) = block_time {
263 anvil = anvil.block_time(bt.as_secs());
264 }
265
266 anvil.spawn()
267}