1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
use crate::{Config, Error};
use codec::{Decode, Encode};
use sp_runtime::DispatchError;
use sp_std::{vec, vec::Vec};

#[derive(Encode, Decode)]
pub enum TransferEventStub<T: frame_system::Config, Balance> {
    Endowed(T::AccountId, Balance),
    DustLost(T::AccountId, Balance),
    Transfer {
        from: T::AccountId,
        to: T::AccountId,
        amount: Balance,
    },
}

type CurrencyId = u32;

#[derive(Encode, Decode)]
pub enum MultiTransferEventStub<T: frame_system::Config, Balance, CurrencyId> {
    Endowed(CurrencyId, T::AccountId, Balance),
    DustLost(CurrencyId, T::AccountId, Balance),
    Transfer {
        currency_id: CurrencyId,
        from: T::AccountId,
        to: T::AccountId,
        amount: Balance,
    },
}

pub(crate) fn decode_event<T: Config<I>, I: 'static>(
    id: &[u8; 4],
    mut encoded_event: Vec<u8>,
    value_abi_unsigned_type: &[u8],
) -> Result<(Vec<Vec<u8>>, Vec<u8>), DispatchError> {
    // the first byte is the pallet index, which we don't need
    let _ = encoded_event.remove(0);
    match &id {
        &b"tran" => {
            // Assume that the different Pallet ID Circuit vs Target wouldn't matter for decoding on Circuit.
            match value_abi_unsigned_type {
                b"uint32" => match Decode::decode(&mut &encoded_event[..]) {
                    Ok(TransferEventStub::<T, u32>::Transfer { from, to, amount }) =>
                        Ok((vec![from.encode(), to.encode(), amount.encode()], vec![])),
                    _ => Err(Error::<T, I>::EventDecodingFailed.into()),
                },
                b"uint64" => match Decode::decode(&mut &encoded_event[..]) {
                    Ok(TransferEventStub::<T, u64>::Transfer { from, to, amount }) =>
                        Ok((vec![from.encode(), to.encode(), amount.encode()], vec![])),
                    _ => Err(Error::<T, I>::EventDecodingFailed.into()),
                },
                b"uint128" => match Decode::decode(&mut &encoded_event[..]) {
                    Ok(TransferEventStub::<T, u128>::Transfer { from, to, amount }) =>
                        Ok((vec![from.encode(), to.encode(), amount.encode()], vec![])),
                    _ => Err(Error::<T, I>::EventDecodingFailed.into()),
                },
                &_ => Err(Error::<T, I>::EventDecodingFailed.into()),
            }
        },
        &b"swap" | &b"aliq" => match value_abi_unsigned_type {
            b"uint32" => match Decode::decode(&mut &encoded_event[..]) {
                Ok(MultiTransferEventStub::<T, u32, CurrencyId>::Transfer {
                    currency_id,
                    from,
                    to,
                    amount,
                }) => Ok((
                    vec![
                        from.encode(),
                        to.encode(),
                        currency_id.encode(),
                        amount.encode(),
                    ],
                    vec![],
                )),
                _ => Err(Error::<T, I>::EventDecodingFailed.into()),
            },
            b"uint64" => match Decode::decode(&mut &encoded_event[..]) {
                Ok(MultiTransferEventStub::<T, u64, CurrencyId>::Transfer {
                    currency_id,
                    from,
                    to,
                    amount,
                }) => Ok((
                    vec![
                        from.encode(),
                        to.encode(),
                        currency_id.encode(),
                        amount.encode(),
                    ],
                    vec![],
                )),
                _ => Err(Error::<T, I>::EventDecodingFailed.into()),
            },
            b"uint128" => match Decode::decode(&mut &encoded_event[..]) {
                Ok(MultiTransferEventStub::<T, u128, CurrencyId>::Transfer {
                    currency_id,
                    from,
                    to,
                    amount,
                }) => Ok((
                    vec![
                        from.encode(),
                        to.encode(),
                        currency_id.encode(),
                        amount.encode(),
                    ],
                    vec![],
                )),
                _ => Err(Error::<T, I>::EventDecodingFailed.into()),
            },
            &_ => Err(Error::<T, I>::EventDecodingFailed.into()),
        },
        &_ => Err(Error::<T, I>::UnkownSideEffect.into()),
    }
}