tempo_precompiles/tip20_factory/
dispatch.rs1use crate::{Precompile, fill_precompile_output, input_cost, mutate, unknown_selector, view};
2use alloy::{primitives::Address, sol_types::SolCall};
3use revm::precompile::{PrecompileError, PrecompileResult};
4
5use crate::tip20_factory::{ITIP20Factory, TIP20Factory};
6
7impl Precompile for TIP20Factory {
8 fn call(&mut self, calldata: &[u8], msg_sender: Address) -> PrecompileResult {
9 self.storage
10 .deduct_gas(input_cost(calldata.len()))
11 .map_err(|_| PrecompileError::OutOfGas)?;
12
13 let selector: [u8; 4] = calldata
14 .get(..4)
15 .ok_or_else(|| {
16 PrecompileError::Other("Invalid input: missing function selector".into())
17 })?
18 .try_into()
19 .map_err(|_| PrecompileError::Other("Invalid function selector length".into()))?;
20
21 let result = match selector {
22 ITIP20Factory::tokenIdCounterCall::SELECTOR => {
23 view::<ITIP20Factory::tokenIdCounterCall>(calldata, |_call| self.token_id_counter())
24 }
25 ITIP20Factory::createTokenCall::SELECTOR => {
26 mutate::<ITIP20Factory::createTokenCall>(calldata, msg_sender, |s, call| {
27 self.create_token(s, call)
28 })
29 }
30 ITIP20Factory::isTIP20Call::SELECTOR => {
31 view::<ITIP20Factory::isTIP20Call>(calldata, |call| self.is_tip20(call.token))
32 }
33 _ => unknown_selector(selector, self.storage.gas_used(), self.storage.spec()),
34 };
35
36 result.map(|res| fill_precompile_output(res, &mut self.storage))
37 }
38}
39
40#[cfg(test)]
41mod tests {
42 use super::*;
43 use crate::{
44 storage::{StorageCtx, hashmap::HashMapStorageProvider},
45 test_util::{assert_full_coverage, check_selector_coverage},
46 };
47 use tempo_contracts::precompiles::ITIP20Factory::ITIP20FactoryCalls;
48
49 #[test]
50 fn tip20_factory_test_selector_coverage() {
51 let mut storage = HashMapStorageProvider::new(1);
52
53 StorageCtx::enter(&mut storage, || {
54 let mut factory = TIP20Factory::new();
55
56 let unsupported = check_selector_coverage(
57 &mut factory,
58 ITIP20FactoryCalls::SELECTORS,
59 "ITIP20Factory",
60 ITIP20FactoryCalls::name_by_selector,
61 );
62
63 assert_full_coverage([unsupported]);
64 })
65 }
66}