tempo_precompiles/tip20_rewards_registry/
dispatch.rs

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