-
Notifications
You must be signed in to change notification settings - Fork 33
/
Copy pathforwardingWallet-copycreate.iele
71 lines (59 loc) · 2.55 KB
/
forwardingWallet-copycreate.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
// Copyright (c) 2017 Runtime Verification, Inc. All Rights Reserved.
//
// This example showcases the dynamic contract creation feature of IELE. The
// Wallet contract can dynamically create accounts and deploy a full copy of a
// contract already deployed in an existing account. The deployed code is not
// statically known but it is not dynamically generated either.
// 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. The
// contract deployed with a new forwarder account is found with (and copied
// from) a provided account. An example of such a contract can be found in the
// forwarder.iele example.
contract Wallet {
// initializes a wallet account by storing the provided account address in
// %owner as the wallet's owner and the provided account address in %forwarder
// as the account from where the forwarder contract can be copied.
define @init(%owner, %forwarder) {
sstore %owner, 0
sstore %forwarder, 1
}
// 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 // throw if call fails
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
// get the address of the account with the forwarder contract to copy
%forwarder = sload 1
// create a new account, deploy the forwarder contract copied from the
// designated account and return the new account's address
%status, %addr = copycreate %forwarder () send 0
br %status, throw
ret %addr
throw:
call @iele.invalid()
}
}