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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
|
#pragma version 5
// This application accepts payments in algo, and holds them
// until the requester asks for them back. Depositors invoke
// the app with "deposit" as arg[0], and make a pay
// transaction to the app account in the following txn slot.
// The app records the deposit in the user's local state (so
// the user must be opted-in), though they may do so in their
// initial call.
// To withdraw, users call with "withdraw" in arg[0], and a
// big-endian integer amount in arg[1]. If the withdrawal
// amount is less than the amount deposited, the app pays out
// the request, and decrements the user's balance.
// ApplicationID is zero in inital creation txn
txn ApplicationID
bz handle_createapp
// Handle possible OnCompletion type. We don't have to
// worry about handling ClearState, because the
// ClearStateProgram will execute in that case, not the
// ApprovalProgram.
txn OnCompletion
int NoOp
==
bnz handle_noop
txn OnCompletion
int OptIn
==
bnz handle_optin
txn OnCompletion
int CloseOut
==
bnz handle_closeout
txn OnCompletion
int UpdateApplication
==
bnz handle_updateapp
txn OnCompletion
int DeleteApplication
==
bnz handle_deleteapp
// Unexpected OnCompletion value. Should be unreachable.
err
handle_createapp:
int 1
return
handle_optin:
// Let anyone optin with a single txn, with no arguments. If
// it's not a single txn, fall through to handle_noop, so that
// a deposit can be made while opting in.
// We should standardize a behaviour like this in ABI.
global GroupSize
int 1
==
bz handle_noop
int 1
return
handle_noop:
txn ApplicationArgs 0
byte "deposit():void"
==
bz not_deposit
byte "deposit"
callsub debug
// Handle a deposit. Next txn slot must pay our app account
txn GroupIndex
int 1
+
dup
dup
gtxns TypeEnum
int pay // axfer if we want an ASA escrower
==
assert
gtxns Receiver
global CurrentApplicationAddress
==
assert
gtxns Amount // For ASA escrow, use AssetAmount
// Track the amount this sender deposited in their local state
int 0
byte "balance"
dup2
app_local_get
uncover 3 // pull up the Amount
+
app_local_put
int 1
return
not_deposit:
txn ApplicationArgs 0
byte "withdraw(uint64):void"
==
bz not_withdraw
// Handle withdraw.
int 0
byte "balance"
dup2
app_local_get
// Subtract the request and replace. Rejects on underflow
txn ApplicationArgs 1
btoi
-
app_local_put
itxn_begin
int pay
itxn_field TypeEnum
txn ApplicationArgs 1
btoi
itxn_field Amount
txn Sender
itxn_field Receiver
itxn_submit
int 1
return
not_withdraw:
// Unknown call "method"
err
handle_closeout:
int 1
return
handle_updateapp:
handle_deleteapp:
txn Sender
global CreatorAddress
==
return
bad:
err
debug:
byte "debug"
swap
app_global_put
retsub
|