Skip to content

Commit fedfdbf

Browse files
committed
eth: generate erc20 params from a simple txt file
Also optimize firmware binary space by grouping params by decimals, so the `decimal` field is not repeated for every token, removing ~1 byte per token. Currently it reduces the firmware size by 1968 bytes.
1 parent 81daa8e commit fedfdbf

File tree

5 files changed

+2491
-13909
lines changed

5 files changed

+2491
-13909
lines changed

src/rust/Cargo.lock

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/rust/erc20_params/Cargo.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,9 @@ version = "0.1.0"
1818
authors = ["Shift Crypto AG <[email protected]>"]
1919
edition = "2021"
2020
license = "Apache-2.0"
21+
22+
[dev-dependencies]
23+
hex = { workspace = true }
24+
25+
[build-dependencies]
26+
hex = { workspace = true }

src/rust/erc20_params/build.rs

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
// Copyright 2024 Shift Crypto AG
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#![allow(clippy::format_collect)]
16+
17+
use std::collections::HashMap;
18+
use std::fs::{File, OpenOptions};
19+
use std::io::{self, BufRead, Write};
20+
use std::path::Path;
21+
22+
struct Token {
23+
unit: String,
24+
contract_address: [u8; 20],
25+
decimals: u8,
26+
}
27+
28+
fn main() {
29+
let file = File::open("src/tokens.txt").unwrap();
30+
let reader = io::BufReader::new(file);
31+
let mut tokens = Vec::<Token>::new();
32+
33+
for line in reader.lines() {
34+
let line = line.unwrap();
35+
if line.starts_with('#') {
36+
continue;
37+
}
38+
let parts: Vec<&str> = line.split(';').collect();
39+
if parts.len() != 3 {
40+
panic!("token line has more than three fields");
41+
}
42+
let (unit, contract_address) = (parts[0], parts[1]);
43+
let decimals: u8 = parts[2].parse().unwrap();
44+
45+
tokens.push(Token {
46+
unit: unit.into(),
47+
contract_address: hex::decode(contract_address.strip_prefix("0x").unwrap())
48+
.unwrap()
49+
.try_into()
50+
.unwrap(),
51+
decimals,
52+
});
53+
}
54+
55+
// Group tokens by decimals
56+
let mut grouped_tokens: HashMap<u8, Vec<&Token>> = HashMap::new();
57+
for token in &tokens {
58+
grouped_tokens
59+
.entry(token.decimals)
60+
.or_default()
61+
.push(token);
62+
}
63+
64+
let out_filename = Path::new(&std::env::var("OUT_DIR").unwrap()).join("tokens.rs");
65+
let mut output_file = OpenOptions::new()
66+
.create(true)
67+
.write(true)
68+
.truncate(true)
69+
.open(out_filename)
70+
.unwrap();
71+
72+
for (decimals, tokens) in &grouped_tokens {
73+
writeln!(output_file, "const PARAMS_{}: &[P] = &[", decimals).unwrap();
74+
for token in tokens {
75+
writeln!(
76+
output_file,
77+
" P {{ unit: b\"{}\\0\".as_ptr(), contract_address: *b\"{}\" }},",
78+
token.unit,
79+
token
80+
.contract_address
81+
.iter()
82+
.map(|byte| format!("\\x{:02x}", byte))
83+
.collect::<String>(),
84+
)
85+
.unwrap();
86+
}
87+
writeln!(output_file, "];").unwrap();
88+
}
89+
90+
let mut decimals_vec: Vec<u8> = grouped_tokens.keys().cloned().collect();
91+
decimals_vec.sort();
92+
writeln!(
93+
output_file,
94+
"const ALL: &[(u8, &[P])] = &[{}];",
95+
decimals_vec
96+
.iter()
97+
.map(|decimal| format!("({}, PARAMS_{})", decimal, decimal))
98+
.collect::<Vec<String>>()
99+
.join(", ")
100+
)
101+
.unwrap();
102+
}

0 commit comments

Comments
 (0)