-
Notifications
You must be signed in to change notification settings - Fork 33
/
Copy pathforwardingWallet.iele
94 lines (77 loc) · 2.92 KB
/
forwardingWallet.iele
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
// Copyright (c) 2017 Runtime Verification, Inc. All Rights Reserved.
//
// This examples showcases the dynamic contract creation feature of IELE. The
// Wallet contract can dynamically create accounts with the Forwarder contract
// deployed, since the code for the Forwarder contract is statically available.
// This contract implements a forwarder that forwards any funds sent to
// the account it is deployed with to the account that created it.
contract Forwarder {
// initializes a forwarded by storing in the account storage the account
// number of the creator, this is the account to which received funds should
// be forwarded
define @init() {
%parent = call @iele.caller()
sstore %parent, 0
}
// deposit forwards the received funds to the creator of this account
define public @deposit() {
// get the received funds
%value = call @iele.callvalue()
// get the creator account, where we should forward funds, from the storage
%sender = sload 0
// forward funds by calling deposit at the creator account
%gas = call @iele.gas()
%status = call @deposit at %sender () send %value , gaslimit %gas
br %status, throw
ret void
throw:
call @iele.invalid()
}
}
// This contract implements a wallet that can serve deposit and withdrawal
// requests as well as setup new accounts that forward funds sent to them to
// this wallet. Only the owner can withdraw and/or setup new forwarders.
contract Wallet {
external contract Forwarder
// initializes a wallet account by storing the provided account address as
// the wallet's owner
define @init(%owner) {
sstore %owner, 0
}
// deposits the sent value to the wallet account's balance
define public @deposit() {}
// withdraws amount equal to %value from the wallet and sends it to the
// account address %to
define public @withdraw(%to, %value) {
// get the wallet's owner from storage
%owner = sload 0
// ensure that the caller (the withdrawer) is the wallet's owner
%caller = call @iele.caller()
%isnotowner = cmp ne %caller, %owner
br %isnotowner, throw
// withdraw the desired amount and send it to the desired account
%gas = call @iele.gas()
%status = call @deposit at %to () send %value , gaslimit %gas
br %status, throw
ret void
throw:
call @iele.invalid()
}
// creates a new account that simply forwards any funds sent to it to this
// wallet and returns the address of the created forwarder account
define public @newForwarder() {
// get the wallet's owner from storage
%owner = sload 0
// ensure that the caller is the wallet's owner
%caller = call @iele.caller()
%isnotowner = cmp ne %caller, %owner
br %isnotowner, throw
// create a new account, deploy the Forwarder contract with it and
// return its address
%status, %addr = create Forwarder () send 0
br %status, throw
ret %addr
throw:
call @iele.invalid()
}
}