From e21dc55779fbd18e432a5e57b9e4535be64a8820 Mon Sep 17 00:00:00 2001 From: Daniel McGregor Date: Wed, 13 Mar 2024 17:07:05 +0800 Subject: [PATCH] feat: add is_opted_in method to Account type (#126) --- examples/sizes.txt | 4 +- .../awst_build/eb/reference_types/account.py | 56 +++- src/puyapy-stubs/_reference.pyi | 7 + test_cases/application/contract.py | 2 + .../application/out/Reference.approval.mir | 291 +++++++++--------- .../application/out/Reference.approval.teal | 45 +-- .../application/out/Reference.clear.mir | 4 +- .../application/out/Reference.clear.teal | 2 +- .../application/out/Reference.destructured.ir | 82 ++--- test_cases/application/out/Reference.ssa.ir | 88 +++--- .../out/Reference.ssa.opt_pass_1.ir | 82 ++--- test_cases/application/out/contract.awst | 1 + .../out_O2/Reference.approval.teal | 5 + .../out_O2/Reference.destructured.ir | 82 ++--- .../out_unoptimized/Reference.approval.teal | 47 +-- .../out_unoptimized/Reference.clear.teal | 2 +- .../out_unoptimized/Reference.destructured.ir | 88 +++--- test_cases/application/puya.log | 152 ++++----- test_cases/asset/contract.py | 1 + test_cases/asset/out/Reference.approval.mir | 9 + test_cases/asset/out/Reference.approval.teal | 7 + .../asset/out/Reference.destructured.ir | 3 + test_cases/asset/out/Reference.ssa.ir | 3 + .../asset/out/Reference.ssa.opt_pass_1.ir | 3 + test_cases/asset/out/contract.awst | 1 + .../asset/out_O2/Reference.approval.teal | 5 + .../asset/out_O2/Reference.destructured.ir | 3 + .../out_unoptimized/Reference.approval.teal | 8 + .../out_unoptimized/Reference.destructured.ir | 3 + test_cases/asset/puya.log | 4 + 30 files changed, 630 insertions(+), 460 deletions(-) diff --git a/examples/sizes.txt b/examples/sizes.txt index 7e62cdba57..b2415f1f74 100644 --- a/examples/sizes.txt +++ b/examples/sizes.txt @@ -1,7 +1,7 @@ Name O0 size O1 size O2 size abi_routing/Reference 1179 1019 1019 amm/ConstantProductAMM 1213 1114 1114 -application/Reference 168 161 161 +application/Reference 175 168 168 arc4_numeric_comparisons/UIntNOrdering 1220 908 908 arc4_types/Arc4Arrays 588 376 376 arc4_types/Arc4BoolEval 569 20 20 @@ -15,7 +15,7 @@ arc4_types/Arc4StringTypes 328 8 8 arc4_types/Arc4StructsFromAnotherModule 67 12 12 arc4_types/Arc4StructsType 296 237 237 arc4_types/Arc4TuplesType 799 146 146 -asset/Reference 259 252 252 +asset/Reference 268 261 261 auction/Auction 564 523 523 augmented_assignment/Augmented 157 156 156 avm_types_in_abi/Test 226 173 173 diff --git a/src/puya/awst_build/eb/reference_types/account.py b/src/puya/awst_build/eb/reference_types/account.py index d22ee289f8..aabf19d85a 100644 --- a/src/puya/awst_build/eb/reference_types/account.py +++ b/src/puya/awst_build/eb/reference_types/account.py @@ -1,6 +1,7 @@ from __future__ import annotations import typing +from typing import Sequence from immutabledict import immutabledict @@ -10,10 +11,16 @@ AddressConstant, BytesComparisonExpression, EqualityComparison, + Expression, IntrinsicCall, Literal, + TupleItemExpression, +) +from puya.awst_build.eb.base import ( + BuilderComparisonOp, + ExpressionBuilder, + IntermediateExpressionBuilder, ) -from puya.awst_build.eb.base import BuilderComparisonOp, ExpressionBuilder from puya.awst_build.eb.bytes_backed import BytesBackedClassExpressionBuilder from puya.awst_build.eb.reference_types.base import ReferenceValueExpressionBuilder from puya.awst_build.eb.var_factory import var_expression @@ -57,6 +64,48 @@ def call( raise CodeError("Invalid/unhandled arguments", location) +class AccountOptedInExpressionBuilder(IntermediateExpressionBuilder): + def __init__(self, expr: Expression, source_location: SourceLocation): + super().__init__(source_location) + self.expr = expr + + def call( + self, + args: Sequence[ExpressionBuilder | Literal], + arg_kinds: list[mypy.nodes.ArgKind], + arg_names: list[str | None], + location: SourceLocation, + original_expr: mypy.nodes.CallExpr, + ) -> ExpressionBuilder: + match args: + case [ExpressionBuilder(value_type=wtypes.asset_wtype) as asset]: + return var_expression( + TupleItemExpression( + base=IntrinsicCall( + op_code="asset_holding_get", + immediates=["AssetBalance"], + stack_args=[self.expr, asset.rvalue()], + wtype=wtypes.WTuple.from_types( + (wtypes.uint64_wtype, wtypes.bool_wtype) + ), + source_location=location, + ), + index=1, + source_location=location, + ) + ) + case [ExpressionBuilder(value_type=wtypes.application_wtype) as app]: + return var_expression( + IntrinsicCall( + op_code="app_opted_in", + stack_args=[self.expr, app.rvalue()], + source_location=location, + wtype=wtypes.bool_wtype, + ) + ) + raise CodeError("Unexpected argument", location) + + class AccountExpressionBuilder(ReferenceValueExpressionBuilder): wtype = wtypes.account_wtype native_wtype = wtypes.bytes_wtype @@ -80,6 +129,11 @@ class AccountExpressionBuilder(ReferenceValueExpressionBuilder): field_op_code = "acct_params_get" field_bool_comment = "account funded" + def member_access(self, name: str, location: SourceLocation) -> ExpressionBuilder | Literal: + if name == "is_opted_in": + return AccountOptedInExpressionBuilder(self.expr, location) + return super().member_access(name, location) + def bool_eval(self, location: SourceLocation, *, negate: bool = False) -> ExpressionBuilder: cmp_with_zero_expr = BytesComparisonExpression( source_location=location, diff --git a/src/puyapy-stubs/_reference.pyi b/src/puyapy-stubs/_reference.pyi index 99580475d9..a041b5f3ce 100644 --- a/src/puyapy-stubs/_reference.pyi +++ b/src/puyapy-stubs/_reference.pyi @@ -117,6 +117,13 @@ class Account(BytesBacked): Account must be an available resource ``` """ + def is_opted_in(self, aseet_or_app: Asset | Application) -> bool: + """Returns true if this account is opted in to the specified Asset or Application. + + ```{note} + Account and Asset/Application must be an available resource + ``` + """ class Asset: """An Asset on the Algorand network.""" diff --git a/test_cases/application/contract.py b/test_cases/application/contract.py index 91e1cab1d4..d6bd408d91 100644 --- a/test_cases/application/contract.py +++ b/test_cases/application/contract.py @@ -3,6 +3,7 @@ Bytes, Contract, LocalState, + Txn, UInt64, op, subroutine, @@ -35,6 +36,7 @@ def clear_state_program(self) -> bool: @subroutine def validate_asset(self, app: Application) -> None: + assert not Txn.sender.is_opted_in(app), "app opted in" assert app.creator == op.Global.creator_address, "expected creator" assert app.global_num_uint == 1, "expected global_num_uint" assert app.global_num_byte_slice == 2, "expected global_num_byte_slice" diff --git a/test_cases/application/out/Reference.approval.mir b/test_cases/application/out/Reference.approval.mir index 947e770e65..06403c5d5d 100644 --- a/test_cases/application/out/Reference.approval.mir +++ b/test_cases/application/out/Reference.approval.mir @@ -15,163 +15,174 @@ main_on_create@1: // Implicit fall through to main_entrypoint@2 // main_entrypoint@2: - txn NumAppArgs // {txn} op.Txn.num_app_args application/contract.py:26 - // virtual: store tmp%1#0 to l-stack (no copy) tmp%1#0 op.Txn.num_app_args application/contract.py:26 - // virtual: load tmp%1#0 from l-stack (no copy) tmp%1#0 op.Txn.num_app_args == 1: application/contract.py:26 - int 1 // tmp%1#0,1 1 application/contract.py:26 - == // {==} op.Txn.num_app_args == 1: application/contract.py:26 - // virtual: store tmp%2#0 to l-stack (no copy) tmp%2#0 op.Txn.num_app_args == 1: application/contract.py:26 - // virtual: load tmp%2#0 from l-stack (no copy) tmp%2#0 if op.Txn.num_app_args == 1: application/contract.py:26 - bz main_after_if_else@7 // if op.Txn.num_app_args == 1: application/contract.py:26 - // Implicit fall through to main_if_body@3 // if op.Txn.num_app_args == 1: application/contract.py:26 + txn NumAppArgs // {txn} op.Txn.num_app_args application/contract.py:27 + // virtual: store tmp%1#0 to l-stack (no copy) tmp%1#0 op.Txn.num_app_args application/contract.py:27 + // virtual: load tmp%1#0 from l-stack (no copy) tmp%1#0 op.Txn.num_app_args == 1: application/contract.py:27 + int 1 // tmp%1#0,1 1 application/contract.py:27 + == // {==} op.Txn.num_app_args == 1: application/contract.py:27 + // virtual: store tmp%2#0 to l-stack (no copy) tmp%2#0 op.Txn.num_app_args == 1: application/contract.py:27 + // virtual: load tmp%2#0 from l-stack (no copy) tmp%2#0 if op.Txn.num_app_args == 1: application/contract.py:27 + bz main_after_if_else@7 // if op.Txn.num_app_args == 1: application/contract.py:27 + // Implicit fall through to main_if_body@3 // if op.Txn.num_app_args == 1: application/contract.py:27 main_if_body@3: - txna ApplicationArgs 0 // {txna} op.Txn.application_args(0) application/contract.py:27 - // virtual: store tmp%3#0 to l-stack (no copy) tmp%3#0 op.Txn.application_args(0) application/contract.py:27 - // virtual: load tmp%3#0 from l-stack (no copy) tmp%3#0 op.Txn.application_args(0) == b"validate": application/contract.py:27 - byte "validate" // tmp%3#0,"validate" b"validate" application/contract.py:27 - == // {==} op.Txn.application_args(0) == b"validate": application/contract.py:27 - // virtual: store tmp%4#0 to l-stack (no copy) tmp%4#0 op.Txn.application_args(0) == b"validate": application/contract.py:27 - // virtual: load tmp%4#0 from l-stack (no copy) tmp%4#0 if op.Txn.application_args(0) == b"validate": application/contract.py:27 - assert // Expected validate // if op.Txn.application_args(0) == b"validate": application/contract.py:27 - global CurrentApplicationID // {global} op.Global.current_application_id application/contract.py:28 - // virtual: store tmp%5#0 to l-stack (no copy) tmp%5#0 op.Global.current_application_id application/contract.py:28 - // virtual: load tmp%5#0 from l-stack (no copy) tmp%5#0 self.validate_asset(op.Global.current_application_id) application/contract.py:28 - callsub validate_asset // self.validate_asset(op.Global.current_application_id) application/contract.py:28 + txna ApplicationArgs 0 // {txna} op.Txn.application_args(0) application/contract.py:28 + // virtual: store tmp%3#0 to l-stack (no copy) tmp%3#0 op.Txn.application_args(0) application/contract.py:28 + // virtual: load tmp%3#0 from l-stack (no copy) tmp%3#0 op.Txn.application_args(0) == b"validate": application/contract.py:28 + byte "validate" // tmp%3#0,"validate" b"validate" application/contract.py:28 + == // {==} op.Txn.application_args(0) == b"validate": application/contract.py:28 + // virtual: store tmp%4#0 to l-stack (no copy) tmp%4#0 op.Txn.application_args(0) == b"validate": application/contract.py:28 + // virtual: load tmp%4#0 from l-stack (no copy) tmp%4#0 if op.Txn.application_args(0) == b"validate": application/contract.py:28 + assert // Expected validate // if op.Txn.application_args(0) == b"validate": application/contract.py:28 + global CurrentApplicationID // {global} op.Global.current_application_id application/contract.py:29 + // virtual: store tmp%5#0 to l-stack (no copy) tmp%5#0 op.Global.current_application_id application/contract.py:29 + // virtual: load tmp%5#0 from l-stack (no copy) tmp%5#0 self.validate_asset(op.Global.current_application_id) application/contract.py:29 + callsub validate_asset // self.validate_asset(op.Global.current_application_id) application/contract.py:29 // Implicit fall through to main_after_if_else@7 // main_after_if_else@7: - int 1 // 1 True application/contract.py:31 - return // return True application/contract.py:31 + int 1 // 1 True application/contract.py:32 + return // return True application/contract.py:32 // test_cases.application.contract.Reference.validate_asset(app: uint64) -> void: validate_asset: - proto 1 0 // (𝕡) app#0 | @subroutine\ndef validate_asset(self, app: Application) -> None: application/contract.py:36-37 + proto 1 0 // (𝕡) app#0 | @subroutine\ndef validate_asset(self, app: Application) -> None: application/contract.py:37-38 validate_asset_block@0: - frame_dig -1 // load app#0 from parameters (𝕡) app#0 | app#0 app.creator application/contract.py:38 - app_params_get AppCreator // (𝕡) app#0 | {app_params_get}.0,{app_params_get}.1 app.creator application/contract.py:38 - // virtual: store check%1#0 to l-stack (no copy) (𝕡) app#0 | check%1#0,{app_params_get}.0 app.creator application/contract.py:38 - // virtual: store value%0#0 to l-stack (no copy) (𝕡) app#0 | value%0#0,check%1#0 app.creator application/contract.py:38 - // virtual: load check%1#0 from l-stack (no copy) (𝕡) app#0 | value%0#0,check%1#0 app.creator application/contract.py:38 - assert // application exists // (𝕡) app#0 | value%0#0 app.creator application/contract.py:38 - global CreatorAddress // (𝕡) app#0 | value%0#0,{global} op.Global.creator_address application/contract.py:38 - // virtual: store tmp%2#0 to l-stack (no copy) (𝕡) app#0 | value%0#0,tmp%2#0 op.Global.creator_address application/contract.py:38 - // virtual: load value%0#0 from l-stack (no copy) (𝕡) app#0 | tmp%2#0,value%0#0 app.creator == op.Global.creator_address, "expected creator" application/contract.py:38 - // virtual: load tmp%2#0 from l-stack (no copy) (𝕡) app#0 | value%0#0,tmp%2#0 app.creator == op.Global.creator_address, "expected creator" application/contract.py:38 - == // (𝕡) app#0 | {==} app.creator == op.Global.creator_address, "expected creator" application/contract.py:38 - // virtual: store tmp%3#0 to l-stack (no copy) (𝕡) app#0 | tmp%3#0 app.creator == op.Global.creator_address, "expected creator" application/contract.py:38 - // virtual: load tmp%3#0 from l-stack (no copy) (𝕡) app#0 | tmp%3#0 assert app.creator == op.Global.creator_address, "expected creator" application/contract.py:38 - assert // expected creator // (𝕡) app#0 | assert app.creator == op.Global.creator_address, "expected creator" application/contract.py:38 - frame_dig -1 // load app#0 from parameters (𝕡) app#0 | app#0 app.global_num_uint application/contract.py:39 - app_params_get AppGlobalNumUint // (𝕡) app#0 | {app_params_get}.0,{app_params_get}.1 app.global_num_uint application/contract.py:39 - // virtual: store check%5#0 to l-stack (no copy) (𝕡) app#0 | check%5#0,{app_params_get}.0 app.global_num_uint application/contract.py:39 - // virtual: store value%4#0 to l-stack (no copy) (𝕡) app#0 | value%4#0,check%5#0 app.global_num_uint application/contract.py:39 - // virtual: load check%5#0 from l-stack (no copy) (𝕡) app#0 | value%4#0,check%5#0 app.global_num_uint application/contract.py:39 - assert // application exists // (𝕡) app#0 | value%4#0 app.global_num_uint application/contract.py:39 - // virtual: load value%4#0 from l-stack (no copy) (𝕡) app#0 | value%4#0 app.global_num_uint == 1, "expected global_num_uint" application/contract.py:39 - int 1 // (𝕡) app#0 | value%4#0,1 1 application/contract.py:39 - == // (𝕡) app#0 | {==} app.global_num_uint == 1, "expected global_num_uint" application/contract.py:39 - // virtual: store tmp%6#0 to l-stack (no copy) (𝕡) app#0 | tmp%6#0 app.global_num_uint == 1, "expected global_num_uint" application/contract.py:39 - // virtual: load tmp%6#0 from l-stack (no copy) (𝕡) app#0 | tmp%6#0 assert app.global_num_uint == 1, "expected global_num_uint" application/contract.py:39 - assert // expected global_num_uint // (𝕡) app#0 | assert app.global_num_uint == 1, "expected global_num_uint" application/contract.py:39 - frame_dig -1 // load app#0 from parameters (𝕡) app#0 | app#0 app.global_num_byte_slice application/contract.py:40 - app_params_get AppGlobalNumByteSlice // (𝕡) app#0 | {app_params_get}.0,{app_params_get}.1 app.global_num_byte_slice application/contract.py:40 - // virtual: store check%8#0 to l-stack (no copy) (𝕡) app#0 | check%8#0,{app_params_get}.0 app.global_num_byte_slice application/contract.py:40 - // virtual: store value%7#0 to l-stack (no copy) (𝕡) app#0 | value%7#0,check%8#0 app.global_num_byte_slice application/contract.py:40 - // virtual: load check%8#0 from l-stack (no copy) (𝕡) app#0 | value%7#0,check%8#0 app.global_num_byte_slice application/contract.py:40 - assert // application exists // (𝕡) app#0 | value%7#0 app.global_num_byte_slice application/contract.py:40 - // virtual: load value%7#0 from l-stack (no copy) (𝕡) app#0 | value%7#0 app.global_num_byte_slice == 2, "expected global_num_byte_slice" application/contract.py:40 - int 2 // (𝕡) app#0 | value%7#0,2 2 application/contract.py:40 - == // (𝕡) app#0 | {==} app.global_num_byte_slice == 2, "expected global_num_byte_slice" application/contract.py:40 - // virtual: store tmp%9#0 to l-stack (no copy) (𝕡) app#0 | tmp%9#0 app.global_num_byte_slice == 2, "expected global_num_byte_slice" application/contract.py:40 - // virtual: load tmp%9#0 from l-stack (no copy) (𝕡) app#0 | tmp%9#0 assert app.global_num_byte_slice == 2, "expected global_num_byte_slice" application/contract.py:40 - assert // expected global_num_byte_slice // (𝕡) app#0 | assert app.global_num_byte_slice == 2, "expected global_num_byte_slice" application/contract.py:40 - frame_dig -1 // load app#0 from parameters (𝕡) app#0 | app#0 app.local_num_uint application/contract.py:41 - app_params_get AppLocalNumUint // (𝕡) app#0 | {app_params_get}.0,{app_params_get}.1 app.local_num_uint application/contract.py:41 - // virtual: store check%11#0 to l-stack (no copy) (𝕡) app#0 | check%11#0,{app_params_get}.0 app.local_num_uint application/contract.py:41 - // virtual: store value%10#0 to l-stack (no copy) (𝕡) app#0 | value%10#0,check%11#0 app.local_num_uint application/contract.py:41 - // virtual: load check%11#0 from l-stack (no copy) (𝕡) app#0 | value%10#0,check%11#0 app.local_num_uint application/contract.py:41 - assert // application exists // (𝕡) app#0 | value%10#0 app.local_num_uint application/contract.py:41 - // virtual: load value%10#0 from l-stack (no copy) (𝕡) app#0 | value%10#0 app.local_num_uint == 3, "expected local_num_uint" application/contract.py:41 - int 3 // (𝕡) app#0 | value%10#0,3 3 application/contract.py:41 - == // (𝕡) app#0 | {==} app.local_num_uint == 3, "expected local_num_uint" application/contract.py:41 - // virtual: store tmp%12#0 to l-stack (no copy) (𝕡) app#0 | tmp%12#0 app.local_num_uint == 3, "expected local_num_uint" application/contract.py:41 - // virtual: load tmp%12#0 from l-stack (no copy) (𝕡) app#0 | tmp%12#0 assert app.local_num_uint == 3, "expected local_num_uint" application/contract.py:41 - assert // expected local_num_uint // (𝕡) app#0 | assert app.local_num_uint == 3, "expected local_num_uint" application/contract.py:41 - frame_dig -1 // load app#0 from parameters (𝕡) app#0 | app#0 app.local_num_byte_slice application/contract.py:42 - app_params_get AppLocalNumByteSlice // (𝕡) app#0 | {app_params_get}.0,{app_params_get}.1 app.local_num_byte_slice application/contract.py:42 - // virtual: store check%14#0 to l-stack (no copy) (𝕡) app#0 | check%14#0,{app_params_get}.0 app.local_num_byte_slice application/contract.py:42 - // virtual: store value%13#0 to l-stack (no copy) (𝕡) app#0 | value%13#0,check%14#0 app.local_num_byte_slice application/contract.py:42 - // virtual: load check%14#0 from l-stack (no copy) (𝕡) app#0 | value%13#0,check%14#0 app.local_num_byte_slice application/contract.py:42 - assert // application exists // (𝕡) app#0 | value%13#0 app.local_num_byte_slice application/contract.py:42 - // virtual: load value%13#0 from l-stack (no copy) (𝕡) app#0 | value%13#0 app.local_num_byte_slice == 4, "expected local_num_byte_slice" application/contract.py:42 - int 4 // (𝕡) app#0 | value%13#0,4 4 application/contract.py:42 - == // (𝕡) app#0 | {==} app.local_num_byte_slice == 4, "expected local_num_byte_slice" application/contract.py:42 - // virtual: store tmp%15#0 to l-stack (no copy) (𝕡) app#0 | tmp%15#0 app.local_num_byte_slice == 4, "expected local_num_byte_slice" application/contract.py:42 - // virtual: load tmp%15#0 from l-stack (no copy) (𝕡) app#0 | tmp%15#0 assert app.local_num_byte_slice == 4, "expected local_num_byte_slice" application/contract.py:42 - assert // expected local_num_byte_slice // (𝕡) app#0 | assert app.local_num_byte_slice == 4, "expected local_num_byte_slice" application/contract.py:42 - frame_dig -1 // load app#0 from parameters (𝕡) app#0 | app#0 app.approval_program application/contract.py:43 - app_params_get AppApprovalProgram // (𝕡) app#0 | {app_params_get}.0,{app_params_get}.1 app.approval_program application/contract.py:43 - // virtual: store check%17#0 to l-stack (no copy) (𝕡) app#0 | check%17#0,{app_params_get}.0 app.approval_program application/contract.py:43 - // virtual: store value%16#0 to l-stack (no copy) (𝕡) app#0 | value%16#0,check%17#0 app.approval_program application/contract.py:43 - // virtual: load check%17#0 from l-stack (no copy) (𝕡) app#0 | value%16#0,check%17#0 app.approval_program application/contract.py:43 - assert // application exists // (𝕡) app#0 | value%16#0 app.approval_program application/contract.py:43 - // virtual: load value%16#0 from l-stack (no copy) (𝕡) app#0 | value%16#0 app.approval_program application/contract.py:43 - len // (𝕡) app#0 | {len} app.approval_program application/contract.py:43 - // virtual: store tmp%18#0 to l-stack (no copy) (𝕡) app#0 | tmp%18#0 app.approval_program application/contract.py:43 - // virtual: load tmp%18#0 from l-stack (no copy) (𝕡) app#0 | tmp%18#0 assert app.approval_program, "expected approval_program" application/contract.py:43 - assert // expected approval_program // (𝕡) app#0 | assert app.approval_program, "expected approval_program" application/contract.py:43 - frame_dig -1 // load app#0 from parameters (𝕡) app#0 | app#0 app.clear_state_program application/contract.py:44 - app_params_get AppClearStateProgram // (𝕡) app#0 | {app_params_get}.0,{app_params_get}.1 app.clear_state_program application/contract.py:44 - // virtual: store check%20#0 to l-stack (no copy) (𝕡) app#0 | check%20#0,{app_params_get}.0 app.clear_state_program application/contract.py:44 - // virtual: store value%19#0 to l-stack (no copy) (𝕡) app#0 | value%19#0,check%20#0 app.clear_state_program application/contract.py:44 - // virtual: load check%20#0 from l-stack (no copy) (𝕡) app#0 | value%19#0,check%20#0 app.clear_state_program application/contract.py:44 - assert // application exists // (𝕡) app#0 | value%19#0 app.clear_state_program application/contract.py:44 - // virtual: load value%19#0 from l-stack (no copy) (𝕡) app#0 | value%19#0 app.clear_state_program application/contract.py:44 - len // (𝕡) app#0 | {len} app.clear_state_program application/contract.py:44 - // virtual: store tmp%21#0 to l-stack (no copy) (𝕡) app#0 | tmp%21#0 app.clear_state_program application/contract.py:44 - // virtual: load tmp%21#0 from l-stack (no copy) (𝕡) app#0 | tmp%21#0 assert app.clear_state_program, "expected clear_state_program" application/contract.py:44 - assert // expected clear_state_program // (𝕡) app#0 | assert app.clear_state_program, "expected clear_state_program" application/contract.py:44 - global CurrentApplicationID // (𝕡) app#0 | {global} op.Global.current_application_id application/contract.py:45 - // virtual: store tmp%22#0 to l-stack (no copy) (𝕡) app#0 | tmp%22#0 op.Global.current_application_id application/contract.py:45 - frame_dig -1 // load app#0 from parameters (𝕡) app#0 | tmp%22#0,app#0 app == op.Global.current_application_id, "expected current_application_id" application/contract.py:45 - swap // load tmp%22#0 from l-stack (no copy) (𝕡) app#0 | app#0,tmp%22#0 app == op.Global.current_application_id, "expected current_application_id" application/contract.py:45 - == // (𝕡) app#0 | {==} app == op.Global.current_application_id, "expected current_application_id" application/contract.py:45 - // virtual: store tmp%23#0 to l-stack (no copy) (𝕡) app#0 | tmp%23#0 app == op.Global.current_application_id, "expected current_application_id" application/contract.py:45 - // virtual: load tmp%23#0 from l-stack (no copy) (𝕡) app#0 | tmp%23#0 assert app == op.Global.current_application_id, "expected current_application_id" application/contract.py:45 - assert // expected current_application_id // (𝕡) app#0 | assert app == op.Global.current_application_id, "expected current_application_id" application/contract.py:45 - frame_dig -1 // load app#0 from parameters (𝕡) app#0 | app#0 app.address application/contract.py:47 - app_params_get AppAddress // (𝕡) app#0 | {app_params_get}.0,{app_params_get}.1 app.address application/contract.py:47 - // virtual: store check%25#0 to l-stack (no copy) (𝕡) app#0 | check%25#0,{app_params_get}.0 app.address application/contract.py:47 - // virtual: store value%24#0 to l-stack (no copy) (𝕡) app#0 | value%24#0,check%25#0 app.address application/contract.py:47 - // virtual: load check%25#0 from l-stack (no copy) (𝕡) app#0 | value%24#0,check%25#0 app.address application/contract.py:47 - assert // application exists // (𝕡) app#0 | value%24#0 app.address application/contract.py:47 - global CurrentApplicationAddress // (𝕡) app#0 | value%24#0,{global} op.Global.current_application_address application/contract.py:47 - // virtual: store tmp%26#0 to l-stack (no copy) (𝕡) app#0 | value%24#0,tmp%26#0 op.Global.current_application_address application/contract.py:47 - // virtual: load value%24#0 from l-stack (no copy) (𝕡) app#0 | tmp%26#0,value%24#0 app.address == op.Global.current_application_address application/contract.py:47 - // virtual: load tmp%26#0 from l-stack (no copy) (𝕡) app#0 | value%24#0,tmp%26#0 app.address == op.Global.current_application_address application/contract.py:47 - == // (𝕡) app#0 | {==} app.address == op.Global.current_application_address application/contract.py:47 - // virtual: store tmp%27#0 to l-stack (no copy) (𝕡) app#0 | tmp%27#0 app.address == op.Global.current_application_address application/contract.py:47 - // virtual: load tmp%27#0 from l-stack (no copy) (𝕡) app#0 | tmp%27#0 assert (\napp.address == op.Global.current_application_address\n), "expected current_application_... application/contract.py:46-48 - assert // expected current_application_address // (𝕡) app#0 | assert (\napp.address == op.Global.current_application_address\n), "expected current_application_... application/contract.py:46-48 + txn Sender // (𝕡) app#0 | {txn} Txn.sender application/contract.py:39 + // virtual: store tmp%0#0 to l-stack (no copy) (𝕡) app#0 | tmp%0#0 Txn.sender application/contract.py:39 + // virtual: load tmp%0#0 from l-stack (no copy) (𝕡) app#0 | tmp%0#0 Txn.sender.is_opted_in(app) application/contract.py:39 + frame_dig -1 // load app#0 from parameters (𝕡) app#0 | tmp%0#0,app#0 Txn.sender.is_opted_in(app) application/contract.py:39 + app_opted_in // (𝕡) app#0 | {app_opted_in} Txn.sender.is_opted_in(app) application/contract.py:39 + // virtual: store tmp%1#0 to l-stack (no copy) (𝕡) app#0 | tmp%1#0 Txn.sender.is_opted_in(app) application/contract.py:39 + // virtual: load tmp%1#0 from l-stack (no copy) (𝕡) app#0 | tmp%1#0 not Txn.sender.is_opted_in(app) application/contract.py:39 + ! // (𝕡) app#0 | {!} not Txn.sender.is_opted_in(app) application/contract.py:39 + // virtual: store tmp%2#0 to l-stack (no copy) (𝕡) app#0 | tmp%2#0 not Txn.sender.is_opted_in(app) application/contract.py:39 + // virtual: load tmp%2#0 from l-stack (no copy) (𝕡) app#0 | tmp%2#0 assert not Txn.sender.is_opted_in(app), "app opted in" application/contract.py:39 + assert // app opted in // (𝕡) app#0 | assert not Txn.sender.is_opted_in(app), "app opted in" application/contract.py:39 + frame_dig -1 // load app#0 from parameters (𝕡) app#0 | app#0 app.creator application/contract.py:40 + app_params_get AppCreator // (𝕡) app#0 | {app_params_get}.0,{app_params_get}.1 app.creator application/contract.py:40 + // virtual: store check%4#0 to l-stack (no copy) (𝕡) app#0 | check%4#0,{app_params_get}.0 app.creator application/contract.py:40 + // virtual: store value%3#0 to l-stack (no copy) (𝕡) app#0 | value%3#0,check%4#0 app.creator application/contract.py:40 + // virtual: load check%4#0 from l-stack (no copy) (𝕡) app#0 | value%3#0,check%4#0 app.creator application/contract.py:40 + assert // application exists // (𝕡) app#0 | value%3#0 app.creator application/contract.py:40 + global CreatorAddress // (𝕡) app#0 | value%3#0,{global} op.Global.creator_address application/contract.py:40 + // virtual: store tmp%5#0 to l-stack (no copy) (𝕡) app#0 | value%3#0,tmp%5#0 op.Global.creator_address application/contract.py:40 + // virtual: load value%3#0 from l-stack (no copy) (𝕡) app#0 | tmp%5#0,value%3#0 app.creator == op.Global.creator_address, "expected creator" application/contract.py:40 + // virtual: load tmp%5#0 from l-stack (no copy) (𝕡) app#0 | value%3#0,tmp%5#0 app.creator == op.Global.creator_address, "expected creator" application/contract.py:40 + == // (𝕡) app#0 | {==} app.creator == op.Global.creator_address, "expected creator" application/contract.py:40 + // virtual: store tmp%6#0 to l-stack (no copy) (𝕡) app#0 | tmp%6#0 app.creator == op.Global.creator_address, "expected creator" application/contract.py:40 + // virtual: load tmp%6#0 from l-stack (no copy) (𝕡) app#0 | tmp%6#0 assert app.creator == op.Global.creator_address, "expected creator" application/contract.py:40 + assert // expected creator // (𝕡) app#0 | assert app.creator == op.Global.creator_address, "expected creator" application/contract.py:40 + frame_dig -1 // load app#0 from parameters (𝕡) app#0 | app#0 app.global_num_uint application/contract.py:41 + app_params_get AppGlobalNumUint // (𝕡) app#0 | {app_params_get}.0,{app_params_get}.1 app.global_num_uint application/contract.py:41 + // virtual: store check%8#0 to l-stack (no copy) (𝕡) app#0 | check%8#0,{app_params_get}.0 app.global_num_uint application/contract.py:41 + // virtual: store value%7#0 to l-stack (no copy) (𝕡) app#0 | value%7#0,check%8#0 app.global_num_uint application/contract.py:41 + // virtual: load check%8#0 from l-stack (no copy) (𝕡) app#0 | value%7#0,check%8#0 app.global_num_uint application/contract.py:41 + assert // application exists // (𝕡) app#0 | value%7#0 app.global_num_uint application/contract.py:41 + // virtual: load value%7#0 from l-stack (no copy) (𝕡) app#0 | value%7#0 app.global_num_uint == 1, "expected global_num_uint" application/contract.py:41 + int 1 // (𝕡) app#0 | value%7#0,1 1 application/contract.py:41 + == // (𝕡) app#0 | {==} app.global_num_uint == 1, "expected global_num_uint" application/contract.py:41 + // virtual: store tmp%9#0 to l-stack (no copy) (𝕡) app#0 | tmp%9#0 app.global_num_uint == 1, "expected global_num_uint" application/contract.py:41 + // virtual: load tmp%9#0 from l-stack (no copy) (𝕡) app#0 | tmp%9#0 assert app.global_num_uint == 1, "expected global_num_uint" application/contract.py:41 + assert // expected global_num_uint // (𝕡) app#0 | assert app.global_num_uint == 1, "expected global_num_uint" application/contract.py:41 + frame_dig -1 // load app#0 from parameters (𝕡) app#0 | app#0 app.global_num_byte_slice application/contract.py:42 + app_params_get AppGlobalNumByteSlice // (𝕡) app#0 | {app_params_get}.0,{app_params_get}.1 app.global_num_byte_slice application/contract.py:42 + // virtual: store check%11#0 to l-stack (no copy) (𝕡) app#0 | check%11#0,{app_params_get}.0 app.global_num_byte_slice application/contract.py:42 + // virtual: store value%10#0 to l-stack (no copy) (𝕡) app#0 | value%10#0,check%11#0 app.global_num_byte_slice application/contract.py:42 + // virtual: load check%11#0 from l-stack (no copy) (𝕡) app#0 | value%10#0,check%11#0 app.global_num_byte_slice application/contract.py:42 + assert // application exists // (𝕡) app#0 | value%10#0 app.global_num_byte_slice application/contract.py:42 + // virtual: load value%10#0 from l-stack (no copy) (𝕡) app#0 | value%10#0 app.global_num_byte_slice == 2, "expected global_num_byte_slice" application/contract.py:42 + int 2 // (𝕡) app#0 | value%10#0,2 2 application/contract.py:42 + == // (𝕡) app#0 | {==} app.global_num_byte_slice == 2, "expected global_num_byte_slice" application/contract.py:42 + // virtual: store tmp%12#0 to l-stack (no copy) (𝕡) app#0 | tmp%12#0 app.global_num_byte_slice == 2, "expected global_num_byte_slice" application/contract.py:42 + // virtual: load tmp%12#0 from l-stack (no copy) (𝕡) app#0 | tmp%12#0 assert app.global_num_byte_slice == 2, "expected global_num_byte_slice" application/contract.py:42 + assert // expected global_num_byte_slice // (𝕡) app#0 | assert app.global_num_byte_slice == 2, "expected global_num_byte_slice" application/contract.py:42 + frame_dig -1 // load app#0 from parameters (𝕡) app#0 | app#0 app.local_num_uint application/contract.py:43 + app_params_get AppLocalNumUint // (𝕡) app#0 | {app_params_get}.0,{app_params_get}.1 app.local_num_uint application/contract.py:43 + // virtual: store check%14#0 to l-stack (no copy) (𝕡) app#0 | check%14#0,{app_params_get}.0 app.local_num_uint application/contract.py:43 + // virtual: store value%13#0 to l-stack (no copy) (𝕡) app#0 | value%13#0,check%14#0 app.local_num_uint application/contract.py:43 + // virtual: load check%14#0 from l-stack (no copy) (𝕡) app#0 | value%13#0,check%14#0 app.local_num_uint application/contract.py:43 + assert // application exists // (𝕡) app#0 | value%13#0 app.local_num_uint application/contract.py:43 + // virtual: load value%13#0 from l-stack (no copy) (𝕡) app#0 | value%13#0 app.local_num_uint == 3, "expected local_num_uint" application/contract.py:43 + int 3 // (𝕡) app#0 | value%13#0,3 3 application/contract.py:43 + == // (𝕡) app#0 | {==} app.local_num_uint == 3, "expected local_num_uint" application/contract.py:43 + // virtual: store tmp%15#0 to l-stack (no copy) (𝕡) app#0 | tmp%15#0 app.local_num_uint == 3, "expected local_num_uint" application/contract.py:43 + // virtual: load tmp%15#0 from l-stack (no copy) (𝕡) app#0 | tmp%15#0 assert app.local_num_uint == 3, "expected local_num_uint" application/contract.py:43 + assert // expected local_num_uint // (𝕡) app#0 | assert app.local_num_uint == 3, "expected local_num_uint" application/contract.py:43 + frame_dig -1 // load app#0 from parameters (𝕡) app#0 | app#0 app.local_num_byte_slice application/contract.py:44 + app_params_get AppLocalNumByteSlice // (𝕡) app#0 | {app_params_get}.0,{app_params_get}.1 app.local_num_byte_slice application/contract.py:44 + // virtual: store check%17#0 to l-stack (no copy) (𝕡) app#0 | check%17#0,{app_params_get}.0 app.local_num_byte_slice application/contract.py:44 + // virtual: store value%16#0 to l-stack (no copy) (𝕡) app#0 | value%16#0,check%17#0 app.local_num_byte_slice application/contract.py:44 + // virtual: load check%17#0 from l-stack (no copy) (𝕡) app#0 | value%16#0,check%17#0 app.local_num_byte_slice application/contract.py:44 + assert // application exists // (𝕡) app#0 | value%16#0 app.local_num_byte_slice application/contract.py:44 + // virtual: load value%16#0 from l-stack (no copy) (𝕡) app#0 | value%16#0 app.local_num_byte_slice == 4, "expected local_num_byte_slice" application/contract.py:44 + int 4 // (𝕡) app#0 | value%16#0,4 4 application/contract.py:44 + == // (𝕡) app#0 | {==} app.local_num_byte_slice == 4, "expected local_num_byte_slice" application/contract.py:44 + // virtual: store tmp%18#0 to l-stack (no copy) (𝕡) app#0 | tmp%18#0 app.local_num_byte_slice == 4, "expected local_num_byte_slice" application/contract.py:44 + // virtual: load tmp%18#0 from l-stack (no copy) (𝕡) app#0 | tmp%18#0 assert app.local_num_byte_slice == 4, "expected local_num_byte_slice" application/contract.py:44 + assert // expected local_num_byte_slice // (𝕡) app#0 | assert app.local_num_byte_slice == 4, "expected local_num_byte_slice" application/contract.py:44 + frame_dig -1 // load app#0 from parameters (𝕡) app#0 | app#0 app.approval_program application/contract.py:45 + app_params_get AppApprovalProgram // (𝕡) app#0 | {app_params_get}.0,{app_params_get}.1 app.approval_program application/contract.py:45 + // virtual: store check%20#0 to l-stack (no copy) (𝕡) app#0 | check%20#0,{app_params_get}.0 app.approval_program application/contract.py:45 + // virtual: store value%19#0 to l-stack (no copy) (𝕡) app#0 | value%19#0,check%20#0 app.approval_program application/contract.py:45 + // virtual: load check%20#0 from l-stack (no copy) (𝕡) app#0 | value%19#0,check%20#0 app.approval_program application/contract.py:45 + assert // application exists // (𝕡) app#0 | value%19#0 app.approval_program application/contract.py:45 + // virtual: load value%19#0 from l-stack (no copy) (𝕡) app#0 | value%19#0 app.approval_program application/contract.py:45 + len // (𝕡) app#0 | {len} app.approval_program application/contract.py:45 + // virtual: store tmp%21#0 to l-stack (no copy) (𝕡) app#0 | tmp%21#0 app.approval_program application/contract.py:45 + // virtual: load tmp%21#0 from l-stack (no copy) (𝕡) app#0 | tmp%21#0 assert app.approval_program, "expected approval_program" application/contract.py:45 + assert // expected approval_program // (𝕡) app#0 | assert app.approval_program, "expected approval_program" application/contract.py:45 + frame_dig -1 // load app#0 from parameters (𝕡) app#0 | app#0 app.clear_state_program application/contract.py:46 + app_params_get AppClearStateProgram // (𝕡) app#0 | {app_params_get}.0,{app_params_get}.1 app.clear_state_program application/contract.py:46 + // virtual: store check%23#0 to l-stack (no copy) (𝕡) app#0 | check%23#0,{app_params_get}.0 app.clear_state_program application/contract.py:46 + // virtual: store value%22#0 to l-stack (no copy) (𝕡) app#0 | value%22#0,check%23#0 app.clear_state_program application/contract.py:46 + // virtual: load check%23#0 from l-stack (no copy) (𝕡) app#0 | value%22#0,check%23#0 app.clear_state_program application/contract.py:46 + assert // application exists // (𝕡) app#0 | value%22#0 app.clear_state_program application/contract.py:46 + // virtual: load value%22#0 from l-stack (no copy) (𝕡) app#0 | value%22#0 app.clear_state_program application/contract.py:46 + len // (𝕡) app#0 | {len} app.clear_state_program application/contract.py:46 + // virtual: store tmp%24#0 to l-stack (no copy) (𝕡) app#0 | tmp%24#0 app.clear_state_program application/contract.py:46 + // virtual: load tmp%24#0 from l-stack (no copy) (𝕡) app#0 | tmp%24#0 assert app.clear_state_program, "expected clear_state_program" application/contract.py:46 + assert // expected clear_state_program // (𝕡) app#0 | assert app.clear_state_program, "expected clear_state_program" application/contract.py:46 + global CurrentApplicationID // (𝕡) app#0 | {global} op.Global.current_application_id application/contract.py:47 + // virtual: store tmp%25#0 to l-stack (no copy) (𝕡) app#0 | tmp%25#0 op.Global.current_application_id application/contract.py:47 + frame_dig -1 // load app#0 from parameters (𝕡) app#0 | tmp%25#0,app#0 app == op.Global.current_application_id, "expected current_application_id" application/contract.py:47 + swap // load tmp%25#0 from l-stack (no copy) (𝕡) app#0 | app#0,tmp%25#0 app == op.Global.current_application_id, "expected current_application_id" application/contract.py:47 + == // (𝕡) app#0 | {==} app == op.Global.current_application_id, "expected current_application_id" application/contract.py:47 + // virtual: store tmp%26#0 to l-stack (no copy) (𝕡) app#0 | tmp%26#0 app == op.Global.current_application_id, "expected current_application_id" application/contract.py:47 + // virtual: load tmp%26#0 from l-stack (no copy) (𝕡) app#0 | tmp%26#0 assert app == op.Global.current_application_id, "expected current_application_id" application/contract.py:47 + assert // expected current_application_id // (𝕡) app#0 | assert app == op.Global.current_application_id, "expected current_application_id" application/contract.py:47 + frame_dig -1 // load app#0 from parameters (𝕡) app#0 | app#0 app.address application/contract.py:49 + app_params_get AppAddress // (𝕡) app#0 | {app_params_get}.0,{app_params_get}.1 app.address application/contract.py:49 + // virtual: store check%28#0 to l-stack (no copy) (𝕡) app#0 | check%28#0,{app_params_get}.0 app.address application/contract.py:49 + // virtual: store value%27#0 to l-stack (no copy) (𝕡) app#0 | value%27#0,check%28#0 app.address application/contract.py:49 + // virtual: load check%28#0 from l-stack (no copy) (𝕡) app#0 | value%27#0,check%28#0 app.address application/contract.py:49 + assert // application exists // (𝕡) app#0 | value%27#0 app.address application/contract.py:49 + global CurrentApplicationAddress // (𝕡) app#0 | value%27#0,{global} op.Global.current_application_address application/contract.py:49 + // virtual: store tmp%29#0 to l-stack (no copy) (𝕡) app#0 | value%27#0,tmp%29#0 op.Global.current_application_address application/contract.py:49 + // virtual: load value%27#0 from l-stack (no copy) (𝕡) app#0 | tmp%29#0,value%27#0 app.address == op.Global.current_application_address application/contract.py:49 + // virtual: load tmp%29#0 from l-stack (no copy) (𝕡) app#0 | value%27#0,tmp%29#0 app.address == op.Global.current_application_address application/contract.py:49 + == // (𝕡) app#0 | {==} app.address == op.Global.current_application_address application/contract.py:49 + // virtual: store tmp%30#0 to l-stack (no copy) (𝕡) app#0 | tmp%30#0 app.address == op.Global.current_application_address application/contract.py:49 + // virtual: load tmp%30#0 from l-stack (no copy) (𝕡) app#0 | tmp%30#0 assert (\napp.address == op.Global.current_application_address\n), "expected current_application_... application/contract.py:48-50 + assert // expected current_application_address // (𝕡) app#0 | assert (\napp.address == op.Global.current_application_address\n), "expected current_application_... application/contract.py:48-50 retsub // // test_cases.application.contract.Reference.__init__() -> void: __init__: - proto 0 0 // def __init__(self) -> None: application/contract.py:13 + proto 0 0 // def __init__(self) -> None: application/contract.py:14 __init___block@0: - byte "int_1" // "int_1" self.int_1 application/contract.py:14 - int 0 // "int_1",0 0 application/contract.py:14 - app_global_put // self.int_1 = UInt64(0) application/contract.py:14 - byte "bytes_1" // "bytes_1" self.bytes_1 application/contract.py:15 - byte "" // "bytes_1","" b"" application/contract.py:15 - app_global_put // self.bytes_1 = Bytes(b"") application/contract.py:15 - byte "bytes_2" // "bytes_2" self.bytes_2 application/contract.py:16 - byte "" // "bytes_2","" b"" application/contract.py:16 - app_global_put // self.bytes_2 = Bytes(b"") application/contract.py:16 + byte "int_1" // "int_1" self.int_1 application/contract.py:15 + int 0 // "int_1",0 0 application/contract.py:15 + app_global_put // self.int_1 = UInt64(0) application/contract.py:15 + byte "bytes_1" // "bytes_1" self.bytes_1 application/contract.py:16 + byte "" // "bytes_1","" b"" application/contract.py:16 + app_global_put // self.bytes_1 = Bytes(b"") application/contract.py:16 + byte "bytes_2" // "bytes_2" self.bytes_2 application/contract.py:17 + byte "" // "bytes_2","" b"" application/contract.py:17 + app_global_put // self.bytes_2 = Bytes(b"") application/contract.py:17 retsub // diff --git a/test_cases/application/out/Reference.approval.teal b/test_cases/application/out/Reference.approval.teal index e9666ed594..46b6610258 100644 --- a/test_cases/application/out/Reference.approval.teal +++ b/test_cases/application/out/Reference.approval.teal @@ -6,25 +6,25 @@ test_cases.application.contract.Reference.approval_program: callsub __init__ main_entrypoint@2: - // application/contract.py:26 + // application/contract.py:27 // if op.Txn.num_app_args == 1: txn NumAppArgs int 1 == bz main_after_if_else@7 - // application/contract.py:27 + // application/contract.py:28 // if op.Txn.application_args(0) == b"validate": txna ApplicationArgs 0 byte "validate" == assert // Expected validate - // application/contract.py:28 + // application/contract.py:29 // self.validate_asset(op.Global.current_application_id) global CurrentApplicationID callsub validate_asset main_after_if_else@7: - // application/contract.py:31 + // application/contract.py:32 // return True int 1 return @@ -32,11 +32,18 @@ main_after_if_else@7: // test_cases.application.contract.Reference.validate_asset(app: uint64) -> void: validate_asset: - // application/contract.py:36-37 + // application/contract.py:37-38 // @subroutine // def validate_asset(self, app: Application) -> None: proto 1 0 - // application/contract.py:38 + // application/contract.py:39 + // assert not Txn.sender.is_opted_in(app), "app opted in" + txn Sender + frame_dig -1 + app_opted_in + ! + assert // app opted in + // application/contract.py:40 // assert app.creator == op.Global.creator_address, "expected creator" frame_dig -1 app_params_get AppCreator @@ -44,7 +51,7 @@ validate_asset: global CreatorAddress == assert // expected creator - // application/contract.py:39 + // application/contract.py:41 // assert app.global_num_uint == 1, "expected global_num_uint" frame_dig -1 app_params_get AppGlobalNumUint @@ -52,7 +59,7 @@ validate_asset: int 1 == assert // expected global_num_uint - // application/contract.py:40 + // application/contract.py:42 // assert app.global_num_byte_slice == 2, "expected global_num_byte_slice" frame_dig -1 app_params_get AppGlobalNumByteSlice @@ -60,7 +67,7 @@ validate_asset: int 2 == assert // expected global_num_byte_slice - // application/contract.py:41 + // application/contract.py:43 // assert app.local_num_uint == 3, "expected local_num_uint" frame_dig -1 app_params_get AppLocalNumUint @@ -68,7 +75,7 @@ validate_asset: int 3 == assert // expected local_num_uint - // application/contract.py:42 + // application/contract.py:44 // assert app.local_num_byte_slice == 4, "expected local_num_byte_slice" frame_dig -1 app_params_get AppLocalNumByteSlice @@ -76,34 +83,34 @@ validate_asset: int 4 == assert // expected local_num_byte_slice - // application/contract.py:43 + // application/contract.py:45 // assert app.approval_program, "expected approval_program" frame_dig -1 app_params_get AppApprovalProgram assert // application exists len assert // expected approval_program - // application/contract.py:44 + // application/contract.py:46 // assert app.clear_state_program, "expected clear_state_program" frame_dig -1 app_params_get AppClearStateProgram assert // application exists len assert // expected clear_state_program - // application/contract.py:45 + // application/contract.py:47 // assert app == op.Global.current_application_id, "expected current_application_id" frame_dig -1 global CurrentApplicationID == assert // expected current_application_id - // application/contract.py:47 + // application/contract.py:49 // app.address == op.Global.current_application_address frame_dig -1 app_params_get AppAddress assert // application exists global CurrentApplicationAddress == - // application/contract.py:46-48 + // application/contract.py:48-50 // assert ( // app.address == op.Global.current_application_address // ), "expected current_application_address" @@ -113,20 +120,20 @@ validate_asset: // test_cases.application.contract.Reference.__init__() -> void: __init__: - // application/contract.py:13 + // application/contract.py:14 // def __init__(self) -> None: proto 0 0 - // application/contract.py:14 + // application/contract.py:15 // self.int_1 = UInt64(0) byte "int_1" int 0 app_global_put - // application/contract.py:15 + // application/contract.py:16 // self.bytes_1 = Bytes(b"") byte "bytes_1" byte "" app_global_put - // application/contract.py:16 + // application/contract.py:17 // self.bytes_2 = Bytes(b"") byte "bytes_2" byte "" diff --git a/test_cases/application/out/Reference.clear.mir b/test_cases/application/out/Reference.clear.mir index fe27f80d0a..62d1729239 100644 --- a/test_cases/application/out/Reference.clear.mir +++ b/test_cases/application/out/Reference.clear.mir @@ -4,6 +4,6 @@ // test_cases.application.contract.Reference.clear_state_program() -> uint64: main_block@0: - int 1 // 1 True application/contract.py:34 - return // return True application/contract.py:34 + int 1 // 1 True application/contract.py:35 + return // return True application/contract.py:35 diff --git a/test_cases/application/out/Reference.clear.teal b/test_cases/application/out/Reference.clear.teal index 427e20bb57..68733d388f 100644 --- a/test_cases/application/out/Reference.clear.teal +++ b/test_cases/application/out/Reference.clear.teal @@ -1,7 +1,7 @@ #pragma version 10 test_cases.application.contract.Reference.clear_state_program: - // application/contract.py:34 + // application/contract.py:35 // return True int 1 return diff --git a/test_cases/application/out/Reference.destructured.ir b/test_cases/application/out/Reference.destructured.ir index 6f16f1b85e..50aae1bf4d 100644 --- a/test_cases/application/out/Reference.destructured.ir +++ b/test_cases/application/out/Reference.destructured.ir @@ -1,69 +1,73 @@ contract test_cases.application.contract.Reference: program approval: subroutine test_cases.application.contract.Reference.approval_program() -> uint64: - block@0: // L25 + block@0: // L26 let app_id%0#0: uint64 = (txn ApplicationID) goto app_id%0#0 ? block@2 : block@1 - block@1: // on_create_L13 + block@1: // on_create_L14 test_cases.application.contract.Reference.__init__() goto block@2 - block@2: // entrypoint_L13 + block@2: // entrypoint_L14 let tmp%1#0: uint64 = (txn NumAppArgs) let tmp%2#0: uint64 = (== tmp%1#0 1u) goto tmp%2#0 ? block@3 : block@7 - block@3: // if_body_L26 + block@3: // if_body_L27 let tmp%3#0: bytes = (txna ApplicationArgs 0) let tmp%4#0: uint64 = (== tmp%3#0 "validate") (assert tmp%4#0) // Expected validate let tmp%5#0: uint64 = (global CurrentApplicationID) test_cases.application.contract.Reference.validate_asset(tmp%5#0) goto block@7 - block@7: // after_if_else_L26 + block@7: // after_if_else_L27 return 1u subroutine test_cases.application.contract.Reference.validate_asset(app: uint64) -> void: - block@0: // L36 - let (value%0#0: bytes, check%1#0: uint64) = ((app_params_get AppCreator) app#0) - (assert check%1#0) // application exists - let tmp%2#0: bytes = (global CreatorAddress) - let tmp%3#0: uint64 = (== value%0#0 tmp%2#0) - (assert tmp%3#0) // expected creator - let (value%4#0: uint64, check%5#0: uint64) = ((app_params_get AppGlobalNumUint) app#0) - (assert check%5#0) // application exists - let tmp%6#0: uint64 = (== value%4#0 1u) - (assert tmp%6#0) // expected global_num_uint - let (value%7#0: uint64, check%8#0: uint64) = ((app_params_get AppGlobalNumByteSlice) app#0) + block@0: // L37 + let tmp%0#0: bytes = (txn Sender) + let tmp%1#0: uint64 = (app_opted_in tmp%0#0 app#0) + let tmp%2#0: uint64 = (! tmp%1#0) + (assert tmp%2#0) // app opted in + let (value%3#0: bytes, check%4#0: uint64) = ((app_params_get AppCreator) app#0) + (assert check%4#0) // application exists + let tmp%5#0: bytes = (global CreatorAddress) + let tmp%6#0: uint64 = (== value%3#0 tmp%5#0) + (assert tmp%6#0) // expected creator + let (value%7#0: uint64, check%8#0: uint64) = ((app_params_get AppGlobalNumUint) app#0) (assert check%8#0) // application exists - let tmp%9#0: uint64 = (== value%7#0 2u) - (assert tmp%9#0) // expected global_num_byte_slice - let (value%10#0: uint64, check%11#0: uint64) = ((app_params_get AppLocalNumUint) app#0) + let tmp%9#0: uint64 = (== value%7#0 1u) + (assert tmp%9#0) // expected global_num_uint + let (value%10#0: uint64, check%11#0: uint64) = ((app_params_get AppGlobalNumByteSlice) app#0) (assert check%11#0) // application exists - let tmp%12#0: uint64 = (== value%10#0 3u) - (assert tmp%12#0) // expected local_num_uint - let (value%13#0: uint64, check%14#0: uint64) = ((app_params_get AppLocalNumByteSlice) app#0) + let tmp%12#0: uint64 = (== value%10#0 2u) + (assert tmp%12#0) // expected global_num_byte_slice + let (value%13#0: uint64, check%14#0: uint64) = ((app_params_get AppLocalNumUint) app#0) (assert check%14#0) // application exists - let tmp%15#0: uint64 = (== value%13#0 4u) - (assert tmp%15#0) // expected local_num_byte_slice - let (value%16#0: bytes, check%17#0: uint64) = ((app_params_get AppApprovalProgram) app#0) + let tmp%15#0: uint64 = (== value%13#0 3u) + (assert tmp%15#0) // expected local_num_uint + let (value%16#0: uint64, check%17#0: uint64) = ((app_params_get AppLocalNumByteSlice) app#0) (assert check%17#0) // application exists - let tmp%18#0: uint64 = (len value%16#0) - (assert tmp%18#0) // expected approval_program - let (value%19#0: bytes, check%20#0: uint64) = ((app_params_get AppClearStateProgram) app#0) + let tmp%18#0: uint64 = (== value%16#0 4u) + (assert tmp%18#0) // expected local_num_byte_slice + let (value%19#0: bytes, check%20#0: uint64) = ((app_params_get AppApprovalProgram) app#0) (assert check%20#0) // application exists let tmp%21#0: uint64 = (len value%19#0) - (assert tmp%21#0) // expected clear_state_program - let tmp%22#0: uint64 = (global CurrentApplicationID) - let tmp%23#0: uint64 = (== app#0 tmp%22#0) - (assert tmp%23#0) // expected current_application_id - let (value%24#0: bytes, check%25#0: uint64) = ((app_params_get AppAddress) app#0) - (assert check%25#0) // application exists - let tmp%26#0: bytes = (global CurrentApplicationAddress) - let tmp%27#0: uint64 = (== value%24#0 tmp%26#0) - (assert tmp%27#0) // expected current_application_address + (assert tmp%21#0) // expected approval_program + let (value%22#0: bytes, check%23#0: uint64) = ((app_params_get AppClearStateProgram) app#0) + (assert check%23#0) // application exists + let tmp%24#0: uint64 = (len value%22#0) + (assert tmp%24#0) // expected clear_state_program + let tmp%25#0: uint64 = (global CurrentApplicationID) + let tmp%26#0: uint64 = (== app#0 tmp%25#0) + (assert tmp%26#0) // expected current_application_id + let (value%27#0: bytes, check%28#0: uint64) = ((app_params_get AppAddress) app#0) + (assert check%28#0) // application exists + let tmp%29#0: bytes = (global CurrentApplicationAddress) + let tmp%30#0: uint64 = (== value%27#0 tmp%29#0) + (assert tmp%30#0) // expected current_application_address return subroutine test_cases.application.contract.Reference.__init__() -> void: - block@0: // L13 + block@0: // L14 (app_global_put "int_1" 0u) (app_global_put "bytes_1" "") (app_global_put "bytes_2" "") @@ -71,5 +75,5 @@ contract test_cases.application.contract.Reference: program clear-state: subroutine test_cases.application.contract.Reference.clear_state_program() -> uint64: - block@0: // L33 + block@0: // L34 return 1u \ No newline at end of file diff --git a/test_cases/application/out/Reference.ssa.ir b/test_cases/application/out/Reference.ssa.ir index eb1e8acbe0..9410d3ae21 100644 --- a/test_cases/application/out/Reference.ssa.ir +++ b/test_cases/application/out/Reference.ssa.ir @@ -1,74 +1,78 @@ contract test_cases.application.contract.Reference: program approval: subroutine test_cases.application.contract.Reference.approval_program() -> uint64: - block@0: // L25 + block@0: // L26 let app_id%0#0: uint64 = (txn ApplicationID) goto app_id%0#0 ? block@2 : block@1 - block@1: // on_create_L13 + block@1: // on_create_L14 test_cases.application.contract.Reference.__init__() goto block@2 - block@2: // entrypoint_L13 + block@2: // entrypoint_L14 let tmp%1#0: uint64 = (txn NumAppArgs) let tmp%2#0: uint64 = (== tmp%1#0 1u) goto tmp%2#0 ? block@3 : block@7 - block@3: // if_body_L26 + block@3: // if_body_L27 let tmp%3#0: bytes = (txna ApplicationArgs 0) let tmp%4#0: uint64 = (== tmp%3#0 "validate") goto tmp%4#0 ? block@4 : block@5 - block@4: // if_body_L27 + block@4: // if_body_L28 let tmp%5#0: uint64 = (global CurrentApplicationID) test_cases.application.contract.Reference.validate_asset(tmp%5#0) goto block@6 - block@5: // else_body_L27 + block@5: // else_body_L28 fail // Expected validate - block@6: // after_if_else_L27 + block@6: // after_if_else_L28 goto block@7 - block@7: // after_if_else_L26 + block@7: // after_if_else_L27 return 1u subroutine test_cases.application.contract.Reference.validate_asset(app: uint64) -> void: - block@0: // L36 - let (value%0#0: bytes, check%1#0: uint64) = ((app_params_get AppCreator) app#0) - (assert check%1#0) // application exists - let tmp%2#0: bytes = (global CreatorAddress) - let tmp%3#0: uint64 = (== value%0#0 tmp%2#0) - (assert tmp%3#0) // expected creator - let (value%4#0: uint64, check%5#0: uint64) = ((app_params_get AppGlobalNumUint) app#0) - (assert check%5#0) // application exists - let tmp%6#0: uint64 = (== value%4#0 1u) - (assert tmp%6#0) // expected global_num_uint - let (value%7#0: uint64, check%8#0: uint64) = ((app_params_get AppGlobalNumByteSlice) app#0) + block@0: // L37 + let tmp%0#0: bytes = (txn Sender) + let tmp%1#0: uint64 = (app_opted_in tmp%0#0 app#0) + let tmp%2#0: uint64 = (! tmp%1#0) + (assert tmp%2#0) // app opted in + let (value%3#0: bytes, check%4#0: uint64) = ((app_params_get AppCreator) app#0) + (assert check%4#0) // application exists + let tmp%5#0: bytes = (global CreatorAddress) + let tmp%6#0: uint64 = (== value%3#0 tmp%5#0) + (assert tmp%6#0) // expected creator + let (value%7#0: uint64, check%8#0: uint64) = ((app_params_get AppGlobalNumUint) app#0) (assert check%8#0) // application exists - let tmp%9#0: uint64 = (== value%7#0 2u) - (assert tmp%9#0) // expected global_num_byte_slice - let (value%10#0: uint64, check%11#0: uint64) = ((app_params_get AppLocalNumUint) app#0) + let tmp%9#0: uint64 = (== value%7#0 1u) + (assert tmp%9#0) // expected global_num_uint + let (value%10#0: uint64, check%11#0: uint64) = ((app_params_get AppGlobalNumByteSlice) app#0) (assert check%11#0) // application exists - let tmp%12#0: uint64 = (== value%10#0 3u) - (assert tmp%12#0) // expected local_num_uint - let (value%13#0: uint64, check%14#0: uint64) = ((app_params_get AppLocalNumByteSlice) app#0) + let tmp%12#0: uint64 = (== value%10#0 2u) + (assert tmp%12#0) // expected global_num_byte_slice + let (value%13#0: uint64, check%14#0: uint64) = ((app_params_get AppLocalNumUint) app#0) (assert check%14#0) // application exists - let tmp%15#0: uint64 = (== value%13#0 4u) - (assert tmp%15#0) // expected local_num_byte_slice - let (value%16#0: bytes, check%17#0: uint64) = ((app_params_get AppApprovalProgram) app#0) + let tmp%15#0: uint64 = (== value%13#0 3u) + (assert tmp%15#0) // expected local_num_uint + let (value%16#0: uint64, check%17#0: uint64) = ((app_params_get AppLocalNumByteSlice) app#0) (assert check%17#0) // application exists - let tmp%18#0: uint64 = (len value%16#0) - (assert tmp%18#0) // expected approval_program - let (value%19#0: bytes, check%20#0: uint64) = ((app_params_get AppClearStateProgram) app#0) + let tmp%18#0: uint64 = (== value%16#0 4u) + (assert tmp%18#0) // expected local_num_byte_slice + let (value%19#0: bytes, check%20#0: uint64) = ((app_params_get AppApprovalProgram) app#0) (assert check%20#0) // application exists let tmp%21#0: uint64 = (len value%19#0) - (assert tmp%21#0) // expected clear_state_program - let tmp%22#0: uint64 = (global CurrentApplicationID) - let tmp%23#0: uint64 = (== app#0 tmp%22#0) - (assert tmp%23#0) // expected current_application_id - let (value%24#0: bytes, check%25#0: uint64) = ((app_params_get AppAddress) app#0) - (assert check%25#0) // application exists - let tmp%26#0: bytes = (global CurrentApplicationAddress) - let tmp%27#0: uint64 = (== value%24#0 tmp%26#0) - (assert tmp%27#0) // expected current_application_address + (assert tmp%21#0) // expected approval_program + let (value%22#0: bytes, check%23#0: uint64) = ((app_params_get AppClearStateProgram) app#0) + (assert check%23#0) // application exists + let tmp%24#0: uint64 = (len value%22#0) + (assert tmp%24#0) // expected clear_state_program + let tmp%25#0: uint64 = (global CurrentApplicationID) + let tmp%26#0: uint64 = (== app#0 tmp%25#0) + (assert tmp%26#0) // expected current_application_id + let (value%27#0: bytes, check%28#0: uint64) = ((app_params_get AppAddress) app#0) + (assert check%28#0) // application exists + let tmp%29#0: bytes = (global CurrentApplicationAddress) + let tmp%30#0: uint64 = (== value%27#0 tmp%29#0) + (assert tmp%30#0) // expected current_application_address return subroutine test_cases.application.contract.Reference.__init__() -> void: - block@0: // L13 + block@0: // L14 (app_global_put "int_1" 0u) (app_global_put "bytes_1" "") (app_global_put "bytes_2" "") @@ -76,5 +80,5 @@ contract test_cases.application.contract.Reference: program clear-state: subroutine test_cases.application.contract.Reference.clear_state_program() -> uint64: - block@0: // L33 + block@0: // L34 return 1u \ No newline at end of file diff --git a/test_cases/application/out/Reference.ssa.opt_pass_1.ir b/test_cases/application/out/Reference.ssa.opt_pass_1.ir index 6f16f1b85e..50aae1bf4d 100644 --- a/test_cases/application/out/Reference.ssa.opt_pass_1.ir +++ b/test_cases/application/out/Reference.ssa.opt_pass_1.ir @@ -1,69 +1,73 @@ contract test_cases.application.contract.Reference: program approval: subroutine test_cases.application.contract.Reference.approval_program() -> uint64: - block@0: // L25 + block@0: // L26 let app_id%0#0: uint64 = (txn ApplicationID) goto app_id%0#0 ? block@2 : block@1 - block@1: // on_create_L13 + block@1: // on_create_L14 test_cases.application.contract.Reference.__init__() goto block@2 - block@2: // entrypoint_L13 + block@2: // entrypoint_L14 let tmp%1#0: uint64 = (txn NumAppArgs) let tmp%2#0: uint64 = (== tmp%1#0 1u) goto tmp%2#0 ? block@3 : block@7 - block@3: // if_body_L26 + block@3: // if_body_L27 let tmp%3#0: bytes = (txna ApplicationArgs 0) let tmp%4#0: uint64 = (== tmp%3#0 "validate") (assert tmp%4#0) // Expected validate let tmp%5#0: uint64 = (global CurrentApplicationID) test_cases.application.contract.Reference.validate_asset(tmp%5#0) goto block@7 - block@7: // after_if_else_L26 + block@7: // after_if_else_L27 return 1u subroutine test_cases.application.contract.Reference.validate_asset(app: uint64) -> void: - block@0: // L36 - let (value%0#0: bytes, check%1#0: uint64) = ((app_params_get AppCreator) app#0) - (assert check%1#0) // application exists - let tmp%2#0: bytes = (global CreatorAddress) - let tmp%3#0: uint64 = (== value%0#0 tmp%2#0) - (assert tmp%3#0) // expected creator - let (value%4#0: uint64, check%5#0: uint64) = ((app_params_get AppGlobalNumUint) app#0) - (assert check%5#0) // application exists - let tmp%6#0: uint64 = (== value%4#0 1u) - (assert tmp%6#0) // expected global_num_uint - let (value%7#0: uint64, check%8#0: uint64) = ((app_params_get AppGlobalNumByteSlice) app#0) + block@0: // L37 + let tmp%0#0: bytes = (txn Sender) + let tmp%1#0: uint64 = (app_opted_in tmp%0#0 app#0) + let tmp%2#0: uint64 = (! tmp%1#0) + (assert tmp%2#0) // app opted in + let (value%3#0: bytes, check%4#0: uint64) = ((app_params_get AppCreator) app#0) + (assert check%4#0) // application exists + let tmp%5#0: bytes = (global CreatorAddress) + let tmp%6#0: uint64 = (== value%3#0 tmp%5#0) + (assert tmp%6#0) // expected creator + let (value%7#0: uint64, check%8#0: uint64) = ((app_params_get AppGlobalNumUint) app#0) (assert check%8#0) // application exists - let tmp%9#0: uint64 = (== value%7#0 2u) - (assert tmp%9#0) // expected global_num_byte_slice - let (value%10#0: uint64, check%11#0: uint64) = ((app_params_get AppLocalNumUint) app#0) + let tmp%9#0: uint64 = (== value%7#0 1u) + (assert tmp%9#0) // expected global_num_uint + let (value%10#0: uint64, check%11#0: uint64) = ((app_params_get AppGlobalNumByteSlice) app#0) (assert check%11#0) // application exists - let tmp%12#0: uint64 = (== value%10#0 3u) - (assert tmp%12#0) // expected local_num_uint - let (value%13#0: uint64, check%14#0: uint64) = ((app_params_get AppLocalNumByteSlice) app#0) + let tmp%12#0: uint64 = (== value%10#0 2u) + (assert tmp%12#0) // expected global_num_byte_slice + let (value%13#0: uint64, check%14#0: uint64) = ((app_params_get AppLocalNumUint) app#0) (assert check%14#0) // application exists - let tmp%15#0: uint64 = (== value%13#0 4u) - (assert tmp%15#0) // expected local_num_byte_slice - let (value%16#0: bytes, check%17#0: uint64) = ((app_params_get AppApprovalProgram) app#0) + let tmp%15#0: uint64 = (== value%13#0 3u) + (assert tmp%15#0) // expected local_num_uint + let (value%16#0: uint64, check%17#0: uint64) = ((app_params_get AppLocalNumByteSlice) app#0) (assert check%17#0) // application exists - let tmp%18#0: uint64 = (len value%16#0) - (assert tmp%18#0) // expected approval_program - let (value%19#0: bytes, check%20#0: uint64) = ((app_params_get AppClearStateProgram) app#0) + let tmp%18#0: uint64 = (== value%16#0 4u) + (assert tmp%18#0) // expected local_num_byte_slice + let (value%19#0: bytes, check%20#0: uint64) = ((app_params_get AppApprovalProgram) app#0) (assert check%20#0) // application exists let tmp%21#0: uint64 = (len value%19#0) - (assert tmp%21#0) // expected clear_state_program - let tmp%22#0: uint64 = (global CurrentApplicationID) - let tmp%23#0: uint64 = (== app#0 tmp%22#0) - (assert tmp%23#0) // expected current_application_id - let (value%24#0: bytes, check%25#0: uint64) = ((app_params_get AppAddress) app#0) - (assert check%25#0) // application exists - let tmp%26#0: bytes = (global CurrentApplicationAddress) - let tmp%27#0: uint64 = (== value%24#0 tmp%26#0) - (assert tmp%27#0) // expected current_application_address + (assert tmp%21#0) // expected approval_program + let (value%22#0: bytes, check%23#0: uint64) = ((app_params_get AppClearStateProgram) app#0) + (assert check%23#0) // application exists + let tmp%24#0: uint64 = (len value%22#0) + (assert tmp%24#0) // expected clear_state_program + let tmp%25#0: uint64 = (global CurrentApplicationID) + let tmp%26#0: uint64 = (== app#0 tmp%25#0) + (assert tmp%26#0) // expected current_application_id + let (value%27#0: bytes, check%28#0: uint64) = ((app_params_get AppAddress) app#0) + (assert check%28#0) // application exists + let tmp%29#0: bytes = (global CurrentApplicationAddress) + let tmp%30#0: uint64 = (== value%27#0 tmp%29#0) + (assert tmp%30#0) // expected current_application_address return subroutine test_cases.application.contract.Reference.__init__() -> void: - block@0: // L13 + block@0: // L14 (app_global_put "int_1" 0u) (app_global_put "bytes_1" "") (app_global_put "bytes_2" "") @@ -71,5 +75,5 @@ contract test_cases.application.contract.Reference: program clear-state: subroutine test_cases.application.contract.Reference.clear_state_program() -> uint64: - block@0: // L33 + block@0: // L34 return 1u \ No newline at end of file diff --git a/test_cases/application/out/contract.awst b/test_cases/application/out/contract.awst index c80a849108..6f5707f45e 100644 --- a/test_cases/application/out/contract.awst +++ b/test_cases/application/out/contract.awst @@ -41,6 +41,7 @@ contract Reference subroutine validate_asset(app: puyapy.Application): None { + assert(!(app_opted_in(txn(), app)), comment="app opted in") assert(checked_maybe(app_params_get(app)) == global(), comment="expected creator") assert(checked_maybe(app_params_get(app)) == 1u, comment="expected global_num_uint") assert(checked_maybe(app_params_get(app)) == 2u, comment="expected global_num_byte_slice") diff --git a/test_cases/application/out_O2/Reference.approval.teal b/test_cases/application/out_O2/Reference.approval.teal index c9c16c2e9c..8320a9289d 100644 --- a/test_cases/application/out_O2/Reference.approval.teal +++ b/test_cases/application/out_O2/Reference.approval.teal @@ -25,6 +25,11 @@ main_after_if_else@7: // test_cases.application.contract.Reference.validate_asset(app: uint64) -> void: validate_asset: proto 1 0 + txn Sender + frame_dig -1 + app_opted_in + ! + assert // app opted in frame_dig -1 app_params_get AppCreator assert // application exists diff --git a/test_cases/application/out_O2/Reference.destructured.ir b/test_cases/application/out_O2/Reference.destructured.ir index 6f16f1b85e..50aae1bf4d 100644 --- a/test_cases/application/out_O2/Reference.destructured.ir +++ b/test_cases/application/out_O2/Reference.destructured.ir @@ -1,69 +1,73 @@ contract test_cases.application.contract.Reference: program approval: subroutine test_cases.application.contract.Reference.approval_program() -> uint64: - block@0: // L25 + block@0: // L26 let app_id%0#0: uint64 = (txn ApplicationID) goto app_id%0#0 ? block@2 : block@1 - block@1: // on_create_L13 + block@1: // on_create_L14 test_cases.application.contract.Reference.__init__() goto block@2 - block@2: // entrypoint_L13 + block@2: // entrypoint_L14 let tmp%1#0: uint64 = (txn NumAppArgs) let tmp%2#0: uint64 = (== tmp%1#0 1u) goto tmp%2#0 ? block@3 : block@7 - block@3: // if_body_L26 + block@3: // if_body_L27 let tmp%3#0: bytes = (txna ApplicationArgs 0) let tmp%4#0: uint64 = (== tmp%3#0 "validate") (assert tmp%4#0) // Expected validate let tmp%5#0: uint64 = (global CurrentApplicationID) test_cases.application.contract.Reference.validate_asset(tmp%5#0) goto block@7 - block@7: // after_if_else_L26 + block@7: // after_if_else_L27 return 1u subroutine test_cases.application.contract.Reference.validate_asset(app: uint64) -> void: - block@0: // L36 - let (value%0#0: bytes, check%1#0: uint64) = ((app_params_get AppCreator) app#0) - (assert check%1#0) // application exists - let tmp%2#0: bytes = (global CreatorAddress) - let tmp%3#0: uint64 = (== value%0#0 tmp%2#0) - (assert tmp%3#0) // expected creator - let (value%4#0: uint64, check%5#0: uint64) = ((app_params_get AppGlobalNumUint) app#0) - (assert check%5#0) // application exists - let tmp%6#0: uint64 = (== value%4#0 1u) - (assert tmp%6#0) // expected global_num_uint - let (value%7#0: uint64, check%8#0: uint64) = ((app_params_get AppGlobalNumByteSlice) app#0) + block@0: // L37 + let tmp%0#0: bytes = (txn Sender) + let tmp%1#0: uint64 = (app_opted_in tmp%0#0 app#0) + let tmp%2#0: uint64 = (! tmp%1#0) + (assert tmp%2#0) // app opted in + let (value%3#0: bytes, check%4#0: uint64) = ((app_params_get AppCreator) app#0) + (assert check%4#0) // application exists + let tmp%5#0: bytes = (global CreatorAddress) + let tmp%6#0: uint64 = (== value%3#0 tmp%5#0) + (assert tmp%6#0) // expected creator + let (value%7#0: uint64, check%8#0: uint64) = ((app_params_get AppGlobalNumUint) app#0) (assert check%8#0) // application exists - let tmp%9#0: uint64 = (== value%7#0 2u) - (assert tmp%9#0) // expected global_num_byte_slice - let (value%10#0: uint64, check%11#0: uint64) = ((app_params_get AppLocalNumUint) app#0) + let tmp%9#0: uint64 = (== value%7#0 1u) + (assert tmp%9#0) // expected global_num_uint + let (value%10#0: uint64, check%11#0: uint64) = ((app_params_get AppGlobalNumByteSlice) app#0) (assert check%11#0) // application exists - let tmp%12#0: uint64 = (== value%10#0 3u) - (assert tmp%12#0) // expected local_num_uint - let (value%13#0: uint64, check%14#0: uint64) = ((app_params_get AppLocalNumByteSlice) app#0) + let tmp%12#0: uint64 = (== value%10#0 2u) + (assert tmp%12#0) // expected global_num_byte_slice + let (value%13#0: uint64, check%14#0: uint64) = ((app_params_get AppLocalNumUint) app#0) (assert check%14#0) // application exists - let tmp%15#0: uint64 = (== value%13#0 4u) - (assert tmp%15#0) // expected local_num_byte_slice - let (value%16#0: bytes, check%17#0: uint64) = ((app_params_get AppApprovalProgram) app#0) + let tmp%15#0: uint64 = (== value%13#0 3u) + (assert tmp%15#0) // expected local_num_uint + let (value%16#0: uint64, check%17#0: uint64) = ((app_params_get AppLocalNumByteSlice) app#0) (assert check%17#0) // application exists - let tmp%18#0: uint64 = (len value%16#0) - (assert tmp%18#0) // expected approval_program - let (value%19#0: bytes, check%20#0: uint64) = ((app_params_get AppClearStateProgram) app#0) + let tmp%18#0: uint64 = (== value%16#0 4u) + (assert tmp%18#0) // expected local_num_byte_slice + let (value%19#0: bytes, check%20#0: uint64) = ((app_params_get AppApprovalProgram) app#0) (assert check%20#0) // application exists let tmp%21#0: uint64 = (len value%19#0) - (assert tmp%21#0) // expected clear_state_program - let tmp%22#0: uint64 = (global CurrentApplicationID) - let tmp%23#0: uint64 = (== app#0 tmp%22#0) - (assert tmp%23#0) // expected current_application_id - let (value%24#0: bytes, check%25#0: uint64) = ((app_params_get AppAddress) app#0) - (assert check%25#0) // application exists - let tmp%26#0: bytes = (global CurrentApplicationAddress) - let tmp%27#0: uint64 = (== value%24#0 tmp%26#0) - (assert tmp%27#0) // expected current_application_address + (assert tmp%21#0) // expected approval_program + let (value%22#0: bytes, check%23#0: uint64) = ((app_params_get AppClearStateProgram) app#0) + (assert check%23#0) // application exists + let tmp%24#0: uint64 = (len value%22#0) + (assert tmp%24#0) // expected clear_state_program + let tmp%25#0: uint64 = (global CurrentApplicationID) + let tmp%26#0: uint64 = (== app#0 tmp%25#0) + (assert tmp%26#0) // expected current_application_id + let (value%27#0: bytes, check%28#0: uint64) = ((app_params_get AppAddress) app#0) + (assert check%28#0) // application exists + let tmp%29#0: bytes = (global CurrentApplicationAddress) + let tmp%30#0: uint64 = (== value%27#0 tmp%29#0) + (assert tmp%30#0) // expected current_application_address return subroutine test_cases.application.contract.Reference.__init__() -> void: - block@0: // L13 + block@0: // L14 (app_global_put "int_1" 0u) (app_global_put "bytes_1" "") (app_global_put "bytes_2" "") @@ -71,5 +75,5 @@ contract test_cases.application.contract.Reference: program clear-state: subroutine test_cases.application.contract.Reference.clear_state_program() -> uint64: - block@0: // L33 + block@0: // L34 return 1u \ No newline at end of file diff --git a/test_cases/application/out_unoptimized/Reference.approval.teal b/test_cases/application/out_unoptimized/Reference.approval.teal index a24bff92aa..7c31e45e04 100644 --- a/test_cases/application/out_unoptimized/Reference.approval.teal +++ b/test_cases/application/out_unoptimized/Reference.approval.teal @@ -6,33 +6,33 @@ test_cases.application.contract.Reference.approval_program: callsub __init__ main_entrypoint@2: - // application/contract.py:26 + // application/contract.py:27 // if op.Txn.num_app_args == 1: txn NumAppArgs int 1 == bz main_after_if_else@7 - // application/contract.py:27 + // application/contract.py:28 // if op.Txn.application_args(0) == b"validate": txna ApplicationArgs 0 byte "validate" == bz main_else_body@5 - // application/contract.py:28 + // application/contract.py:29 // self.validate_asset(op.Global.current_application_id) global CurrentApplicationID callsub validate_asset b main_after_if_else@6 main_else_body@5: - // application/contract.py:30 + // application/contract.py:31 // assert False, "Expected validate" err // Expected validate main_after_if_else@6: main_after_if_else@7: - // application/contract.py:31 + // application/contract.py:32 // return True int 1 return @@ -40,11 +40,18 @@ main_after_if_else@7: // test_cases.application.contract.Reference.validate_asset(app: uint64) -> void: validate_asset: - // application/contract.py:36-37 + // application/contract.py:37-38 // @subroutine // def validate_asset(self, app: Application) -> None: proto 1 0 - // application/contract.py:38 + // application/contract.py:39 + // assert not Txn.sender.is_opted_in(app), "app opted in" + txn Sender + frame_dig -1 + app_opted_in + ! + assert // app opted in + // application/contract.py:40 // assert app.creator == op.Global.creator_address, "expected creator" frame_dig -1 app_params_get AppCreator @@ -52,7 +59,7 @@ validate_asset: global CreatorAddress == assert // expected creator - // application/contract.py:39 + // application/contract.py:41 // assert app.global_num_uint == 1, "expected global_num_uint" frame_dig -1 app_params_get AppGlobalNumUint @@ -60,7 +67,7 @@ validate_asset: int 1 == assert // expected global_num_uint - // application/contract.py:40 + // application/contract.py:42 // assert app.global_num_byte_slice == 2, "expected global_num_byte_slice" frame_dig -1 app_params_get AppGlobalNumByteSlice @@ -68,7 +75,7 @@ validate_asset: int 2 == assert // expected global_num_byte_slice - // application/contract.py:41 + // application/contract.py:43 // assert app.local_num_uint == 3, "expected local_num_uint" frame_dig -1 app_params_get AppLocalNumUint @@ -76,7 +83,7 @@ validate_asset: int 3 == assert // expected local_num_uint - // application/contract.py:42 + // application/contract.py:44 // assert app.local_num_byte_slice == 4, "expected local_num_byte_slice" frame_dig -1 app_params_get AppLocalNumByteSlice @@ -84,35 +91,35 @@ validate_asset: int 4 == assert // expected local_num_byte_slice - // application/contract.py:43 + // application/contract.py:45 // assert app.approval_program, "expected approval_program" frame_dig -1 app_params_get AppApprovalProgram assert // application exists len assert // expected approval_program - // application/contract.py:44 + // application/contract.py:46 // assert app.clear_state_program, "expected clear_state_program" frame_dig -1 app_params_get AppClearStateProgram assert // application exists len assert // expected clear_state_program - // application/contract.py:45 + // application/contract.py:47 // assert app == op.Global.current_application_id, "expected current_application_id" global CurrentApplicationID frame_dig -1 swap == assert // expected current_application_id - // application/contract.py:47 + // application/contract.py:49 // app.address == op.Global.current_application_address frame_dig -1 app_params_get AppAddress assert // application exists global CurrentApplicationAddress == - // application/contract.py:46-48 + // application/contract.py:48-50 // assert ( // app.address == op.Global.current_application_address // ), "expected current_application_address" @@ -122,20 +129,20 @@ validate_asset: // test_cases.application.contract.Reference.__init__() -> void: __init__: - // application/contract.py:13 + // application/contract.py:14 // def __init__(self) -> None: proto 0 0 - // application/contract.py:14 + // application/contract.py:15 // self.int_1 = UInt64(0) byte "int_1" int 0 app_global_put - // application/contract.py:15 + // application/contract.py:16 // self.bytes_1 = Bytes(b"") byte "bytes_1" byte "" app_global_put - // application/contract.py:16 + // application/contract.py:17 // self.bytes_2 = Bytes(b"") byte "bytes_2" byte "" diff --git a/test_cases/application/out_unoptimized/Reference.clear.teal b/test_cases/application/out_unoptimized/Reference.clear.teal index 427e20bb57..68733d388f 100644 --- a/test_cases/application/out_unoptimized/Reference.clear.teal +++ b/test_cases/application/out_unoptimized/Reference.clear.teal @@ -1,7 +1,7 @@ #pragma version 10 test_cases.application.contract.Reference.clear_state_program: - // application/contract.py:34 + // application/contract.py:35 // return True int 1 return diff --git a/test_cases/application/out_unoptimized/Reference.destructured.ir b/test_cases/application/out_unoptimized/Reference.destructured.ir index eb1e8acbe0..9410d3ae21 100644 --- a/test_cases/application/out_unoptimized/Reference.destructured.ir +++ b/test_cases/application/out_unoptimized/Reference.destructured.ir @@ -1,74 +1,78 @@ contract test_cases.application.contract.Reference: program approval: subroutine test_cases.application.contract.Reference.approval_program() -> uint64: - block@0: // L25 + block@0: // L26 let app_id%0#0: uint64 = (txn ApplicationID) goto app_id%0#0 ? block@2 : block@1 - block@1: // on_create_L13 + block@1: // on_create_L14 test_cases.application.contract.Reference.__init__() goto block@2 - block@2: // entrypoint_L13 + block@2: // entrypoint_L14 let tmp%1#0: uint64 = (txn NumAppArgs) let tmp%2#0: uint64 = (== tmp%1#0 1u) goto tmp%2#0 ? block@3 : block@7 - block@3: // if_body_L26 + block@3: // if_body_L27 let tmp%3#0: bytes = (txna ApplicationArgs 0) let tmp%4#0: uint64 = (== tmp%3#0 "validate") goto tmp%4#0 ? block@4 : block@5 - block@4: // if_body_L27 + block@4: // if_body_L28 let tmp%5#0: uint64 = (global CurrentApplicationID) test_cases.application.contract.Reference.validate_asset(tmp%5#0) goto block@6 - block@5: // else_body_L27 + block@5: // else_body_L28 fail // Expected validate - block@6: // after_if_else_L27 + block@6: // after_if_else_L28 goto block@7 - block@7: // after_if_else_L26 + block@7: // after_if_else_L27 return 1u subroutine test_cases.application.contract.Reference.validate_asset(app: uint64) -> void: - block@0: // L36 - let (value%0#0: bytes, check%1#0: uint64) = ((app_params_get AppCreator) app#0) - (assert check%1#0) // application exists - let tmp%2#0: bytes = (global CreatorAddress) - let tmp%3#0: uint64 = (== value%0#0 tmp%2#0) - (assert tmp%3#0) // expected creator - let (value%4#0: uint64, check%5#0: uint64) = ((app_params_get AppGlobalNumUint) app#0) - (assert check%5#0) // application exists - let tmp%6#0: uint64 = (== value%4#0 1u) - (assert tmp%6#0) // expected global_num_uint - let (value%7#0: uint64, check%8#0: uint64) = ((app_params_get AppGlobalNumByteSlice) app#0) + block@0: // L37 + let tmp%0#0: bytes = (txn Sender) + let tmp%1#0: uint64 = (app_opted_in tmp%0#0 app#0) + let tmp%2#0: uint64 = (! tmp%1#0) + (assert tmp%2#0) // app opted in + let (value%3#0: bytes, check%4#0: uint64) = ((app_params_get AppCreator) app#0) + (assert check%4#0) // application exists + let tmp%5#0: bytes = (global CreatorAddress) + let tmp%6#0: uint64 = (== value%3#0 tmp%5#0) + (assert tmp%6#0) // expected creator + let (value%7#0: uint64, check%8#0: uint64) = ((app_params_get AppGlobalNumUint) app#0) (assert check%8#0) // application exists - let tmp%9#0: uint64 = (== value%7#0 2u) - (assert tmp%9#0) // expected global_num_byte_slice - let (value%10#0: uint64, check%11#0: uint64) = ((app_params_get AppLocalNumUint) app#0) + let tmp%9#0: uint64 = (== value%7#0 1u) + (assert tmp%9#0) // expected global_num_uint + let (value%10#0: uint64, check%11#0: uint64) = ((app_params_get AppGlobalNumByteSlice) app#0) (assert check%11#0) // application exists - let tmp%12#0: uint64 = (== value%10#0 3u) - (assert tmp%12#0) // expected local_num_uint - let (value%13#0: uint64, check%14#0: uint64) = ((app_params_get AppLocalNumByteSlice) app#0) + let tmp%12#0: uint64 = (== value%10#0 2u) + (assert tmp%12#0) // expected global_num_byte_slice + let (value%13#0: uint64, check%14#0: uint64) = ((app_params_get AppLocalNumUint) app#0) (assert check%14#0) // application exists - let tmp%15#0: uint64 = (== value%13#0 4u) - (assert tmp%15#0) // expected local_num_byte_slice - let (value%16#0: bytes, check%17#0: uint64) = ((app_params_get AppApprovalProgram) app#0) + let tmp%15#0: uint64 = (== value%13#0 3u) + (assert tmp%15#0) // expected local_num_uint + let (value%16#0: uint64, check%17#0: uint64) = ((app_params_get AppLocalNumByteSlice) app#0) (assert check%17#0) // application exists - let tmp%18#0: uint64 = (len value%16#0) - (assert tmp%18#0) // expected approval_program - let (value%19#0: bytes, check%20#0: uint64) = ((app_params_get AppClearStateProgram) app#0) + let tmp%18#0: uint64 = (== value%16#0 4u) + (assert tmp%18#0) // expected local_num_byte_slice + let (value%19#0: bytes, check%20#0: uint64) = ((app_params_get AppApprovalProgram) app#0) (assert check%20#0) // application exists let tmp%21#0: uint64 = (len value%19#0) - (assert tmp%21#0) // expected clear_state_program - let tmp%22#0: uint64 = (global CurrentApplicationID) - let tmp%23#0: uint64 = (== app#0 tmp%22#0) - (assert tmp%23#0) // expected current_application_id - let (value%24#0: bytes, check%25#0: uint64) = ((app_params_get AppAddress) app#0) - (assert check%25#0) // application exists - let tmp%26#0: bytes = (global CurrentApplicationAddress) - let tmp%27#0: uint64 = (== value%24#0 tmp%26#0) - (assert tmp%27#0) // expected current_application_address + (assert tmp%21#0) // expected approval_program + let (value%22#0: bytes, check%23#0: uint64) = ((app_params_get AppClearStateProgram) app#0) + (assert check%23#0) // application exists + let tmp%24#0: uint64 = (len value%22#0) + (assert tmp%24#0) // expected clear_state_program + let tmp%25#0: uint64 = (global CurrentApplicationID) + let tmp%26#0: uint64 = (== app#0 tmp%25#0) + (assert tmp%26#0) // expected current_application_id + let (value%27#0: bytes, check%28#0: uint64) = ((app_params_get AppAddress) app#0) + (assert check%28#0) // application exists + let tmp%29#0: bytes = (global CurrentApplicationAddress) + let tmp%30#0: uint64 = (== value%27#0 tmp%29#0) + (assert tmp%30#0) // expected current_application_address return subroutine test_cases.application.contract.Reference.__init__() -> void: - block@0: // L13 + block@0: // L14 (app_global_put "int_1" 0u) (app_global_put "bytes_1" "") (app_global_put "bytes_2" "") @@ -76,5 +80,5 @@ contract test_cases.application.contract.Reference: program clear-state: subroutine test_cases.application.contract.Reference.clear_state_program() -> uint64: - block@0: // L33 + block@0: // L34 return 1u \ No newline at end of file diff --git a/test_cases/application/puya.log b/test_cases/application/puya.log index 074937b69e..6d416df5b7 100644 --- a/test_cases/application/puya.log +++ b/test_cases/application/puya.log @@ -285,29 +285,29 @@ debug: Deleting Phi assignment: let sequence#1: bytes = φ(sequence#0 <- block@0 debug: Replaced trivial Phi node: let sequence#1: bytes = φ(sequence#0 <- block@0, sequence#1 <- block@4) (sequence#1) with sequence#0 in current definition for 3 blocks debug: Sealing block@None: // after_while_L11 debug: Terminated block@5: // after_while_L11 -debug: Sealing block@0: // L36 -debug: Terminated block@0: // L36 -debug: Sealing block@0: // L13 -debug: Terminated block@0: // L13 -debug: Sealing block@0: // L25 -debug: Terminated block@0: // L25 -debug: Sealing block@None: // on_create_L13 -debug: Terminated block@1: // on_create_L13 -debug: Sealing block@2: // entrypoint_L13 -debug: Terminated block@2: // entrypoint_L13 -debug: Sealing block@None: // if_body_L26 -debug: Sealing block@None: // else_body_L26 -debug: Terminated block@3: // if_body_L26 +debug: Sealing block@0: // L37 +debug: Terminated block@0: // L37 +debug: Sealing block@0: // L14 +debug: Terminated block@0: // L14 +debug: Sealing block@0: // L26 +debug: Terminated block@0: // L26 +debug: Sealing block@None: // on_create_L14 +debug: Terminated block@1: // on_create_L14 +debug: Sealing block@2: // entrypoint_L14 +debug: Terminated block@2: // entrypoint_L14 debug: Sealing block@None: // if_body_L27 debug: Sealing block@None: // else_body_L27 -debug: Terminated block@4: // if_body_L27 -debug: Terminated block@5: // else_body_L27 -debug: Sealing block@6: // after_if_else_L27 -debug: Terminated block@6: // after_if_else_L27 -debug: Sealing block@7: // after_if_else_L26 -debug: Terminated block@7: // after_if_else_L26 -debug: Sealing block@0: // L33 -debug: Terminated block@0: // L33 +debug: Terminated block@3: // if_body_L27 +debug: Sealing block@None: // if_body_L28 +debug: Sealing block@None: // else_body_L28 +debug: Terminated block@4: // if_body_L28 +debug: Terminated block@5: // else_body_L28 +debug: Sealing block@6: // after_if_else_L28 +debug: Terminated block@6: // after_if_else_L28 +debug: Sealing block@7: // after_if_else_L27 +debug: Terminated block@7: // after_if_else_L27 +debug: Sealing block@0: // L34 +debug: Terminated block@0: // L34 debug: Output IR to application/out/Reference.ssa.ir info: Optimizing test_cases.application.contract.Reference at level 1 debug: Begin optimization pass 1/100 @@ -319,15 +319,15 @@ debug: Optimizer: Intrinsic Simplifier debug: Optimizer: Remove Unused Variables debug: Optimizer: Simplify Control Ops debug: inlining condition branch to err block into an assert true -debug: simplified terminator of block@3: // if_body_L26 from goto tmp%4#0 ? block@4 : block@5 to goto block@4 +debug: simplified terminator of block@3: // if_body_L27 from goto tmp%4#0 ? block@4 : block@5 to goto block@4 debug: Optimizer: Remove Linear Jump -debug: Replaced predecessor block@4: // if_body_L27 with block@3: // if_body_L26 in block@6: // after_if_else_L27 -debug: Merged linear block@4: // if_body_L27 into block@3: // if_body_L26 -debug: Replaced predecessor block@6: // after_if_else_L27 with block@3: // if_body_L26 in block@7: // after_if_else_L26 -debug: Merged linear block@6: // after_if_else_L27 into block@3: // if_body_L26 +debug: Replaced predecessor block@4: // if_body_L28 with block@3: // if_body_L27 in block@6: // after_if_else_L28 +debug: Merged linear block@4: // if_body_L28 into block@3: // if_body_L27 +debug: Replaced predecessor block@6: // after_if_else_L28 with block@3: // if_body_L27 in block@7: // after_if_else_L27 +debug: Merged linear block@6: // after_if_else_L28 into block@3: // if_body_L27 debug: Optimizer: Remove Empty Blocks debug: Optimizer: Remove Unreachable Blocks -debug: Removing unreachable blocks: block@5: // else_body_L27 +debug: Removing unreachable blocks: block@5: // else_body_L28 debug: Optimizer: Repeated Expression Elimination debug: Optimizing subroutine test_cases.application.contract.Reference.validate_asset debug: Splitting parallel copies prior to optimization @@ -436,30 +436,34 @@ debug: Replaced main_if_body@3.ops[8]: 'load tmp%4#0' with 'load tmp%4#0 from l- debug: Inserted main_if_body@3.ops[11]: 'store tmp%5#0 to l-stack (copy)' debug: Replaced main_if_body@3.ops[13]: 'load tmp%5#0' with 'load tmp%5#0 from l-stack (no copy)' debug: Found 2 edge set/s for test_cases.application.contract.Reference.approval_program -debug: Inserted validate_asset_block@0.ops[11]: 'store tmp%3#0 to l-stack (copy)' -debug: Replaced validate_asset_block@0.ops[13]: 'load tmp%3#0' with 'load tmp%3#0 from l-stack (no copy)' -debug: Inserted validate_asset_block@0.ops[24]: 'store tmp%6#0 to l-stack (copy)' -debug: Replaced validate_asset_block@0.ops[26]: 'load tmp%6#0' with 'load tmp%6#0 from l-stack (no copy)' -debug: Inserted validate_asset_block@0.ops[37]: 'store tmp%9#0 to l-stack (copy)' -debug: Replaced validate_asset_block@0.ops[39]: 'load tmp%9#0' with 'load tmp%9#0 from l-stack (no copy)' -debug: Inserted validate_asset_block@0.ops[50]: 'store tmp%12#0 to l-stack (copy)' -debug: Replaced validate_asset_block@0.ops[52]: 'load tmp%12#0' with 'load tmp%12#0 from l-stack (no copy)' -debug: Inserted validate_asset_block@0.ops[63]: 'store tmp%15#0 to l-stack (copy)' -debug: Replaced validate_asset_block@0.ops[65]: 'load tmp%15#0' with 'load tmp%15#0 from l-stack (no copy)' -debug: Inserted validate_asset_block@0.ops[75]: 'store tmp%18#0 to l-stack (copy)' -debug: Replaced validate_asset_block@0.ops[77]: 'load tmp%18#0' with 'load tmp%18#0 from l-stack (no copy)' -debug: Inserted validate_asset_block@0.ops[87]: 'store tmp%21#0 to l-stack (copy)' -debug: Replaced validate_asset_block@0.ops[89]: 'load tmp%21#0' with 'load tmp%21#0 from l-stack (no copy)' -debug: Inserted validate_asset_block@0.ops[96]: 'store tmp%23#0 to l-stack (copy)' -debug: Replaced validate_asset_block@0.ops[98]: 'load tmp%23#0' with 'load tmp%23#0 from l-stack (no copy)' -debug: Inserted validate_asset_block@0.ops[111]: 'store tmp%27#0 to l-stack (copy)' -debug: Replaced validate_asset_block@0.ops[113]: 'load tmp%27#0' with 'load tmp%27#0 from l-stack (no copy)' -debug: Inserted validate_asset_block@0.ops[2]: 'store check%1#0 to l-stack (copy)' -debug: Replaced validate_asset_block@0.ops[5]: 'load check%1#0' with 'load check%1#0 from l-stack (no copy)' -debug: Inserted validate_asset_block@0.ops[8]: 'store tmp%2#0 to l-stack (copy)' -debug: Replaced validate_asset_block@0.ops[11]: 'load tmp%2#0' with 'load tmp%2#0 from l-stack (no copy)' -debug: Inserted validate_asset_block@0.ops[19]: 'store check%5#0 to l-stack (copy)' -debug: Replaced validate_asset_block@0.ops[22]: 'load check%5#0' with 'load check%5#0 from l-stack (no copy)' +debug: Inserted validate_asset_block@0.ops[1]: 'store tmp%0#0 to l-stack (copy)' +debug: Replaced validate_asset_block@0.ops[3]: 'load tmp%0#0' with 'load tmp%0#0 from l-stack (no copy)' +debug: Inserted validate_asset_block@0.ops[6]: 'store tmp%1#0 to l-stack (copy)' +debug: Replaced validate_asset_block@0.ops[8]: 'load tmp%1#0' with 'load tmp%1#0 from l-stack (no copy)' +debug: Inserted validate_asset_block@0.ops[10]: 'store tmp%2#0 to l-stack (copy)' +debug: Replaced validate_asset_block@0.ops[12]: 'load tmp%2#0' with 'load tmp%2#0 from l-stack (no copy)' +debug: Inserted validate_asset_block@0.ops[25]: 'store tmp%6#0 to l-stack (copy)' +debug: Replaced validate_asset_block@0.ops[27]: 'load tmp%6#0' with 'load tmp%6#0 from l-stack (no copy)' +debug: Inserted validate_asset_block@0.ops[38]: 'store tmp%9#0 to l-stack (copy)' +debug: Replaced validate_asset_block@0.ops[40]: 'load tmp%9#0' with 'load tmp%9#0 from l-stack (no copy)' +debug: Inserted validate_asset_block@0.ops[51]: 'store tmp%12#0 to l-stack (copy)' +debug: Replaced validate_asset_block@0.ops[53]: 'load tmp%12#0' with 'load tmp%12#0 from l-stack (no copy)' +debug: Inserted validate_asset_block@0.ops[64]: 'store tmp%15#0 to l-stack (copy)' +debug: Replaced validate_asset_block@0.ops[66]: 'load tmp%15#0' with 'load tmp%15#0 from l-stack (no copy)' +debug: Inserted validate_asset_block@0.ops[77]: 'store tmp%18#0 to l-stack (copy)' +debug: Replaced validate_asset_block@0.ops[79]: 'load tmp%18#0' with 'load tmp%18#0 from l-stack (no copy)' +debug: Inserted validate_asset_block@0.ops[89]: 'store tmp%21#0 to l-stack (copy)' +debug: Replaced validate_asset_block@0.ops[91]: 'load tmp%21#0' with 'load tmp%21#0 from l-stack (no copy)' +debug: Inserted validate_asset_block@0.ops[101]: 'store tmp%24#0 to l-stack (copy)' +debug: Replaced validate_asset_block@0.ops[103]: 'load tmp%24#0' with 'load tmp%24#0 from l-stack (no copy)' +debug: Inserted validate_asset_block@0.ops[110]: 'store tmp%26#0 to l-stack (copy)' +debug: Replaced validate_asset_block@0.ops[112]: 'load tmp%26#0' with 'load tmp%26#0 from l-stack (no copy)' +debug: Inserted validate_asset_block@0.ops[125]: 'store tmp%30#0 to l-stack (copy)' +debug: Replaced validate_asset_block@0.ops[127]: 'load tmp%30#0' with 'load tmp%30#0 from l-stack (no copy)' +debug: Inserted validate_asset_block@0.ops[16]: 'store check%4#0 to l-stack (copy)' +debug: Replaced validate_asset_block@0.ops[19]: 'load check%4#0' with 'load check%4#0 from l-stack (no copy)' +debug: Inserted validate_asset_block@0.ops[22]: 'store tmp%5#0 to l-stack (copy)' +debug: Replaced validate_asset_block@0.ops[25]: 'load tmp%5#0' with 'load tmp%5#0 from l-stack (no copy)' debug: Inserted validate_asset_block@0.ops[33]: 'store check%8#0 to l-stack (copy)' debug: Replaced validate_asset_block@0.ops[36]: 'load check%8#0' with 'load check%8#0 from l-stack (no copy)' debug: Inserted validate_asset_block@0.ops[47]: 'store check%11#0 to l-stack (copy)' @@ -468,29 +472,31 @@ debug: Inserted validate_asset_block@0.ops[61]: 'store check%14#0 to l-stack (co debug: Replaced validate_asset_block@0.ops[64]: 'load check%14#0' with 'load check%14#0 from l-stack (no copy)' debug: Inserted validate_asset_block@0.ops[75]: 'store check%17#0 to l-stack (copy)' debug: Replaced validate_asset_block@0.ops[78]: 'load check%17#0' with 'load check%17#0 from l-stack (no copy)' -debug: Inserted validate_asset_block@0.ops[88]: 'store check%20#0 to l-stack (copy)' -debug: Replaced validate_asset_block@0.ops[91]: 'load check%20#0' with 'load check%20#0 from l-stack (no copy)' -debug: Inserted validate_asset_block@0.ops[100]: 'store tmp%22#0 to l-stack (copy)' -debug: Replaced validate_asset_block@0.ops[103]: 'load tmp%22#0' with 'load tmp%22#0 from l-stack (no copy)' -debug: Inserted validate_asset_block@0.ops[111]: 'store check%25#0 to l-stack (copy)' -debug: Replaced validate_asset_block@0.ops[114]: 'load check%25#0' with 'load check%25#0 from l-stack (no copy)' -debug: Inserted validate_asset_block@0.ops[117]: 'store tmp%26#0 to l-stack (copy)' -debug: Replaced validate_asset_block@0.ops[120]: 'load tmp%26#0' with 'load tmp%26#0 from l-stack (no copy)' -debug: Inserted validate_asset_block@0.ops[21]: 'store value%4#0 to l-stack (copy)' -debug: Replaced validate_asset_block@0.ops[25]: 'load value%4#0' with 'load value%4#0 from l-stack (no copy)' -debug: Inserted validate_asset_block@0.ops[36]: 'store value%7#0 to l-stack (copy)' -debug: Replaced validate_asset_block@0.ops[40]: 'load value%7#0' with 'load value%7#0 from l-stack (no copy)' -debug: Inserted validate_asset_block@0.ops[51]: 'store value%10#0 to l-stack (copy)' -debug: Replaced validate_asset_block@0.ops[55]: 'load value%10#0' with 'load value%10#0 from l-stack (no copy)' -debug: Inserted validate_asset_block@0.ops[66]: 'store value%13#0 to l-stack (copy)' -debug: Replaced validate_asset_block@0.ops[70]: 'load value%13#0' with 'load value%13#0 from l-stack (no copy)' -debug: Inserted validate_asset_block@0.ops[81]: 'store value%16#0 to l-stack (copy)' -debug: Replaced validate_asset_block@0.ops[85]: 'load value%16#0' with 'load value%16#0 from l-stack (no copy)' +debug: Inserted validate_asset_block@0.ops[89]: 'store check%20#0 to l-stack (copy)' +debug: Replaced validate_asset_block@0.ops[92]: 'load check%20#0' with 'load check%20#0 from l-stack (no copy)' +debug: Inserted validate_asset_block@0.ops[102]: 'store check%23#0 to l-stack (copy)' +debug: Replaced validate_asset_block@0.ops[105]: 'load check%23#0' with 'load check%23#0 from l-stack (no copy)' +debug: Inserted validate_asset_block@0.ops[114]: 'store tmp%25#0 to l-stack (copy)' +debug: Replaced validate_asset_block@0.ops[117]: 'load tmp%25#0' with 'load tmp%25#0 from l-stack (no copy)' +debug: Inserted validate_asset_block@0.ops[125]: 'store check%28#0 to l-stack (copy)' +debug: Replaced validate_asset_block@0.ops[128]: 'load check%28#0' with 'load check%28#0 from l-stack (no copy)' +debug: Inserted validate_asset_block@0.ops[131]: 'store tmp%29#0 to l-stack (copy)' +debug: Replaced validate_asset_block@0.ops[134]: 'load tmp%29#0' with 'load tmp%29#0 from l-stack (no copy)' +debug: Inserted validate_asset_block@0.ops[35]: 'store value%7#0 to l-stack (copy)' +debug: Replaced validate_asset_block@0.ops[39]: 'load value%7#0' with 'load value%7#0 from l-stack (no copy)' +debug: Inserted validate_asset_block@0.ops[50]: 'store value%10#0 to l-stack (copy)' +debug: Replaced validate_asset_block@0.ops[54]: 'load value%10#0' with 'load value%10#0 from l-stack (no copy)' +debug: Inserted validate_asset_block@0.ops[65]: 'store value%13#0 to l-stack (copy)' +debug: Replaced validate_asset_block@0.ops[69]: 'load value%13#0' with 'load value%13#0 from l-stack (no copy)' +debug: Inserted validate_asset_block@0.ops[80]: 'store value%16#0 to l-stack (copy)' +debug: Replaced validate_asset_block@0.ops[84]: 'load value%16#0' with 'load value%16#0 from l-stack (no copy)' debug: Inserted validate_asset_block@0.ops[95]: 'store value%19#0 to l-stack (copy)' debug: Replaced validate_asset_block@0.ops[99]: 'load value%19#0' with 'load value%19#0 from l-stack (no copy)' -debug: Inserted validate_asset_block@0.ops[4]: 'store value%0#0 to l-stack (copy)' -debug: Replaced validate_asset_block@0.ops[11]: 'load value%0#0' with 'load value%0#0 from l-stack (no copy)' -debug: Inserted validate_asset_block@0.ops[120]: 'store value%24#0 to l-stack (copy)' -debug: Replaced validate_asset_block@0.ops[127]: 'load value%24#0' with 'load value%24#0 from l-stack (no copy)' +debug: Inserted validate_asset_block@0.ops[109]: 'store value%22#0 to l-stack (copy)' +debug: Replaced validate_asset_block@0.ops[113]: 'load value%22#0' with 'load value%22#0 from l-stack (no copy)' +debug: Inserted validate_asset_block@0.ops[18]: 'store value%3#0 to l-stack (copy)' +debug: Replaced validate_asset_block@0.ops[25]: 'load value%3#0' with 'load value%3#0 from l-stack (no copy)' +debug: Inserted validate_asset_block@0.ops[134]: 'store value%27#0 to l-stack (copy)' +debug: Replaced validate_asset_block@0.ops[141]: 'load value%27#0' with 'load value%27#0 from l-stack (no copy)' info: Writing application/out/Reference.approval.teal info: Writing application/out/Reference.clear.teal \ No newline at end of file diff --git a/test_cases/asset/contract.py b/test_cases/asset/contract.py index 781d41bf63..036664d208 100644 --- a/test_cases/asset/contract.py +++ b/test_cases/asset/contract.py @@ -64,3 +64,4 @@ def is_opted_asset(self, asset: Asset) -> None: assert asset.freeze == Global.zero_address, "freeze" assert asset.clawback == Global.zero_address, "clawback" assert asset.creator == Global.creator_address, "creator" + assert Global.current_application_address.is_opted_in(asset), "asset opted in" diff --git a/test_cases/asset/out/Reference.approval.mir b/test_cases/asset/out/Reference.approval.mir index 3024509298..e53bb0458a 100644 --- a/test_cases/asset/out/Reference.approval.mir +++ b/test_cases/asset/out/Reference.approval.mir @@ -281,6 +281,15 @@ is_opted_asset_block@0: // virtual: store tmp%44#0 to l-stack (no copy) (𝕡) asset#0 | tmp%44#0 asset.creator == Global.creator_address, "creator" asset/contract.py:66 // virtual: load tmp%44#0 from l-stack (no copy) (𝕡) asset#0 | tmp%44#0 assert asset.creator == Global.creator_address, "creator" asset/contract.py:66 assert // creator // (𝕡) asset#0 | assert asset.creator == Global.creator_address, "creator" asset/contract.py:66 + global CurrentApplicationAddress // (𝕡) asset#0 | {global} Global.current_application_address asset/contract.py:67 + // virtual: store tmp%45#0 to l-stack (no copy) (𝕡) asset#0 | tmp%45#0 Global.current_application_address asset/contract.py:67 + // virtual: load tmp%45#0 from l-stack (no copy) (𝕡) asset#0 | tmp%45#0 Global.current_application_address.is_opted_in(asset) asset/contract.py:67 + frame_dig -1 // load asset#0 from parameters (𝕡) asset#0 | tmp%45#0,asset#0 Global.current_application_address.is_opted_in(asset) asset/contract.py:67 + asset_holding_get AssetBalance // (𝕡) asset#0 | {asset_holding_get}.0,{asset_holding_get}.1 Global.current_application_address.is_opted_in(asset) asset/contract.py:67 + swap // store tmp%47#0 to l-stack (no copy) (𝕡) asset#0 | tmp%47#0,{asset_holding_get}.0 Global.current_application_address.is_opted_in(asset) asset/contract.py:67 + pop // (𝕡) asset#0 | tmp%47#0 Global.current_application_address.is_opted_in(asset) asset/contract.py:67 + // virtual: load tmp%47#0 from l-stack (no copy) (𝕡) asset#0 | tmp%47#0 assert Global.current_application_address.is_opted_in(asset), "asset opted in" asset/contract.py:67 + assert // asset opted in // (𝕡) asset#0 | assert Global.current_application_address.is_opted_in(asset), "asset opted in" asset/contract.py:67 retsub // diff --git a/test_cases/asset/out/Reference.approval.teal b/test_cases/asset/out/Reference.approval.teal index a2dc3e4ee1..83af0b6bc3 100644 --- a/test_cases/asset/out/Reference.approval.teal +++ b/test_cases/asset/out/Reference.approval.teal @@ -211,6 +211,13 @@ is_opted_asset: global CreatorAddress == assert // creator + // asset/contract.py:67 + // assert Global.current_application_address.is_opted_in(asset), "asset opted in" + global CurrentApplicationAddress + frame_dig -1 + asset_holding_get AssetBalance + bury 1 + assert // asset opted in retsub diff --git a/test_cases/asset/out/Reference.destructured.ir b/test_cases/asset/out/Reference.destructured.ir index 070d96b332..dc63fdfe9e 100644 --- a/test_cases/asset/out/Reference.destructured.ir +++ b/test_cases/asset/out/Reference.destructured.ir @@ -109,6 +109,9 @@ contract test_cases.asset.contract.Reference: let tmp%43#0: bytes = (global CreatorAddress) let tmp%44#0: uint64 = (== value%41#0 tmp%43#0) (assert tmp%44#0) // creator + let tmp%45#0: bytes = (global CurrentApplicationAddress) + let (tmp%46#0: uint64, tmp%47#0: uint64) = ((asset_holding_get AssetBalance) tmp%45#0 asset#0) + (assert tmp%47#0) // asset opted in return subroutine test_cases.asset.contract.Reference.__init__() -> void: diff --git a/test_cases/asset/out/Reference.ssa.ir b/test_cases/asset/out/Reference.ssa.ir index 6ed685d7ab..c1a44c1ff9 100644 --- a/test_cases/asset/out/Reference.ssa.ir +++ b/test_cases/asset/out/Reference.ssa.ir @@ -116,6 +116,9 @@ contract test_cases.asset.contract.Reference: let tmp%43#0: bytes = (global CreatorAddress) let tmp%44#0: uint64 = (== value%41#0 tmp%43#0) (assert tmp%44#0) // creator + let tmp%45#0: bytes = (global CurrentApplicationAddress) + let (tmp%46#0: uint64, tmp%47#0: uint64) = ((asset_holding_get AssetBalance) tmp%45#0 asset#0) + (assert tmp%47#0) // asset opted in return subroutine test_cases.asset.contract.Reference.__init__() -> void: diff --git a/test_cases/asset/out/Reference.ssa.opt_pass_1.ir b/test_cases/asset/out/Reference.ssa.opt_pass_1.ir index e486a07d89..774d97fe7c 100644 --- a/test_cases/asset/out/Reference.ssa.opt_pass_1.ir +++ b/test_cases/asset/out/Reference.ssa.opt_pass_1.ir @@ -109,6 +109,9 @@ contract test_cases.asset.contract.Reference: let tmp%43#0: bytes = (global CreatorAddress) let tmp%44#0: uint64 = (== value%41#0 tmp%43#0) (assert tmp%44#0) // creator + let tmp%45#0: bytes = (global CurrentApplicationAddress) + let (tmp%46#0: uint64, tmp%47#0: uint64) = ((asset_holding_get AssetBalance) tmp%45#0 asset#0) + (assert tmp%47#0) // asset opted in return subroutine test_cases.asset.contract.Reference.__init__() -> void: diff --git a/test_cases/asset/out/contract.awst b/test_cases/asset/out/contract.awst index d9304a5c16..cea540947f 100644 --- a/test_cases/asset/out/contract.awst +++ b/test_cases/asset/out/contract.awst @@ -60,5 +60,6 @@ contract Reference assert(checked_maybe(asset_params_get(asset)) == global(), comment="freeze") assert(checked_maybe(asset_params_get(asset)) == global(), comment="clawback") assert(checked_maybe(asset_params_get(asset)) == global(), comment="creator") + assert(asset_holding_get(global(), asset)[1], comment="asset opted in") } } \ No newline at end of file diff --git a/test_cases/asset/out_O2/Reference.approval.teal b/test_cases/asset/out_O2/Reference.approval.teal index 796fc2be7f..cfa6cc17f9 100644 --- a/test_cases/asset/out_O2/Reference.approval.teal +++ b/test_cases/asset/out_O2/Reference.approval.teal @@ -141,6 +141,11 @@ is_opted_asset: global CreatorAddress == assert // creator + global CurrentApplicationAddress + frame_dig -1 + asset_holding_get AssetBalance + bury 1 + assert // asset opted in retsub diff --git a/test_cases/asset/out_O2/Reference.destructured.ir b/test_cases/asset/out_O2/Reference.destructured.ir index 070d96b332..dc63fdfe9e 100644 --- a/test_cases/asset/out_O2/Reference.destructured.ir +++ b/test_cases/asset/out_O2/Reference.destructured.ir @@ -109,6 +109,9 @@ contract test_cases.asset.contract.Reference: let tmp%43#0: bytes = (global CreatorAddress) let tmp%44#0: uint64 = (== value%41#0 tmp%43#0) (assert tmp%44#0) // creator + let tmp%45#0: bytes = (global CurrentApplicationAddress) + let (tmp%46#0: uint64, tmp%47#0: uint64) = ((asset_holding_get AssetBalance) tmp%45#0 asset#0) + (assert tmp%47#0) // asset opted in return subroutine test_cases.asset.contract.Reference.__init__() -> void: diff --git a/test_cases/asset/out_unoptimized/Reference.approval.teal b/test_cases/asset/out_unoptimized/Reference.approval.teal index 4d15459c96..926d69be95 100644 --- a/test_cases/asset/out_unoptimized/Reference.approval.teal +++ b/test_cases/asset/out_unoptimized/Reference.approval.teal @@ -222,6 +222,14 @@ is_opted_asset: global CreatorAddress == assert // creator + // asset/contract.py:67 + // assert Global.current_application_address.is_opted_in(asset), "asset opted in" + global CurrentApplicationAddress + frame_dig -1 + asset_holding_get AssetBalance + swap + pop + assert // asset opted in retsub diff --git a/test_cases/asset/out_unoptimized/Reference.destructured.ir b/test_cases/asset/out_unoptimized/Reference.destructured.ir index 941e8c4bc0..d9e1319860 100644 --- a/test_cases/asset/out_unoptimized/Reference.destructured.ir +++ b/test_cases/asset/out_unoptimized/Reference.destructured.ir @@ -116,6 +116,9 @@ contract test_cases.asset.contract.Reference: let tmp%43#0: bytes = (global CreatorAddress) let tmp%44#0: uint64 = (== value%41#0 tmp%43#0) (assert tmp%44#0) // creator + let tmp%45#0: bytes = (global CurrentApplicationAddress) + let (tmp%46#0: uint64, tmp%47#0: uint64) = ((asset_holding_get AssetBalance) tmp%45#0 asset#0) + (assert tmp%47#0) // asset opted in return subroutine test_cases.asset.contract.Reference.__init__() -> void: diff --git a/test_cases/asset/puya.log b/test_cases/asset/puya.log index fd70c34593..6c5b89986e 100644 --- a/test_cases/asset/puya.log +++ b/test_cases/asset/puya.log @@ -518,6 +518,8 @@ debug: Inserted is_opted_asset_block@0.ops[162]: 'store tmp%40#0 to l-stack (cop debug: Replaced is_opted_asset_block@0.ops[164]: 'load tmp%40#0' with 'load tmp%40#0 from l-stack (no copy)' debug: Inserted is_opted_asset_block@0.ops[177]: 'store tmp%44#0 to l-stack (copy)' debug: Replaced is_opted_asset_block@0.ops[179]: 'load tmp%44#0' with 'load tmp%44#0 from l-stack (no copy)' +debug: Inserted is_opted_asset_block@0.ops[182]: 'store tmp%45#0 to l-stack (copy)' +debug: Replaced is_opted_asset_block@0.ops[184]: 'load tmp%45#0' with 'load tmp%45#0 from l-stack (no copy)' debug: Inserted is_opted_asset_block@0.ops[3]: 'store asa_exists%1#0 to l-stack (copy)' debug: Replaced is_opted_asset_block@0.ops[6]: 'load asa_exists%1#0' with 'load asa_exists%1#0 from l-stack (no copy)' debug: Inserted is_opted_asset_block@0.ops[17]: 'store check%4#0 to l-stack (copy)' @@ -556,6 +558,8 @@ debug: Inserted is_opted_asset_block@0.ops[185]: 'store check%42#0 to l-stack (c debug: Replaced is_opted_asset_block@0.ops[188]: 'load check%42#0' with 'load check%42#0 from l-stack (no copy)' debug: Inserted is_opted_asset_block@0.ops[191]: 'store tmp%43#0 to l-stack (copy)' debug: Replaced is_opted_asset_block@0.ops[194]: 'load tmp%43#0' with 'load tmp%43#0 from l-stack (no copy)' +debug: Inserted is_opted_asset_block@0.ops[206]: 'store tmp%47#0 to l-stack (copy)' +debug: Replaced is_opted_asset_block@0.ops[209]: 'load tmp%47#0' with 'load tmp%47#0 from l-stack (no copy)' debug: Inserted is_opted_asset_block@0.ops[5]: 'store asa_value%0#0 to l-stack (copy)' debug: Replaced is_opted_asset_block@0.ops[9]: 'load asa_value%0#0' with 'load asa_value%0#0 from l-stack (no copy)' debug: Inserted is_opted_asset_block@0.ops[20]: 'store value%3#0 to l-stack (copy)'