From c793a96b58ccf082624c817744c0a589533c453d Mon Sep 17 00:00:00 2001 From: Stanislaw Czembor Date: Thu, 18 Aug 2022 21:36:51 +0200 Subject: [PATCH 1/6] fixed error description --- packages/web/src/types-input.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web/src/types-input.ts b/packages/web/src/types-input.ts index 9f7f3c0c2..8e8958b6c 100644 --- a/packages/web/src/types-input.ts +++ b/packages/web/src/types-input.ts @@ -11,7 +11,7 @@ export const ASADefSchema = z.object({ .union([z.number(), z.bigint(), z.string()]) // 'string' to support bigint from yaml file .refine( (t) => totalRegex.test(String(t)) && BigInt(t) <= 0xffffffffffffffffn && BigInt(t) >= 0n, - { message: "Total must be a positive number and smaller than 2^64-1" } + { message: "Total must be a positive number <= 2^64-1" } ), decimals: z .union([z.number(), z.bigint()]) From 3813d94fc2864c4b9433414d514e5787c888859c Mon Sep 17 00:00:00 2001 From: Stanislaw Czembor Date: Mon, 29 Aug 2022 16:32:38 +0200 Subject: [PATCH 2/6] test scenario for uint64 overflow --- .../asa/assets/teal/2-gold-contract-asc.teal | 55 ++++++++++--------- .../unique-nft-asa/assets/nft-app-clear.py | 2 +- .../unique-nft-asa/scripts/0-deploy-app.js | 14 ++--- .../test/src/interpreter/inner-transaction.ts | 35 ++++++++++++ .../test/src/interpreter/opcode-list.ts | 19 +++++++ 5 files changed, 90 insertions(+), 35 deletions(-) diff --git a/examples/asa/assets/teal/2-gold-contract-asc.teal b/examples/asa/assets/teal/2-gold-contract-asc.teal index db649fc66..611e07050 100644 --- a/examples/asa/assets/teal/2-gold-contract-asc.teal +++ b/examples/asa/assets/teal/2-gold-contract-asc.teal @@ -1,29 +1,30 @@ -#pragma version 4 +#pragma version 6 // Check if Transaction type is pay or axfer, algo amount AND asset amount is <= 100 -txn TypeEnum +itxn_begin +int 0 +itxn_field Fee +int acfg +itxn_field TypeEnum +int 18446744073709551615 +itxn_field ConfigAssetTotal +int 6 +itxn_field ConfigAssetDecimals +load 0 +byte "/" +concat +load 1 +concat +byte " PACT LP Token" +concat +itxn_field ConfigAssetName +byte "PLP" +itxn_field ConfigAssetUnitName +byte "https://pact.fi/" +itxn_field ConfigAssetURL +global CurrentApplicationAddress +itxn_field ConfigAssetReserve +itxn_submit +byte "LTID" +itxn CreatedAssetID +app_global_put int 1 -== -txn TypeEnum -int 4 -== -|| -txn Amount -int 100 -<= -&& -txn AssetAmount -int 100 -<= -&& -txn RekeyTo -global ZeroAddress -== -&& -txn CloseRemainderTo -global ZeroAddress -== -&& -txn Fee -int 10000 -<= -&& \ No newline at end of file diff --git a/examples/unique-nft-asa/assets/nft-app-clear.py b/examples/unique-nft-asa/assets/nft-app-clear.py index 5d284ab6e..e0f073ade 100644 --- a/examples/unique-nft-asa/assets/nft-app-clear.py +++ b/examples/unique-nft-asa/assets/nft-app-clear.py @@ -5,4 +5,4 @@ def clear_state_program(): optimize_options = OptimizeOptions(scratch_slots=True) if __name__ == "__main__": - print(compileTeal(clear_state_program(), Mode.Application, version = 5, optimize=optimize_options)) \ No newline at end of file + print(compileTeal(clear_state_program(), Mode.Application, version = 6, optimize=optimize_options)) \ No newline at end of file diff --git a/examples/unique-nft-asa/scripts/0-deploy-app.js b/examples/unique-nft-asa/scripts/0-deploy-app.js index 127992008..ee0e363a7 100644 --- a/examples/unique-nft-asa/scripts/0-deploy-app.js +++ b/examples/unique-nft-asa/scripts/0-deploy-app.js @@ -13,7 +13,7 @@ async function run(runtimeEnv, deployer) { { appName: "NftApp", metaType: types.MetaType.FILE, - approvalProgramFilename: "nft-app-approval.py", + approvalProgramFilename: "test.teal", clearProgramFilename: "nft-app-clear.py", localInts: 1, // p localBytes: 1, // creator @@ -23,12 +23,12 @@ async function run(runtimeEnv, deployer) { console.log(nftAppInfo); // fund C_p lsig - await deployer.fundLsigByFile( - "stateless.py", - { funder: creator, fundingMicroAlgo: 1e6 }, - {}, // 1 algo - { ARG_P: p, ARG_NFT_APP_ID: nftAppInfo.appID } - ); + // await deployer.fundLsigByFile( + // "stateless.py", + // { funder: creator, fundingMicroAlgo: 1e6 }, + // {}, // 1 algo + // { ARG_P: p, ARG_NFT_APP_ID: nftAppInfo.appID } + // ); console.log("Contracts deployed successfully!"); } diff --git a/packages/runtime/test/src/interpreter/inner-transaction.ts b/packages/runtime/test/src/interpreter/inner-transaction.ts index 908d5eb99..7e7681c4f 100644 --- a/packages/runtime/test/src/interpreter/inner-transaction.ts +++ b/packages/runtime/test/src/interpreter/inner-transaction.ts @@ -1072,6 +1072,41 @@ describe("Inner Transactions", function () { assert.doesNotThrow(() => executeTEAL(create)); }); }); + describe.only("Test Pact's CPMM smart contract", () => { + it("should execute asset configuration branch", () => { + const create = ` + itxn_begin + int 0 + itxn_field Fee + int acfg + itxn_field TypeEnum + int 18446744073709551615 + itxn_field ConfigAssetTotal + int 6 + itxn_field ConfigAssetDecimals + load 0 + byte "/" + concat + load 1 + concat + byte " PACT LP Token" + concat + itxn_field ConfigAssetName + byte "PLP" + itxn_field ConfigAssetUnitName + byte "https://pact.fi/" + itxn_field ConfigAssetURL + global CurrentApplicationAddress + itxn_field ConfigAssetReserve + itxn_submit + byte "LTID" + itxn CreatedAssetID + app_global_put + int 1 + `; + assert.doesNotThrow(() => executeTEAL(create)); + }); + }); describe("TestAssetFreeze", () => { it(`should test asset freeze inner transaction (flow test)`, function () { diff --git a/packages/runtime/test/src/interpreter/opcode-list.ts b/packages/runtime/test/src/interpreter/opcode-list.ts index 652109506..5b83b4f61 100644 --- a/packages/runtime/test/src/interpreter/opcode-list.ts +++ b/packages/runtime/test/src/interpreter/opcode-list.ts @@ -3642,6 +3642,25 @@ describe("Teal Opcodes", function () { assert.equal(5n, stack.pop()); }); + it("Int: Should not throw an overflow error", () => { + const total = BigInt(2 ** 64) - 1n; + assert.doesNotThrow(() => new Int([total.toString()], 0)); + }); + it("Int: Should throw an overflow error", () => { + const total = BigInt(2 ** 64); + expectRuntimeError( + () => new Int([total.toString()], 0), + RUNTIME_ERRORS.TEAL.UINT64_OVERFLOW + ); + }); + it("Int: Should throw an overflow error", () => { + const total = BigInt(2 ** 64) + 1n; + expectRuntimeError( + () => new Int([total.toString()], 0), + RUNTIME_ERRORS.TEAL.UINT64_OVERFLOW + ); + }); + it("Int: should push correct TypeEnumConstants enum value to stack", function () { let op = new Int(["unknown"], 0); op.execute(stack); From fe88daa3db94481b1fa1174ccbb4cdf13ae22d70 Mon Sep 17 00:00:00 2001 From: Stanislaw Czembor Date: Mon, 29 Aug 2022 16:41:20 +0200 Subject: [PATCH 3/6] cleanup --- .../asa/assets/teal/2-gold-contract-asc.teal | 55 +++++++++---------- .../unique-nft-asa/assets/nft-app-clear.py | 2 +- .../unique-nft-asa/scripts/0-deploy-app.js | 14 ++--- .../test/src/interpreter/inner-transaction.ts | 35 ------------ 4 files changed, 35 insertions(+), 71 deletions(-) diff --git a/examples/asa/assets/teal/2-gold-contract-asc.teal b/examples/asa/assets/teal/2-gold-contract-asc.teal index 611e07050..db649fc66 100644 --- a/examples/asa/assets/teal/2-gold-contract-asc.teal +++ b/examples/asa/assets/teal/2-gold-contract-asc.teal @@ -1,30 +1,29 @@ -#pragma version 6 +#pragma version 4 // Check if Transaction type is pay or axfer, algo amount AND asset amount is <= 100 -itxn_begin -int 0 -itxn_field Fee -int acfg -itxn_field TypeEnum -int 18446744073709551615 -itxn_field ConfigAssetTotal -int 6 -itxn_field ConfigAssetDecimals -load 0 -byte "/" -concat -load 1 -concat -byte " PACT LP Token" -concat -itxn_field ConfigAssetName -byte "PLP" -itxn_field ConfigAssetUnitName -byte "https://pact.fi/" -itxn_field ConfigAssetURL -global CurrentApplicationAddress -itxn_field ConfigAssetReserve -itxn_submit -byte "LTID" -itxn CreatedAssetID -app_global_put +txn TypeEnum int 1 +== +txn TypeEnum +int 4 +== +|| +txn Amount +int 100 +<= +&& +txn AssetAmount +int 100 +<= +&& +txn RekeyTo +global ZeroAddress +== +&& +txn CloseRemainderTo +global ZeroAddress +== +&& +txn Fee +int 10000 +<= +&& \ No newline at end of file diff --git a/examples/unique-nft-asa/assets/nft-app-clear.py b/examples/unique-nft-asa/assets/nft-app-clear.py index e0f073ade..5d284ab6e 100644 --- a/examples/unique-nft-asa/assets/nft-app-clear.py +++ b/examples/unique-nft-asa/assets/nft-app-clear.py @@ -5,4 +5,4 @@ def clear_state_program(): optimize_options = OptimizeOptions(scratch_slots=True) if __name__ == "__main__": - print(compileTeal(clear_state_program(), Mode.Application, version = 6, optimize=optimize_options)) \ No newline at end of file + print(compileTeal(clear_state_program(), Mode.Application, version = 5, optimize=optimize_options)) \ No newline at end of file diff --git a/examples/unique-nft-asa/scripts/0-deploy-app.js b/examples/unique-nft-asa/scripts/0-deploy-app.js index ee0e363a7..127992008 100644 --- a/examples/unique-nft-asa/scripts/0-deploy-app.js +++ b/examples/unique-nft-asa/scripts/0-deploy-app.js @@ -13,7 +13,7 @@ async function run(runtimeEnv, deployer) { { appName: "NftApp", metaType: types.MetaType.FILE, - approvalProgramFilename: "test.teal", + approvalProgramFilename: "nft-app-approval.py", clearProgramFilename: "nft-app-clear.py", localInts: 1, // p localBytes: 1, // creator @@ -23,12 +23,12 @@ async function run(runtimeEnv, deployer) { console.log(nftAppInfo); // fund C_p lsig - // await deployer.fundLsigByFile( - // "stateless.py", - // { funder: creator, fundingMicroAlgo: 1e6 }, - // {}, // 1 algo - // { ARG_P: p, ARG_NFT_APP_ID: nftAppInfo.appID } - // ); + await deployer.fundLsigByFile( + "stateless.py", + { funder: creator, fundingMicroAlgo: 1e6 }, + {}, // 1 algo + { ARG_P: p, ARG_NFT_APP_ID: nftAppInfo.appID } + ); console.log("Contracts deployed successfully!"); } diff --git a/packages/runtime/test/src/interpreter/inner-transaction.ts b/packages/runtime/test/src/interpreter/inner-transaction.ts index 7e7681c4f..908d5eb99 100644 --- a/packages/runtime/test/src/interpreter/inner-transaction.ts +++ b/packages/runtime/test/src/interpreter/inner-transaction.ts @@ -1072,41 +1072,6 @@ describe("Inner Transactions", function () { assert.doesNotThrow(() => executeTEAL(create)); }); }); - describe.only("Test Pact's CPMM smart contract", () => { - it("should execute asset configuration branch", () => { - const create = ` - itxn_begin - int 0 - itxn_field Fee - int acfg - itxn_field TypeEnum - int 18446744073709551615 - itxn_field ConfigAssetTotal - int 6 - itxn_field ConfigAssetDecimals - load 0 - byte "/" - concat - load 1 - concat - byte " PACT LP Token" - concat - itxn_field ConfigAssetName - byte "PLP" - itxn_field ConfigAssetUnitName - byte "https://pact.fi/" - itxn_field ConfigAssetURL - global CurrentApplicationAddress - itxn_field ConfigAssetReserve - itxn_submit - byte "LTID" - itxn CreatedAssetID - app_global_put - int 1 - `; - assert.doesNotThrow(() => executeTEAL(create)); - }); - }); describe("TestAssetFreeze", () => { it(`should test asset freeze inner transaction (flow test)`, function () { From 8a9b16204e5a2dbb41ffc641900a716349954cb9 Mon Sep 17 00:00:00 2001 From: sczembor <43810037+sczembor@users.noreply.github.com> Date: Tue, 30 Aug 2022 09:06:49 +0200 Subject: [PATCH 4/6] Apply suggestions from code review Co-authored-by: Robert Zaremba --- packages/runtime/test/src/interpreter/opcode-list.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/runtime/test/src/interpreter/opcode-list.ts b/packages/runtime/test/src/interpreter/opcode-list.ts index 5b83b4f61..c34967824 100644 --- a/packages/runtime/test/src/interpreter/opcode-list.ts +++ b/packages/runtime/test/src/interpreter/opcode-list.ts @@ -3642,18 +3642,18 @@ describe("Teal Opcodes", function () { assert.equal(5n, stack.pop()); }); - it("Int: Should not throw an overflow error", () => { - const total = BigInt(2 ** 64) - 1n; + it("Int: Should work with 2^64 - 1 (max supported number)", () => { + const total = 2n**64n - 1n; assert.doesNotThrow(() => new Int([total.toString()], 0)); }); - it("Int: Should throw an overflow error", () => { + it("Int: Should throw an overflow error on 2^64", () => { const total = BigInt(2 ** 64); expectRuntimeError( () => new Int([total.toString()], 0), RUNTIME_ERRORS.TEAL.UINT64_OVERFLOW ); }); - it("Int: Should throw an overflow error", () => { + it("Int: Should throw an overflow error on 2^64+1", () => { const total = BigInt(2 ** 64) + 1n; expectRuntimeError( () => new Int([total.toString()], 0), From 1636046e249848bac9aca2ac60b59c327b7e4477 Mon Sep 17 00:00:00 2001 From: Stanislaw Czembor Date: Tue, 30 Aug 2022 09:17:24 +0200 Subject: [PATCH 5/6] changed number format --- packages/runtime/test/src/interpreter/opcode-list.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/runtime/test/src/interpreter/opcode-list.ts b/packages/runtime/test/src/interpreter/opcode-list.ts index c34967824..34ccd4cd8 100644 --- a/packages/runtime/test/src/interpreter/opcode-list.ts +++ b/packages/runtime/test/src/interpreter/opcode-list.ts @@ -3643,18 +3643,18 @@ describe("Teal Opcodes", function () { }); it("Int: Should work with 2^64 - 1 (max supported number)", () => { - const total = 2n**64n - 1n; + const total = 2n ** 64n - 1n; assert.doesNotThrow(() => new Int([total.toString()], 0)); }); it("Int: Should throw an overflow error on 2^64", () => { - const total = BigInt(2 ** 64); + const total = 2n ** 64n; expectRuntimeError( () => new Int([total.toString()], 0), RUNTIME_ERRORS.TEAL.UINT64_OVERFLOW ); }); it("Int: Should throw an overflow error on 2^64+1", () => { - const total = BigInt(2 ** 64) + 1n; + const total = 2n ** 64n + 1n; expectRuntimeError( () => new Int([total.toString()], 0), RUNTIME_ERRORS.TEAL.UINT64_OVERFLOW From 0d73ece7ac7b28f455da09b064fcd8cad70b616b Mon Sep 17 00:00:00 2001 From: Stanislaw Czembor Date: Tue, 30 Aug 2022 09:59:01 +0200 Subject: [PATCH 6/6] test for asa creation with total value = 2^64-1 --- packages/runtime/test/src/runtime.ts | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/packages/runtime/test/src/runtime.ts b/packages/runtime/test/src/runtime.ts index ee7f87df5..7f6014386 100644 --- a/packages/runtime/test/src/runtime.ts +++ b/packages/runtime/test/src/runtime.ts @@ -452,6 +452,32 @@ describe("Algorand Standard Assets", function () { assert.equal(res.url, "url"); }); + it("Should create asset with total = 2^64-1 (max value possible)", () => { + const maxUint64 = 2n ** 64n - 1n; + const execParams: types.ExecParams = { + type: types.TransactionType.DeployASA, + sign: types.SignType.SecretKey, + fromAccount: john.account, + asaName: "maxTotal", + asaDef: { + total: maxUint64, + decimals: 0, + defaultFrozen: false, + unitName: "TTL", + url: "url", + metadataHash: "12312442142141241244444411111134", + note: "note", + }, + payFlags: {}, + }; + runtime.executeTx([execParams]); + syncAccounts(); + + const res = runtime.getAssetInfoFromName("maxTotal"); + assert.isDefined(res); + assert.equal(res?.assetDef.total, maxUint64); + }); + it("should create asset without using asa.yaml (execute transaction)", () => { const execParams: types.ExecParams = { type: types.TransactionType.DeployASA,