Skip to content
This repository was archived by the owner on Aug 14, 2023. It is now read-only.

Commit 000944b

Browse files
SVM Wallet App (#91)
1 parent 9b29364 commit 000944b

38 files changed

+2350
-232
lines changed

Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,5 +77,4 @@ members = [
7777

7878
exclude = [
7979
"crates/svm-extern",
80-
"apps/transfer",
8180
]

apps/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
wasm/*.wasm
2+
wasm/*.wast

apps/precompiled/transfer.wasm

-89.5 KB
Binary file not shown.

apps/precompiled/transfer.wast

Lines changed: 0 additions & 86 deletions
This file was deleted.
Lines changed: 3 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
[package]
2-
name = "transfer"
3-
version = "0.0.0"
2+
name = "wallet"
3+
version = "0.1.0"
44
authors = ["Yaron Wittenstein <yaron.wittenstein@gmail.com>"]
55
edition = "2018"
66
publish = false
77

8+
[workspace]
9+
810
[lib]
911
path = "src/lib.rs"
10-
crate-type = ["cdylib"]
12+
# crate-type = ["cdylib"]
1113

1214
[profile.release]
1315
panic = "abort"
@@ -16,4 +18,4 @@ debug = false
1618
lto=true
1719

1820
[dependencies]
19-
svm-extern = { path = "../../crates/svm-extern" }
21+
svm-extern = { path = "../../../crates/svm-extern" }

apps/src/wallet/build.sh

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
cargo +nightly build --target wasm32-unknown-unknown --release
2+
cp target/wasm32-unknown-unknown/release/*.wasm ../../../apps/wasm
3+
pushd ../../wasm
4+
wasm2wat wallet.wasm > wallet.wast
5+
rm wallet.wasm
6+
wat2wasm wallet.wast
7+
popd

apps/src/wallet/src/auth.rs

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
include!("imports.rs");
2+
3+
use super::{read::*, write::*};
4+
5+
use crate::{hostctx, offset, sizeof};
6+
7+
#[no_mangle]
8+
pub(crate) fn is_multisig() -> bool {
9+
match read_is_multisig() {
10+
0 => false,
11+
_ => true,
12+
}
13+
}
14+
15+
#[no_mangle]
16+
pub(crate) fn pub_key_auth() {
17+
assert!(is_multisig() == false);
18+
19+
let reg_bits = sizeof!(pub_key) * 8;
20+
21+
unsafe {
22+
reg_push(reg_bits, 0);
23+
reg_push(reg_bits, 1);
24+
25+
copy_host_pub_key_to_reg(reg_bits, 0);
26+
read_pub_key(offset!(pub_key1), reg_bits, 1);
27+
28+
if pub_key_cmp(0, 1) == 0 {
29+
panic!("auth failed!")
30+
}
31+
32+
reg_pop(reg_bits, 1);
33+
reg_pop(reg_bits, 0);
34+
}
35+
}
36+
37+
#[no_mangle]
38+
pub(crate) fn multisig_start() {
39+
assert!(is_multisig());
40+
41+
multisig_any_key_auth();
42+
write_pending_pub_key();
43+
}
44+
45+
#[no_mangle]
46+
pub(crate) fn multisig_complete() {
47+
assert!(is_multisig());
48+
49+
multisig_any_key_auth();
50+
51+
let reg_bits = sizeof!(pub_key) * 8;
52+
53+
/// we need to assert that the current `pub_key` is different
54+
/// from the presisted `pending_pub_key`.
55+
/// If they keys differ - we conclude the multisig auth as a success
56+
/// and we zero the `pending_pub_key.`
57+
unsafe {
58+
reg_push(reg_bits, 0);
59+
reg_push(reg_bits, 1);
60+
61+
copy_host_pub_key_to_reg(reg_bits, 0);
62+
read_pending_pub_key(reg_bits, 1);
63+
64+
if pub_key_cmp(0, 1) == 0 {
65+
panic!("auth failed!")
66+
}
67+
68+
reset_pending_pub_key();
69+
70+
reg_pop(reg_bits, 1);
71+
reg_pop(reg_bits, 0);
72+
};
73+
}
74+
75+
/// Private
76+
77+
#[no_mangle]
78+
fn multisig_any_key_auth() {
79+
let reg_bits = sizeof!(pub_key) * 8;
80+
81+
unsafe {
82+
reg_push(reg_bits, 0);
83+
reg_push(reg_bits, 1);
84+
}
85+
86+
copy_host_pub_key_to_reg(reg_bits, 0);
87+
88+
for idx in 0..3 {
89+
read_pub_key(offset!(pub_key, idx), reg_bits, 1);
90+
91+
if pub_key_cmp(0, 1) == 0 {
92+
// we've found a match
93+
94+
// restore regs
95+
unsafe {
96+
reg_pop(reg_bits, 1);
97+
reg_pop(reg_bits, 0);
98+
};
99+
100+
return;
101+
}
102+
}
103+
104+
panic!("auth failed")
105+
}
106+
107+
#[no_mangle]
108+
fn pub_key_cmp(reg_idx1: u32, reg_idx2: u32) -> i32 {
109+
unsafe { reg_cmp(sizeof!(pub_key) * 8, reg_idx1, reg_idx2) }
110+
}
111+
112+
#[no_mangle]
113+
fn copy_host_pub_key_to_reg(reg_bits: u32, reg_idx: u32) {
114+
unsafe {
115+
host_ctx_read_into_reg(hostctx!(pub_key), reg_bits, reg_idx);
116+
}
117+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
///
2+
/// 𝘓𝘛: Layer time (in seconds).
3+
/// The time between subsequent Layers is guaranteed to stay constant.
4+
///
5+
/// 𝘓𝙞𝑞𝘛: Liquidation time (in seconds).
6+
///
7+
/// 𝘓: #Layers during the liquidation time.
8+
/// 𝘓 = 𝘓𝙞𝑞𝘛 / 𝘓𝘛
9+
///
10+
/// 𝘓𝘴: The layer the liquidation starts (given by the Host).
11+
/// 𝘓𝘤𝘶𝘳: The current layer (given by the Host).
12+
///
13+
/// 𝙇𝘱𝘳𝘦𝘷: The layer of the last liquidation computation (initialized with 𝘓𝘴).
14+
/// After each liquidation refresh, we save to the app-storage:
15+
/// 𝙇𝘱𝘳𝘦𝘷 <- 𝙇𝘤𝘶𝘳
16+
///
17+
/// 𝗖: total #coins.
18+
/// 𝘓𝙞𝑞ʟ: liquidation-per-layer
19+
/// 𝘓𝙞𝑞ʟ = 𝗖 / 𝘓
20+
///
21+
/// 𝝙L: Layers delta.
22+
/// 𝝙L = 𝙇𝘤𝘶𝘳 - 𝙇𝘱𝘳𝘦𝘷
23+
///
24+
/// 𝝙𝘓𝙞𝑞: Liquidation delta (𝝙coins that becomes liquidated).
25+
/// 𝝙𝘓𝙞𝑞 = 𝘓𝙞𝑞ʟ * 𝝙L
26+
///
27+
28+
/// Computes the total liquidation period in layers.
29+
///
30+
/// time_iternval - A time interval (in seconds).
31+
/// layer_time - The time time between subsequent layers (in seconds).
32+
pub(crate) fn layer_count(time_interval: u32, layer_time: u32) -> u32 {
33+
assert!(time_interval % layer_time == 0);
34+
35+
time_interval / layer_time
36+
}
37+
38+
/// Computes the `liquidation per layer`.
39+
///
40+
/// `amount` - The amount of unliquidated-yet coins.
41+
/// `layer_count` - The #layers during the liquidation period.
42+
///
43+
pub(crate) fn layer_liquidation(amount: u32, layer_count: u32) -> u32 {
44+
assert!(amount % layer_count == 0);
45+
46+
amount / layer_count
47+
}
48+
49+
/// Computes the new liquidated coins between layers `layer_prev` to `layer_current`
50+
///
51+
/// `layer_liq` - The liquidation per layer. (see: `layer_liquidation` above).
52+
/// `last_layer` - The last layer where the liquidation has been calculated.
53+
/// `current_layer` - The current layer.
54+
///
55+
pub(crate) fn liquidation_delta(layer_liq: u32, last_layer: u64, current_layer: u64) -> u32 {
56+
assert!(current_layer >= last_layer);
57+
58+
let delta: u64 = (layer_liq as u64) * (current_layer - last_layer);
59+
60+
assert!(delta <= 0xFF_FF_FF_FF);
61+
62+
delta as u32
63+
}

0 commit comments

Comments
 (0)