erc20/
erc20.rs

1//! A sample stub for an ERC20 token. Doesn't actually do anything yet. But compiles, runs, and
2//! shows output. It's the bare-minimum required for an ERC20 contract.
3use anyhow::{anyhow, Result};
4use ethnum::U256;
5use versatus_rust::eip20::{process_erc20, Erc20, Erc20ApprovalEvent, Erc20TransferEvent};
6use versatus_rust::versatus_rust::{Address, SmartContract, SmartContractInputs};
7
8#[derive(Clone, Debug)]
9struct ComputeUnitToken {
10    inputs: Option<SmartContractInputs>,
11}
12
13const COMPUTE_NAME: &str = "Compute Unit";
14const COMPUTE_SYMBOL: &str = "COUN";
15const COMPUTE_DECIMALS: u8 = 6;
16
17impl SmartContract for ComputeUnitToken {
18    fn receive_inputs(&mut self, inputs: &mut SmartContractInputs) -> Result<()> {
19        self.inputs = Some(inputs.to_owned());
20        Ok(())
21    }
22}
23
24impl Erc20 for ComputeUnitToken {
25    fn name(&self) -> Result<String> {
26        Ok(COMPUTE_NAME.to_string())
27    }
28
29    fn symbol(&self) -> Result<String> {
30        Ok(COMPUTE_SYMBOL.to_string())
31    }
32
33    fn decimals(&self) -> Result<u8> {
34        Ok(COMPUTE_DECIMALS)
35    }
36
37    fn total_supply(&self) -> Result<U256> {
38        Ok(U256::MAX)
39    }
40
41    fn balance_of(&self, _owner: Address) -> Result<U256> {
42        Ok(U256::MAX)
43    }
44
45    fn transfer(&self, to: Address, value: U256) -> Result<Erc20TransferEvent> {
46        let addr: Address;
47        if let Some(input) = &self.inputs {
48            addr = input.account_addr();
49        } else {
50            // Shouldn't be reachable.
51            return Err(anyhow!("Input data missing"));
52        }
53        Ok(Erc20TransferEvent {
54            from: addr,
55            to,
56            value,
57        })
58    }
59
60    fn transfer_from(&self, from: Address, to: Address, value: U256) -> Result<Erc20TransferEvent> {
61        Ok(Erc20TransferEvent { from, to, value })
62    }
63
64    fn approve(&self, spender: Address, value: U256) -> Result<Erc20ApprovalEvent> {
65        let owner: Address;
66        if let Some(input) = &self.inputs {
67            owner = input.account_addr();
68        } else {
69            // Shouldn't be reachable.
70            return Err(anyhow!("Input data missing"));
71        }
72        Ok(Erc20ApprovalEvent {
73            owner,
74            spender,
75            value,
76        })
77    }
78
79    fn allowance(&self, _owner: Address, _spender: Address) -> Result<U256> {
80        Ok(U256::MIN)
81    }
82}
83
84fn main() {
85    let mut token = ComputeUnitToken { inputs: None };
86    process_erc20(&mut token).unwrap();
87}