tempo_precompiles/tip20_rewards_registry/
dispatch.rs1use 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}