forked from argotorg/fe
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfactory.fe
More file actions
124 lines (101 loc) · 3.52 KB
/
Copy pathfactory.fe
File metadata and controls
124 lines (101 loc) · 3.52 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
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
117
118
119
120
121
122
123
124
/// Contract factory: deploys child contracts and tracks them.
/// Inspired by Uniswap V2 Factory / CREATE2 patterns.
///
/// Tests: Create effect in contracts, single-arg constructors, contract-to-
/// contract deployment, StorageMap for registry, cross-contract reads.
// ---- Child contract ----
msg ChildMsg {
#[selector = 0x01]
GetId -> u256,
#[selector = 0x02]
GetCreator -> u256,
#[selector = 0x03]
Increment -> u256,
#[selector = 0x04]
GetCount -> u256,
}
struct ChildStore {
id: u256,
creator_inner: u256,
count: u256,
}
pub contract Child {
mut store: ChildStore
init(id: u256, creator_inner: u256) uses (mut store) {
store.id = id
store.creator_inner = creator_inner
store.count = 0
}
recv ChildMsg {
GetId -> u256 uses (store) { store.id }
GetCreator -> u256 uses (store) { store.creator_inner }
Increment -> u256 uses (mut store) {
store.count += 1
store.count
}
GetCount -> u256 uses (store) { store.count }
}
}
// ---- Factory contract ----
msg FactoryMsg {
#[selector = 0x10]
CreateChild -> u256,
#[selector = 0x11]
GetChildCount -> u256,
}
struct FactoryStore {
child_count: u256,
creator_inner: u256,
}
pub contract Factory uses (create: mut Create) {
mut store: FactoryStore
init(child_count: u256, creator_inner: u256) uses (mut store) {
store.child_count = child_count
store.creator_inner = creator_inner
}
recv FactoryMsg {
CreateChild -> u256 uses (mut store, mut create) {
store.child_count += 1
let child = create.create2<Child>(
value: 0,
args: (store.child_count, store.creator_inner),
salt: store.child_count,
)
child.inner
}
GetChildCount -> u256 uses (store) {
store.child_count
}
}
}
#[test]
fn test_factory() uses (evm: mut Evm) {
let factory = evm.create2<Factory>(value: 0, args: (0, 0), salt: 0)
assert!(factory.inner != 0)
// Create child 1
let child1_inner: u256 = evm.call(addr: factory, gas: 500000, value: 0, message: FactoryMsg::CreateChild {})
assert!(child1_inner != 0)
let child1 = Address { inner: child1_inner }
// Create child 2
let child2_inner: u256 = evm.call(addr: factory, gas: 500000, value: 0, message: FactoryMsg::CreateChild {})
assert!(child2_inner != 0)
let child2 = Address { inner: child2_inner }
// Children are different contracts
assert!(child1.inner != child2.inner)
// Factory tracks count
let count: u256 = evm.call(addr: factory, gas: 100000, value: 0, message: FactoryMsg::GetChildCount {})
assert!(count == 2)
// Each child has the correct ID
let id1: u256 = evm.call(addr: child1, gas: 100000, value: 0, message: ChildMsg::GetId {})
assert!(id1 == 1)
let id2: u256 = evm.call(addr: child2, gas: 100000, value: 0, message: ChildMsg::GetId {})
assert!(id2 == 2)
// Children are independent
evm.call(addr: child1, gas: 100000, value: 0, message: ChildMsg::Increment {})
evm.call(addr: child1, gas: 100000, value: 0, message: ChildMsg::Increment {})
evm.call(addr: child2, gas: 100000, value: 0, message: ChildMsg::Increment {})
let c1: u256 = evm.call(addr: child1, gas: 100000, value: 0, message: ChildMsg::GetCount {})
assert!(c1 == 2)
let c2: u256 = evm.call(addr: child2, gas: 100000, value: 0, message: ChildMsg::GetCount {})
assert!(c2 == 1)
}