summaryrefslogtreecommitdiff
path: root/test/scripts/e2e_subs/tealprogs/assets-escrow.teal
blob: 3ddf42a197233674314f233aef4b03275b50ce73 (plain)
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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
#pragma version 5
        // This application accepts these actions on assets
        // optin():void  - opt in the app to an asset
        // close():void - opt out the app from an asset
        // deposit():void - deposit assets on app and hold until withdraw is requested;
        //                  update the asset balance in app's local state
        // withdraw(uint64):void - withdraw assets from and update the asset balance in app's local state.
        //                         approve if withdraw amount < balance
        // transfer(uint64):void - app has clawback auth to transfer assets between accounts
        // create(uint64):void - app creates assets
        // mint():void - withdraw assets created by app
        // freeze(uint64):void - freeze/unfreeze an asset on an account

        // 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:
        // opt in app to asset to enable axfer
        txn ApplicationArgs 0
        byte "optin():void"
        ==
        bz not_optin
        byte "optin"
        callsub debug

        itxn_begin
         int axfer
         itxn_field TypeEnum

         int 0
         itxn_field AssetAmount

         txna Assets 0
         itxn_field XferAsset

         global CurrentApplicationAddress
         itxn_field AssetReceiver
        itxn_submit

        int 1
        return
not_optin:
        txn ApplicationArgs 0
        byte "deposit():void"
        ==
        bz not_deposit

        byte "deposit"
        callsub debug

        // Handle a deposit. Next txn slot must axfer our app account
        txn GroupIndex
        int 1
        +
        dup
        dup

        gtxns TypeEnum
        int axfer
        ==
        assert

        gtxns AssetReceiver
        global CurrentApplicationAddress
        ==
        assert

        gtxns 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 axfer
         itxn_field TypeEnum

         txna Assets 0
         itxn_field XferAsset

         txn ApplicationArgs 1
         btoi
         itxn_field AssetAmount

         txn Sender
         itxn_field AssetReceiver
        itxn_submit

        int 1
        return
not_withdraw:
        txn ApplicationArgs 0
        byte "close():void"
        ==
        bz not_close

        // Handle close.
        itxn_begin
            int axfer
            itxn_field TypeEnum

            txna Assets 0
            itxn_field XferAsset

            int 0
            itxn_field AssetAmount

            txn Sender
            itxn_field AssetReceiver

            txn Sender
            itxn_field AssetCloseTo
        itxn_submit

        int 1
        return
not_close:
        txn ApplicationArgs 0
        byte "transfer(uint64):void"
        ==
        bz not_transfer

        // Handle transfer.
        itxn_begin
            int axfer
            itxn_field TypeEnum

            txna Assets 0
            itxn_field XferAsset

            txn ApplicationArgs 1
            btoi
            itxn_field AssetAmount

            txn Sender
            itxn_field AssetSender

            txna Accounts 1
            itxn_field AssetReceiver

        itxn_submit

        int 1
        return

not_transfer:
        txn ApplicationArgs 0
        byte "create(uint64):void"
        ==
        bz not_create
        // Handle create.
        itxn_begin
          int acfg
          itxn_field TypeEnum

          txn ApplicationArgs 1
          btoi
          itxn_field ConfigAssetTotal
          int 0
          itxn_field ConfigAssetDecimals
          byte "x"
          itxn_field ConfigAssetUnitName
          byte "X"
          itxn_field ConfigAssetName
          global CurrentApplicationAddress
          itxn_field ConfigAssetFreeze

        itxn_submit
        int 1
        return
not_create:
        txn ApplicationArgs 0
        byte "mint():void"
        ==
        bz not_mint
        // Handle mint.  Next txn slot must pay our app account
        txn GroupIndex
        int 1
        +
        dup
        dup

        gtxns TypeEnum
        int pay
        ==
        assert

        gtxns Receiver
        global CurrentApplicationAddress
        ==
        assert

        // mint asset
        itxn_begin
         int axfer
         itxn_field TypeEnum

         txna Assets 0
         itxn_field XferAsset

         gtxns Amount
         itxn_field AssetAmount

         txn Sender
         itxn_field AssetReceiver
        itxn_submit

        int 1
        return
not_mint:
        txn ApplicationArgs 0
        byte "freeze(uint64):void"
        ==
        bz not_freeze

        //Handle freeze
        itxn_begin
          int afrz
          itxn_field TypeEnum

          txna Assets 0
          itxn_field FreezeAsset

          txn ApplicationArgs 1
          btoi
          itxn_field FreezeAssetFrozen

          txn Sender
          itxn_field FreezeAssetAccount

        itxn_submit

        int 1
        return
not_freeze:
        // Unknown call "method"
        err

handle_closeout:
        int 1
        return

handle_updateapp:
handle_deleteapp:
        txn Sender
        global CreatorAddress
        ==
        return
debug:
        byte "debug"
        swap
        app_global_put
        retsub