-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlib.fe
More file actions
86 lines (75 loc) · 2.58 KB
/
Copy pathlib.fe
File metadata and controls
86 lines (75 loc) · 2.58 KB
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
/// Constant-product AMM (x * y = k).
///
/// Typed reserves prevent accidentally passing reserve_a where reserve_b
/// is expected. Effects declare exactly what each handler can access.
msg AmmMsg {
#[selector = sol("addLiquidity(uint256,uint256)")]
AddLiquidity { amount_a: u256, amount_b: u256 },
#[selector = sol("swapAForB(uint256)")]
SwapAForB { amount_in: u256 } -> u256,
#[selector = sol("swapBForA(uint256)")]
SwapBForA { amount_in: u256 } -> u256,
#[selector = sol("getReserveA()")]
GetReserveA -> u256,
#[selector = sol("getReserveB()")]
GetReserveB -> u256,
#[selector = sol("getK()")]
GetK -> u256,
}
#[event]
struct LiquidityAdded {
amount_a: u256,
amount_b: u256,
}
#[event]
struct Swap {
#[indexed]
direction: u8,
amount_in: u256,
amount_out: u256,
}
struct AmmStore {
reserve_a: u256,
reserve_b: u256,
}
/// Constant-product swap: dy = reserve_out * dx / (reserve_in + dx)
const fn swap_amount(reserve_in: u256, reserve_out: u256, amount_in: u256) -> u256 {
if amount_in == 0 || reserve_in == 0 || reserve_out == 0 {
0
} else {
reserve_out * amount_in / (reserve_in + amount_in)
}
}
pub contract SimpleAmm uses (ctx: Ctx, log: mut Log) {
mut store: AmmStore
init() uses (mut store) {
store.reserve_a = 0
store.reserve_b = 0
}
recv AmmMsg {
AddLiquidity { amount_a, amount_b } uses (mut store, mut log) {
store.reserve_a += amount_a
store.reserve_b += amount_b
log.emit(LiquidityAdded { amount_a, amount_b })
}
SwapAForB { amount_in } -> u256 uses (mut store, mut log) {
let amount_out = swap_amount(reserve_in: store.reserve_a, reserve_out: store.reserve_b, amount_in)
if amount_out == 0 { return 0 }
store.reserve_a += amount_in
store.reserve_b -= amount_out
log.emit(Swap { direction: 0, amount_in, amount_out })
amount_out
}
SwapBForA { amount_in } -> u256 uses (mut store, mut log) {
let amount_out = swap_amount(reserve_in: store.reserve_b, reserve_out: store.reserve_a, amount_in)
if amount_out == 0 { return 0 }
store.reserve_b += amount_in
store.reserve_a -= amount_out
log.emit(Swap { direction: 1, amount_in, amount_out })
amount_out
}
GetReserveA -> u256 uses (store) { store.reserve_a }
GetReserveB -> u256 uses (store) { store.reserve_b }
GetK -> u256 uses (store) { store.reserve_a * store.reserve_b }
}
}