|
| 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