Skip to content

Commit 7991a84

Browse files
authored
e2e tests for axfer, acfg, and afrz inner txns (#2947)
Similar to app-accounts test, but tests all sorts of asset txns instead of pays.
1 parent 073717e commit 7991a84

File tree

2 files changed

+595
-0
lines changed

2 files changed

+595
-0
lines changed
Lines changed: 267 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,267 @@
1+
#!/bin/bash
2+
3+
filename=$(basename "$0")
4+
scriptname="${filename%.*}"
5+
date "+${scriptname} start %Y%m%d_%H%M%S"
6+
7+
8+
my_dir="$(dirname "$0")"
9+
source "$my_dir/rest.sh" "$@"
10+
function rest() {
11+
curl -q -s -H "Authorization: Bearer $PUB_TOKEN" "$NET$1"
12+
}
13+
14+
set -e
15+
set -x
16+
set -o pipefail
17+
export SHELLOPTS
18+
19+
WALLET=$1
20+
21+
TEAL=test/scripts/e2e_subs/tealprogs
22+
23+
gcmd="goal -w ${WALLET}"
24+
25+
ACCOUNT=$(${gcmd} account list|awk '{ print $3 }')
26+
# Create a smaller account so rewards won't change balances.
27+
SMALL=$(${gcmd} account new | awk '{ print $6 }')
28+
# Under one algo receives no rewards
29+
${gcmd} clerk send -a 1000000 -f "$ACCOUNT" -t "$SMALL"
30+
31+
function balance {
32+
acct=$1; shift
33+
goal account balance -a "$acct" | awk '{print $1}'
34+
}
35+
36+
[ "$(balance "$ACCOUNT")" = 999998999000 ]
37+
[ "$(balance "$SMALL")" = 1000000 ]
38+
39+
function created_assets {
40+
acct=$1;
41+
goal account info -a "$acct" | awk '/Created Assets:/,/Held Assets:/' | grep "ID*" | awk -F'[, ]' '{print $4}'
42+
}
43+
44+
function created_supply {
45+
acct=$1;
46+
goal account info -a "$acct" | awk '/Created Assets:/,/Held Assets:/' | grep "ID*" | awk -F'[, ]' '{print $7}'
47+
}
48+
49+
function asset_bal {
50+
acct=$1;
51+
goal account info -a "$acct" | awk '/Held Assets:/,/Created Apps:/' | grep "ID*" | awk -F'[, ]' '{print $7}'
52+
}
53+
54+
function asset_ids {
55+
acct=$1;
56+
goal account info -a "$acct" | awk '/Held Assets:/,/Created Apps:/' | grep "ID*" | awk -F'[, ]' '{print $2}'
57+
}
58+
#
59+
function assets {
60+
acct=$1;
61+
goal account info -a "$acct" | awk '/Held Assets:/,/Created Apps:/' | grep "ID*" | awk -F'[, ]' '{print $4}'
62+
}
63+
64+
APPID=$(${gcmd} app create --creator "${SMALL}" --approval-prog=${TEAL}/assets-escrow.teal --global-byteslices 4 --global-ints 0 --local-byteslices 0 --local-ints 1 --clear-prog=${TEAL}/approve-all.teal | grep Created | awk '{ print $6 }')
65+
[ "$(balance "$SMALL")" = 999000 ] # 1000 fee
66+
67+
function appl {
68+
method=$1; shift
69+
${gcmd} app call --app-id="$APPID" --app-arg="str:$method" "$@"
70+
}
71+
72+
function app-txid {
73+
# When app (call or optin) submits, this is how the txid is
74+
# printed. Not in appl() because appl is also used with -o to
75+
# create tx
76+
grep -o -E 'txid [A-Z0-9]{52}' | cut -c 6- | head -1
77+
}
78+
79+
function asset-id {
80+
grep -o -E 'index [A-Z0-9]+'| cut -c 7-
81+
}
82+
83+
APPACCT=$(python -c "import algosdk.encoding as e; print(e.encode_address(e.checksum(b'appID'+($APPID).to_bytes(8, 'big'))))")
84+
[ "$(balance "$SMALL")" = 999000 ] # 1000 fee
85+
86+
function asset-create {
87+
amount=$1; shift
88+
${gcmd} asset create --creator "$SMALL" --total "$amount" --decimals 0 "$@"
89+
}
90+
91+
function asset-deposit {
92+
amount=$1;shift
93+
ID=$1; shift
94+
${gcmd} asset send -f "$SMALL" -t "$APPACCT" -a "$amount" --assetid "$ID" "$@"
95+
}
96+
97+
function asset-optin {
98+
${gcmd} asset send -a 0 "$@"
99+
}
100+
101+
function clawback_addr {
102+
grep -o -E 'Clawback address: [A-Z0-9]{58}' | awk '{print $3}'
103+
}
104+
105+
function payin {
106+
amount=$1; shift
107+
${gcmd} clerk send -f "$SMALL" -t "$APPACCT" -a "$amount" "$@"
108+
}
109+
110+
T=$TEMPDIR
111+
112+
function sign {
113+
${gcmd} clerk sign -i "$T/$1.tx" -o "$T/$1.stx"
114+
}
115+
116+
TXID=$(${gcmd} app optin --app-id "$APPID" --from "${SMALL}" | app-txid)
117+
# Rest succeeds, no stray inner-txn array
118+
[ "$(rest "/v2/transactions/pending/$TXID" | jq '.["inner-txn"]')" == null ]
119+
[ "$(balance "$SMALL")" = 998000 ] # 1000 fee
120+
121+
ASSETID=$(asset-create 1000000 --name "e2e" --unitname "e" | asset-id)
122+
[ "$(balance "$SMALL")" = 997000 ] # 1000 fee
123+
124+
${gcmd} clerk send -a 1000000 -f "$ACCOUNT" -t "$APPACCT"
125+
appl "optin():void" --foreign-asset="$ASSETID" --from="$SMALL"
126+
[ "$(balance "$APPACCT")" = 999000 ] # 1000 fee
127+
[ "$(balance "$SMALL")" = 996000 ]
128+
129+
appl "deposit():void" -o "$T/deposit.tx" --from="$SMALL"
130+
asset-deposit 1000 $ASSETID -o "$T/axfer1.tx"
131+
cat "$T/deposit.tx" "$T/axfer1.tx" | ${gcmd} clerk group -i - -o "$T/group.tx"
132+
sign group
133+
${gcmd} clerk rawsend -f "$T/group.stx"
134+
135+
[ "$(asset_ids "$SMALL")" = $ASSETID ] # asset ID
136+
[ "$(asset_bal "$SMALL")" = 999000 ] # asset balance
137+
[ "$(asset_ids "$APPACCT")" = $ASSETID ]
138+
[ "$(asset_bal "$APPACCT")" = 1000 ]
139+
[ "$(balance "$SMALL")" = 994000 ] # 2 fees
140+
[ "$(balance "$APPACCT")" = 999000 ]
141+
142+
# Withdraw 100 in app. Confirm that inner txn is visible to transaction API.
143+
TXID=$(appl "withdraw(uint64):void" --app-arg="int:100" --foreign-asset="$ASSETID" --from="$SMALL" | app-txid)
144+
[ "$(rest "/v2/transactions/pending/$TXID" \
145+
| jq '.["inner-txns"][0].txn.txn.aamt')" = 100 ]
146+
[ "$(rest "/v2/transactions/pending/$TXID?format=msgpack" | msgpacktool -d \
147+
| jq '.["inner-txns"][0].txn.txn.type')" = '"axfer"' ]
148+
# Now confirm it's in blocks API (this time in our internal form)
149+
ROUND=$(rest "/v2/transactions/pending/$TXID" | jq '.["confirmed-round"]')
150+
rest "/v2/blocks/$ROUND" | jq .block.txns[0].dt.itx
151+
152+
[ "$(asset_bal "$SMALL")" = 999100 ] # 100 asset withdrawn
153+
[ "$(asset_bal "$APPACCT")" = 900 ] # 100 asset withdrawn
154+
[ "$(balance "$SMALL")" = 993000 ] # 1 fee
155+
[ "$(balance "$APPACCT")" = 998000 ] # fee paid by app
156+
157+
appl "withdraw(uint64):void" --app-arg="int:100" --foreign-asset="$ASSETID" --fee 2000 --from="$SMALL"
158+
[ "$(asset_bal "$SMALL")" = 999200 ] # 100 asset withdrawn
159+
[ "$(balance "$SMALL")" = 991000 ] # 2000 fee
160+
[ "$(asset_bal "$APPACCT")" = 800 ] # 100 asset withdrawn
161+
[ "$(balance "$APPACCT")" = 998000 ] # fee credit used
162+
163+
# Try to withdraw too much
164+
appl "withdraw(uint64):void" --app-arg="int:1000" --foreign-asset="$ASSETID" --from="$SMALL" && exit 1
165+
[ "$(asset_bal "$SMALL")" = 999200 ] # no change
166+
[ "$(asset_bal "$APPACCT")" = 800 ] # no change
167+
[ "$(balance "$SMALL")" = 991000 ]
168+
[ "$(balance "$APPACCT")" = 998000 ]
169+
170+
# Show that it works AT exact asset balance
171+
appl "withdraw(uint64):void" --app-arg="int:800" --foreign-asset="$ASSETID" --from="$SMALL"
172+
[ "$(asset_bal "$SMALL")" = 1000000 ]
173+
[ "$(asset_bal "$APPACCT")" = 0 ]
174+
[ "$(balance "$SMALL")" = 990000 ]
175+
[ "$(balance "$APPACCT")" = 997000 ]
176+
177+
USER=$(${gcmd} account new | awk '{ print $6 }') #new account
178+
${gcmd} clerk send -a 1000000 -f "$ACCOUNT" -t "$USER" #fund account
179+
asset-optin -f "$USER" -t "$USER" --assetid "$ASSETID" #opt in to asset
180+
# SET $USER as clawback address
181+
${gcmd} asset config --manager $SMALL --assetid $ASSETID --new-clawback $USER
182+
cb_addr=$(${gcmd} asset info --assetid $ASSETID | clawback_addr)
183+
[ "$cb_addr" = "$USER" ]
184+
${gcmd} asset send -f "$SMALL" -t "$USER" -a "1000" --assetid "$ASSETID" --clawback "$USER"
185+
[ $(asset_bal "$USER") = 1000 ]
186+
[ $(asset_bal "$SMALL") = 999000 ]
187+
# rekey $USER to "$APPACCT"
188+
${gcmd} clerk send --from "$USER" --to "$USER" -a 0 --rekey-to "$APPACCT"
189+
# $USER should still have clawback auth. should have been authorized by "$APPACCT"
190+
${gcmd} asset send -f "$SMALL" -t "$USER" -a "1000" --assetid "$ASSETID" --clawback "$USER" && exit 1
191+
192+
USER2=$(${gcmd} account new | awk '{ print $6 }') #new account
193+
${gcmd} clerk send -a 1000000 -f "$ACCOUNT" -t "$USER2" #fund account
194+
asset-optin -f "$USER2" -t "$USER2" --assetid "$ASSETID" #opt in to asset
195+
# set $APPACCT as clawback address on asset
196+
${gcmd} asset config --manager $SMALL --assetid $ASSETID --new-clawback $APPACCT
197+
cb_addr=$(${gcmd} asset info --assetid $ASSETID | clawback_addr)
198+
[ "$cb_addr" = "$APPACCT" ] #app is set as clawback address
199+
# transfer asset from $SMALL to $USER
200+
appl "transfer(uint64):void" --app-arg="int:1000" --foreign-asset="$ASSETID" --from="$SMALL" --app-account="$USER2"
201+
[ $(asset_bal "$USER2") = 1000 ]
202+
[ $(asset_bal "$SMALL") = 998000 ]
203+
# transfer asset from $USER to $SMALL
204+
appl "transfer(uint64):void" --app-arg="int:100" --foreign-asset="$ASSETID" --from="$USER2" --app-account="$SMALL"
205+
[ $(asset_bal "$USER2") = 900 ]
206+
[ $(asset_bal "$SMALL") = 998100 ]
207+
208+
# opt in more assets
209+
ASSETID2=$(asset-create 1000000 --name "alpha" --unitname "a" | asset-id)
210+
appl "optin():void" --foreign-asset="$ASSETID2" --from="$SMALL"
211+
ASSETID3=$(asset-create 1000000 --name "beta" --unitname "b" | asset-id)
212+
appl "optin():void" --foreign-asset="$ASSETID3" --from="$SMALL"
213+
214+
IDs="$ASSETID
215+
$ASSETID2
216+
$ASSETID3"
217+
[[ "$(asset_ids "$APPACCT")" = $IDs ]] # account has 3 assets
218+
219+
# opt out of assets
220+
appl "close():void" --foreign-asset="$ASSETID2" --from="$SMALL"
221+
IDs="$ASSETID
222+
$ASSETID3"
223+
[[ "$(asset_ids "$APPACCT")" = $IDs ]] # account has 2 assets
224+
appl "close():void" --foreign-asset="$ASSETID" --from="$SMALL"
225+
appl "close():void" --foreign-asset="$ASSETID3" --from="$SMALL"
226+
[[ "$(asset_ids "$APPACCT")" = "" ]] # account has no assets
227+
228+
# app creates asset
229+
appl "create(uint64):void" --app-arg="int:1000000" --from="$SMALL"
230+
[ "$(created_assets "$APPACCT")" = "X" ]
231+
[ "$(created_supply "$APPACCT")" = 1000000 ]
232+
233+
# mint asset
234+
APPASSETID=$(asset_ids "$APPACCT")
235+
asset-optin -f "$SMALL" -t "$SMALL" --assetid "$APPASSETID" #opt in to asset
236+
appl "mint():void" --from="$SMALL" --foreign-asset="$APPASSETID" -o "$T/mint.tx"
237+
payin 1000 -o "$T/pay1.tx"
238+
cat "$T/mint.tx" "$T/pay1.tx" | ${gcmd} clerk group -i - -o "$T/group.tx"
239+
sign group
240+
${gcmd} clerk rawsend -f "$T/group.stx"
241+
242+
IDs="$ASSETID
243+
$ASSETID2
244+
$ASSETID3
245+
$APPASSETID"
246+
[[ "$(asset_ids "$SMALL")" = $IDs ]] # has new asset
247+
[ "$(asset_bal "$SMALL" | awk 'FNR==4{print $0}')" = 1000 ] # correct balances
248+
[ "$(asset_bal "$APPACCT")" = 999000 ] # 1k sent
249+
250+
# freeze asset
251+
appl "freeze(uint64):void" --app-arg="int:1" --foreign-asset="$APPASSETID" --from="$SMALL"
252+
# fail since asset is frozen on $SMALL
253+
appl "mint():void" --from="$SMALL" -o "$T/mint.tx" --foreign-asset="$APPASSETID"
254+
payin 1000 -o "$T/pay1.tx"
255+
cat "$T/mint.tx" "$T/pay1.tx" | ${gcmd} clerk group -i - -o "$T/group.tx"
256+
sign group
257+
${gcmd} clerk rawsend -f "$T/group.stx" && exit 1
258+
# unfreeze asset
259+
appl "freeze(uint64):void" --app-arg="int:0" --foreign-asset="$APPASSETID" --from="$SMALL"
260+
appl "mint():void" --from="$SMALL" -o "$T/mint.tx" --foreign-asset="$APPASSETID"
261+
payin 1000 -o "$T/pay1.tx"
262+
cat "$T/mint.tx" "$T/pay1.tx" | ${gcmd} clerk group -i - -o "$T/group.tx"
263+
sign group
264+
${gcmd} clerk rawsend -f "$T/group.stx"
265+
[ "$(asset_bal "$SMALL" | awk 'FNR==4{print $0}')" = 2000 ] # minted 1000
266+
267+
date "+${scriptname} OK %Y%m%d_%H%M%S"

0 commit comments

Comments
 (0)