diff --git a/src/lib/compiler.ts b/src/lib/compiler.ts index 3e93d135a..fcfb5ea0e 100644 --- a/src/lib/compiler.ts +++ b/src/lib/compiler.ts @@ -1,3 +1,4 @@ +/* eslint-disable no-plusplus */ /* eslint-disable max-classes-per-file */ /* eslint-disable no-unused-vars */ import fetch from 'node-fetch'; @@ -5,7 +6,6 @@ import * as vlq from 'vlq'; import ts from 'typescript'; import sourceMap from 'source-map'; import path from 'path'; -import { access } from 'fs'; import * as langspec from '../langspec.json'; export type CompilerOptions = { @@ -379,6 +379,14 @@ export default class Compiler { asset: this.getOpParamObjects('asset_params_get'), }; + private checkDecoding(node: ts.Node, type: string) { + if (type === 'bool') { + this.pushLines(node, 'int 0', 'getbit'); + } else if (this.isDynamicArrayOfStaticType(type)) { + this.pushVoid(node, 'extract 2 0'); + } + } + private storageFunctions: {[type: string]: {[f: string]: Function}} = { global: { get: (node: ts.CallExpression) => { @@ -397,7 +405,7 @@ export default class Compiler { this.processNode(node.arguments[0]); if (keyType !== StackType.bytes) { - this.potentialLengthPrefix(node.arguments[0], this.lastType); + this.checkEncoding(node.arguments[0], this.lastType); } if (isNumeric(keyType)) this.pushVoid(node.arguments[0], 'itob'); @@ -405,7 +413,7 @@ export default class Compiler { } this.push(node.expression, 'app_global_get', valueType); - if (this.isDynamicArrayOfStaticType(valueType) && valueType !== StackType.bytes) this.push(node.expression, 'extract 2 0', valueType); + if (valueType !== StackType.bytes) this.checkDecoding(node, valueType); }, set: (node: ts.CallExpression) => { if (!ts.isPropertyAccessExpression(node.expression)) throw new Error(); @@ -423,7 +431,7 @@ export default class Compiler { this.processNode(node.arguments[0]); if (keyType !== StackType.bytes) { - this.potentialLengthPrefix(node.arguments[0], this.lastType); + this.checkEncoding(node.arguments[0], this.lastType); } if (isNumeric(keyType)) this.pushVoid(node.arguments[0], 'itob'); @@ -433,7 +441,7 @@ export default class Compiler { if (node.arguments[key ? 0 : 1]) { this.processNode(node.arguments[key ? 0 : 1]); if (valueType !== StackType.bytes) { - this.potentialLengthPrefix(node.arguments[key ? 0 : 1], this.lastType); + this.checkEncoding(node.arguments[key ? 0 : 1], this.lastType); } } else this.pushVoid(node.expression, 'swap'); // Used when updating storage array @@ -455,7 +463,7 @@ export default class Compiler { this.processNode(node.arguments[0]); if (keyType !== StackType.bytes) { - this.potentialLengthPrefix(node.arguments[0], this.lastType); + this.checkEncoding(node.arguments[0], this.lastType); } if (isNumeric(keyType)) this.pushVoid(node.arguments[0], 'itob'); @@ -482,7 +490,7 @@ export default class Compiler { this.processNode(node.arguments[0]); if (keyType !== StackType.bytes) { - this.potentialLengthPrefix(node.arguments[0], this.lastType); + this.checkEncoding(node.arguments[0], this.lastType); } if (isNumeric(keyType)) this.pushVoid(node.arguments[0], 'itob'); @@ -511,7 +519,7 @@ export default class Compiler { this.processNode(node.arguments[1]); if (keyType !== StackType.bytes) { - this.potentialLengthPrefix(node.arguments[1], this.lastType); + this.checkEncoding(node.arguments[1], this.lastType); } if (isNumeric(keyType)) this.pushVoid(node.arguments[1], 'itob'); @@ -519,7 +527,7 @@ export default class Compiler { } this.push(node.expression, 'app_local_get', valueType); - if (this.isDynamicArrayOfStaticType(valueType) && valueType !== StackType.bytes) this.push(node.expression, 'extract 2 0', valueType); + if (valueType !== StackType.bytes) this.checkDecoding(node, valueType); }, set: (node: ts.CallExpression) => { if (!ts.isPropertyAccessExpression(node.expression)) throw new Error(); @@ -539,7 +547,7 @@ export default class Compiler { this.processNode(node.arguments[1]); if (keyType !== StackType.bytes) { - this.potentialLengthPrefix(node.arguments[1], this.lastType); + this.checkEncoding(node.arguments[1], this.lastType); } if (isNumeric(keyType)) this.pushVoid(node.arguments[1], 'itob'); @@ -549,7 +557,7 @@ export default class Compiler { if (node.arguments[key ? 1 : 2]) { this.processNode(node.arguments[key ? 1 : 2]); if (valueType !== StackType.bytes) { - this.potentialLengthPrefix(node.arguments[key ? 1 : 2], this.lastType); + this.checkEncoding(node.arguments[key ? 1 : 2], this.lastType); } } else this.pushVoid(node.expression, 'uncover 2'); // Used when updating storage array @@ -573,7 +581,7 @@ export default class Compiler { this.processNode(node.arguments[1]); if (keyType !== StackType.bytes) { - this.potentialLengthPrefix(node.arguments[1], this.lastType); + this.checkEncoding(node.arguments[1], this.lastType); } if (isNumeric(keyType)) this.pushVoid(node.arguments[1], 'itob'); @@ -600,7 +608,7 @@ export default class Compiler { this.processNode(node.arguments[1]); if (keyType !== StackType.bytes) { - this.potentialLengthPrefix(node.arguments[1], this.lastType); + this.checkEncoding(node.arguments[1], this.lastType); } if (isNumeric(keyType)) this.pushVoid(node.arguments[1], 'itob'); @@ -628,7 +636,7 @@ export default class Compiler { this.processNode(node.arguments[0]); if (keyType !== StackType.bytes) { - this.potentialLengthPrefix(node.arguments[0], this.lastType); + this.checkEncoding(node.arguments[0], this.lastType); } if (isNumeric(keyType)) this.pushVoid(node.arguments[0], 'itob'); @@ -656,7 +664,7 @@ export default class Compiler { this.processNode(node.arguments[0]); if (keyType !== StackType.bytes) { - this.potentialLengthPrefix(node.arguments[0], this.lastType); + this.checkEncoding(node.arguments[0], this.lastType); } if (isNumeric(keyType)) this.pushVoid(node.arguments[0], 'itob'); @@ -685,7 +693,7 @@ export default class Compiler { this.processNode(node.arguments[0]); if (keyType !== StackType.bytes) { - this.potentialLengthPrefix(node.arguments[0], this.lastType); + this.checkEncoding(node.arguments[0], this.lastType); } if (isNumeric(keyType)) this.pushVoid(node.arguments[0], 'itob'); @@ -714,7 +722,7 @@ export default class Compiler { this.processNode(node.arguments[0]); if (keyType !== StackType.bytes) { - this.potentialLengthPrefix(node.arguments[0], this.lastType); + this.checkEncoding(node.arguments[0], this.lastType); } if (isNumeric(keyType)) this.pushVoid(node.arguments[0], 'itob'); @@ -739,7 +747,7 @@ export default class Compiler { this.processNode(node.arguments[0]); if (keyType !== StackType.bytes) { - this.potentialLengthPrefix(node.arguments[0], this.lastType); + this.checkEncoding(node.arguments[0], this.lastType); } if (isNumeric(keyType)) this.pushVoid(node.arguments[0], 'itob'); @@ -748,7 +756,7 @@ export default class Compiler { this.maybeValue(node.expression, 'box_get', valueType); if (isNumeric(valueType)) this.push(node.expression, 'btoi', valueType); - if (this.isDynamicArrayOfStaticType(valueType) && valueType !== StackType.bytes) this.push(node.expression, 'extract 2 0', valueType); + if (valueType !== StackType.bytes) this.checkDecoding(node, valueType); }, set: (node: ts.CallExpression) => { if (!ts.isPropertyAccessExpression(node.expression)) throw new Error(); @@ -766,7 +774,7 @@ export default class Compiler { this.processNode(node.arguments[0]); if (keyType !== StackType.bytes) { - this.potentialLengthPrefix(node.arguments[0], this.lastType); + this.checkEncoding(node.arguments[0], this.lastType); } if (isNumeric(keyType)) this.pushVoid(node.arguments[0], 'itob'); @@ -779,7 +787,7 @@ export default class Compiler { this.processNode(node.arguments[key ? 0 : 1]); if (keyType !== StackType.bytes) { - this.potentialLengthPrefix(node.arguments[key ? 0 : 1], this.lastType); + this.checkEncoding(node.arguments[key ? 0 : 1], this.lastType); } } else this.pushVoid(node.expression, 'swap'); // Used when updating storage array @@ -803,7 +811,7 @@ export default class Compiler { this.processNode(node.arguments[0]); if (keyType !== StackType.bytes) { - this.potentialLengthPrefix(node.arguments[0], this.lastType); + this.checkEncoding(node.arguments[0], this.lastType); } if (isNumeric(keyType)) this.pushVoid(node.arguments[0], 'itob'); @@ -828,7 +836,7 @@ export default class Compiler { this.processNode(node.arguments[0]); if (keyType !== StackType.bytes) { - this.potentialLengthPrefix(node.arguments[0], this.lastType); + this.checkEncoding(node.arguments[0], this.lastType); } if (isNumeric(keyType)) this.pushVoid(node.arguments[0], 'itob'); @@ -1016,6 +1024,8 @@ export default class Compiler { } private getTypeLength(inputType: string): number { + if (inputType === '[]') return 0; + const type = this.getABIType(inputType); const typeNode = stringToExpression(type) as ts.Expression; @@ -1028,6 +1038,13 @@ export default class Compiler { } } + if (type.match(/^bool\[\d+\]$/)) { + const lenStr = type.match(/\[\d+]$/)![0].match(/\d+/)![0]; + const length = parseInt(lenStr, 10); + + return Math.ceil(length / 8); + } + if (type.match(/\[\d+]$/)) { const lenStr = type.match(/\[\d+]$/)![0].match(/\d+/)![0]; const length = parseInt(lenStr, 10); @@ -1039,9 +1056,25 @@ export default class Compiler { const tNode = stringToExpression(type); if (!ts.isArrayLiteralExpression(tNode)) throw new Error(); let totalLength = 0; + let consecutiveBools = 0; + tNode.elements.forEach((t) => { - totalLength += this.getTypeLength(t.getText()); + const typeString = t.getText(); + if (typeString === 'bool') { + consecutiveBools += 1; + } else { + if (consecutiveBools > 0) { + totalLength += Math.ceil(consecutiveBools / 8); + } + + totalLength += this.getTypeLength(typeString); + + consecutiveBools = 0; + } }); + + totalLength += Math.ceil(consecutiveBools / 8); + return totalLength; } @@ -1056,10 +1089,23 @@ export default class Compiler { if (type.startsWith('{')) { const types = Object.values(this.getObjectTypes(type)); let totalLength = 0; + let consecutiveBools = 0; types.forEach((t) => { - totalLength += this.getTypeLength(t); + if (t === 'bool') { + consecutiveBools += 1; + } else { + if (consecutiveBools > 0) { + totalLength += Math.ceil(consecutiveBools / 8); + } + + totalLength += this.getTypeLength(t); + + consecutiveBools = 0; + } }); + totalLength += Math.ceil(consecutiveBools / 8); + return totalLength; } @@ -1109,7 +1155,7 @@ export default class Compiler { if (txnTypes[type]) return txnTypes[type]; - if (type === 'boolean') return 'uint64'; + if (type === 'boolean') return 'bool'; if (type === 'number') return 'uint64'; const typeNode = stringToExpression(abiType) as ts.Expression; @@ -1485,6 +1531,8 @@ export default class Compiler { else if (ts.isVariableStatement(node)) this.processNode((node).declarationList); else if (ts.isElementAccessExpression(node)) this.processElementAccessExpression(node); else if (ts.isConditionalExpression(node)) this.processConditionalExpression(node); + else if (node.kind === ts.SyntaxKind.TrueKeyword) this.pushVoid(node, 'int 1'); + else if (node.kind === ts.SyntaxKind.FalseKeyword) this.pushVoid(node, 'int 0'); else throw new Error(`Unknown node type: ${ts.SyntaxKind[node.kind]} (${node.kind})`); } catch (e) { if (!(e instanceof Error)) throw e; @@ -1566,6 +1614,24 @@ export default class Compiler { throw new Error(typeHintNode.getText()); } + private processBools( + nodes: ts.Node[] | ts.NodeArray, + isDynamicArray: boolean = false, + ) { + const boolByteLength = Math.ceil(nodes.length / 8); + + if (isDynamicArray) this.pushVoid(nodes[0], `byte 0x${nodes.length.toString(16).padStart(4, '0')}`); + this.pushVoid(nodes[0], `byte 0x${'00'.repeat(boolByteLength)}`); + + nodes.forEach((n, i) => { + this.pushVoid(n, `int ${i}`); + this.processNode(n); + this.pushVoid(n, 'setbit'); + }); + + if (isDynamicArray) this.pushVoid(nodes[0], 'concat'); + } + private processTuple(node: ts.ArrayLiteralExpression) { if (this.typeHint === undefined) throw new Error('Type hint is undefined'); let { typeHint } = this; @@ -1573,21 +1639,33 @@ export default class Compiler { if (!this.getABIType(typeHint).includes(']')) typeHint = `${typeHint}[]`; const types = this.getarrayElementTypes(node.elements.length); - const headLength = types.reduce((sum, t) => { - const length = this.isDynamicType(t) ? 2 : this.getTypeLength(t); - return sum + length; - }, 0); - node.elements.forEach((e, i) => { - this.typeHint = types[i]; + const dynamicTypes = types.filter((t) => this.isDynamicType(t)); + const staticTypes = types.filter((t) => !this.isDynamicType(t)); + const headLength = this.getTypeLength(`[${staticTypes.join(',')}]`) + dynamicTypes.length * 2; + let consecutiveBools: ts.Node[] = []; + node.elements.forEach((e, i) => { if (i === 0) { this.pushLines(node, 'byte 0x // initial head', 'byte 0x // initial tail', `byte 0x${headLength.toString(16).padStart(4, '0')} // initial head offset`); } + if (types[i] === 'bool') { + consecutiveBools.push(e); + return; + } + + if (consecutiveBools.length > 0) { + this.processBools(consecutiveBools); + this.pushVoid(e, 'callsub process_static_tuple_element'); + consecutiveBools = []; + } + + this.typeHint = types[i]; + this.processNode(e); - this.potentialLengthPrefix(e, types[i]); + this.checkEncoding(e, types[i]); if (isNumeric(this.lastType)) this.pushVoid(e, 'itob'); if (this.lastType.match(/uint\d+$/) && this.lastType !== types[i]) this.fixBitWidth(e, parseInt(types[i].match(/\d+$/)![0], 10), !ts.isNumericLiteral(e)); @@ -1599,12 +1677,20 @@ export default class Compiler { } }); + if (consecutiveBools.length > 0) { + this.processBools(consecutiveBools); + this.pushVoid(node, 'callsub process_static_tuple_element'); + } + this.pushLines(node, 'pop // pop head offset', 'concat // concat head and tail'); } - private potentialLengthPrefix(node: ts.Node, type: string) { + private checkEncoding(node: ts.Node, type: string) { + const abiType = this.getABIType(type); if (this.isDynamicArrayOfStaticType(type)) { - const length = this.getTypeLength(type.replace(/\[\]$/, '')); + const baseType = type.replace(/\[\]$/, ''); + if (baseType === 'bool') return; + const length = this.getTypeLength(baseType); this.pushLines( node, @@ -1625,6 +1711,8 @@ export default class Compiler { 'swap', 'concat', ); + } else if (abiType === 'bool') { + this.pushLines(node, 'byte 0x00', 'int 0', 'uncover 2', 'setbit'); } } @@ -1634,11 +1722,20 @@ export default class Compiler { const elem: TupleElement = new TupleElement(this.getABIType(type), 0); let offset = 0; + let consecutiveBools = 0; if (ts.isArrayLiteralExpression(expr)) { expr.elements.forEach((e) => { const abiType = this.getABIType(e.getText()); + if (abiType === 'bool') { + consecutiveBools += 1; + elem.add(new TupleElement('bool', offset)); + return; + } if (consecutiveBools) { + offset += Math.ceil(consecutiveBools / 8); + } + if (ts.isArrayLiteralExpression(e)) { const t = new TupleElement(abiType, offset); t.add(...this.getTupleElement(abiType)); @@ -1688,14 +1785,18 @@ export default class Compiler { const types = this.getarrayElementTypes(node.elements.length); const arrayTypeHint = typeHint; - node.elements.forEach((e, i) => { - this.typeHint = types[i]; - this.processNode(e); - if (isNumeric(this.lastType)) this.pushVoid(e, 'itob'); - if (this.lastType.match(/uint\d+$/) && this.lastType !== types[i]) this.fixBitWidth(e, parseInt(types[i].match(/\d+$/)![0], 10), !ts.isNumericLiteral(e)); - if (i) this.pushVoid(node, 'concat'); - }); + if (arrayTypeHint.match(/bool\[\d*\]$/)) { + this.processBools(node.elements, arrayTypeHint.endsWith('[]')); + } else { + node.elements.forEach((e, i) => { + this.typeHint = types[i]; + this.processNode(e); + if (isNumeric(this.lastType)) this.pushVoid(e, 'itob'); + if (this.lastType.match(/uint\d+$/) && this.lastType !== types[i]) this.fixBitWidth(e, parseInt(types[i].match(/\d+$/)![0], 10), !ts.isNumericLiteral(e)); + if (i) this.pushVoid(node, 'concat'); + }); + } const typeHintNode = stringToExpression(this.getABIType(arrayTypeHint)); if (ts.isElementAccessExpression(typeHintNode)) { @@ -1796,7 +1897,7 @@ export default class Compiler { node.expression.expression.name.getText() ]; - this.potentialLengthPrefix(node, storageProp.valueType); + this.checkEncoding(node, storageProp.valueType); this.storageFunctions[storageProp.type].set(node); } else { @@ -1925,6 +2026,7 @@ export default class Compiler { node: ts.Node, ) { let previousTupleElement = topLevelTuple; + let previousElemIsBool = false; // At the end of this forEach, the stack will contain the HEAD offset of the accessed element accessors.forEach((acc, i) => { @@ -1952,8 +2054,15 @@ export default class Compiler { const elem: TupleElement = Number.isNaN(accNumber) ? previousTupleElement[0] : previousTupleElement[accNumber] || previousTupleElement[0]; - // Element in tuple - if (previousTupleElement.arrayType === 'tuple') { + if (elem.type === 'bool' && !previousElemIsBool) { + this.pushLines( + acc, + `int ${elem.headOffset} // headOffset`, + '+', + ); + + previousElemIsBool = true; + } else if (previousTupleElement.arrayType === 'tuple') { this.pushLines( acc, `int ${elem.headOffset} // headOffset`, @@ -1970,7 +2079,7 @@ export default class Compiler { '+', ); // Static element in array - } else { + } else if (!previousElemIsBool) { this.processNode(acc); this.pushLines( @@ -2118,7 +2227,7 @@ export default class Compiler { this.processNode(newValue); if (isNumeric(this.lastType)) this.pushVoid(newValue, 'itob'); - this.potentialLengthPrefix(newValue, this.lastType); + this.checkEncoding(newValue, this.lastType); this.pushLines(newValue, 'dup', `store ${scratch.newElement}`); @@ -2160,6 +2269,19 @@ export default class Compiler { }); this.pushVoid(node, `load ${scratch.fullArray}`); + } else if (element.type === 'bool') { + if (!ts.isElementAccessExpression(node)) throw new Error(); + + this.pushLines(node.argumentExpression, 'int 8', '* // get bit offset'); + this.processNode(node.argumentExpression); + this.pushLines(node.argumentExpression, '+ // add accessor bits'); + if (element.parent!.arrayType === 'dynamic') { + this.pushLines(node.argumentExpression, 'int 16', '+ // 16 bits for length prefix'); + } + this.pushLines(node.argumentExpression, `load ${scratch.fullArray}`, 'swap'); + this.processNode(newValue); + + this.pushVoid(node.argumentExpression, 'setbit'); } else { this.pushLines( node, @@ -2173,15 +2295,25 @@ export default class Compiler { this.updateValue(parentExpression); } else { + if (element.type === 'bool') { + if (!ts.isElementAccessExpression(node)) throw new Error(); + + this.pushLines(node.argumentExpression, 'int 8', '*'); + this.processNode(node.argumentExpression); + this.pushLines(node.argumentExpression, '+', `load ${scratch.fullArray}`, 'swap', 'getbit'); + + this.lastType = 'bool'; + return; + } + if (!this.isDynamicType(element.type)) { this.pushLines(node, `load ${scratch.fullArray}`, 'swap', `int ${this.getTypeLength(element.type)}`, 'extract3'); } if (isNumeric(element.type)) this.pushVoid(node, 'btoi'); - if (this.isDynamicArrayOfStaticType(element.type)) { - this.pushVoid(node, 'extract 2 0'); - } + this.checkDecoding(node, element.type); + this.lastType = element.type.replace('string', 'bytes'); } } @@ -2284,6 +2416,7 @@ export default class Compiler { if (this.lastType === 'uint64') this.pushVoid(node.expression!, 'itob'); + console.log(this.lastType, returnType); this.pushVoid(node.expression!, `byte 0x${'FF'.repeat(returnBitWidth / 8)}`); this.pushVoid(node.expression!, 'b&'); @@ -2302,7 +2435,7 @@ export default class Compiler { } if (isAbiMethod) { - this.potentialLengthPrefix(node, returnType); + this.checkEncoding(node, returnType); this.pushLines(node, 'byte 0x151f7c75', 'swap', 'concat', 'log', 'retsub'); } else { this.pushVoid(node, 'retsub'); @@ -2419,6 +2552,10 @@ export default class Compiler { } else { this.push(node.operatorToken, operator, StackType.uint64); } + + if (operator === '==' || operator === '!=') { + this.lastType = 'bool'; + } } private processLogicalExpression(node: ts.BinaryExpression) { @@ -3258,9 +3395,7 @@ export default class Compiler { this.pushVoid(p, 'txn GroupIndex'); this.pushVoid(p, `int ${(gtxnIndex += 1)}`); this.pushVoid(p, '-'); - } else if (this.isDynamicArrayOfStaticType(type)) { - this.pushVoid(p, 'extract 2 0'); - } + } else this.checkDecoding(p, type); args.push({ name: p.name.getText(), type: this.getABIType(abiType).replace('bytes', 'byte[]'), desc: '' }); }); @@ -3435,7 +3570,7 @@ export default class Compiler { this.pushVoid(e, 'itob'); } else { this.processNode(e); - this.potentialLengthPrefix(e, argTypes[i]); + this.checkEncoding(e, argTypes[i]); } this.pushVoid(e, 'itxn_field ApplicationArgs'); }); @@ -3565,6 +3700,7 @@ export default class Compiler { const json = await response.json(); if (response.status !== 200) { + // eslint-disable-next-line no-console console.warn(this.approvalProgram().split('\n').map((l, i) => `${i + 1}: ${l}`).join('\n')); throw new Error(`${response.statusText}: ${json.message}`); diff --git a/tests/abi.test.ts b/tests/abi.test.ts index 4c279b7e2..4e241c14f 100644 --- a/tests/abi.test.ts +++ b/tests/abi.test.ts @@ -143,14 +143,19 @@ async function runMethod( sendParams: { suppressLog: true }, }; - if (name.includes('Storage')) { - await appClient.fundAppAccount({ - amount: algokit.microAlgos(127400), - sendParams: { suppressLog: true }, - }); - return (await appClient.optIn(params)).return?.returnValue; + try { + if (name.includes('Storage')) { + await appClient.fundAppAccount({ + amount: algokit.microAlgos(127400), + sendParams: { suppressLog: true }, + }); + return (await appClient.optIn(params)).return?.returnValue; + } + return (await appClient.call(params)).return?.returnValue; + } catch (e) { + console.warn(e); + throw e; } - return (await appClient.call(params)).return?.returnValue; } describe('ABI', function () { @@ -607,4 +612,65 @@ describe('ABI', function () { expect(await runMethod(appClient, 'emptyDynamicArray')).toEqual([]); }); + test.concurrent('booleanArgAndReturn', async () => { + const { appClient } = await compileAndCreate('booleanArgAndReturn'); + + expect(await runMethod(appClient, 'booleanArgAndReturn', [true])).toEqual(true); + + expect(await runMethod(appClient, 'booleanArgAndReturn', [false])).toEqual(false); + }); + + test.concurrent('boolTuple', async () => { + const { appClient } = await compileAndCreate('boolTuple'); + + expect(await runMethod(appClient, 'boolTuple')).toEqual([true, false, true, true, false, false, true, false, false]); + }); + + test.concurrent('staticBoolArray', async () => { + const { appClient } = await compileAndCreate('staticBoolArray'); + + expect(await runMethod(appClient, 'staticBoolArray')).toEqual([true, false, true, true, false, false, true, false, false]); + }); + + test.concurrent('boolTupleAccess', async () => { + const { appClient } = await compileAndCreate('boolTupleAccess'); + + expect(await runMethod(appClient, 'boolTupleAccess')).toEqual(true); + }); + + test.concurrent('staticBoolArrayAccess', async () => { + const { appClient } = await compileAndCreate('staticBoolArrayAccess'); + + expect(await runMethod(appClient, 'staticBoolArrayAccess')).toEqual(false); + }); + + test.concurrent('dynamicBoolArray', async () => { + const { appClient } = await compileAndCreate('dynamicBoolArray'); + + expect(await runMethod(appClient, 'dynamicBoolArray')).toEqual([true, false, true, true, false, false, true, false, false]); + }); + + test.concurrent('dynamicBoolArrayAccess', async () => { + const { appClient } = await compileAndCreate('dynamicBoolArrayAccess'); + + expect(await runMethod(appClient, 'dynamicBoolArrayAccess')).toEqual(false); + }); + + test.concurrent('staticBoolArrayUpdate', async () => { + const { appClient } = await compileAndCreate('staticBoolArrayUpdate'); + + expect(await runMethod(appClient, 'staticBoolArrayUpdate')).toEqual([true, false, true, true, false, false, true, false, true]); + }); + + test.concurrent('dynamicBoolArrayUpdate', async () => { + const { appClient } = await compileAndCreate('dynamicBoolArrayUpdate'); + + expect(await runMethod(appClient, 'dynamicBoolArrayUpdate')).toEqual([true, false, true, true, false, false, true, false, true]); + }); + + test.concurrent('boolTupleUpdate', async () => { + const { appClient } = await compileAndCreate('boolTupleUpdate'); + + expect(await runMethod(appClient, 'boolTupleUpdate')).toEqual([true, false, true, true, false, false, true, false, true]); + }); }); diff --git a/tests/contracts/abi.algo.ts b/tests/contracts/abi.algo.ts index 31762bbf0..18fc45a26 100644 --- a/tests/contracts/abi.algo.ts +++ b/tests/contracts/abi.algo.ts @@ -835,3 +835,95 @@ class ABITestEmptyDynamicArray extends Contract { return []; } } +class ABITestBooleanArgAndReturn extends Contract { + booleanArgAndReturn(a: boolean): boolean { + return a; + } +} + +class ABITestBoolTuple extends Contract { + boolTuple(): [boolean, boolean, boolean, boolean, boolean, boolean, boolean, boolean, boolean] { + const a: [boolean, boolean, boolean, boolean, boolean, boolean, boolean, boolean, boolean] = [ + true, false, true, true, false, false, true, false, false, + ]; + + return a; + } +} + +class ABITestStaticBoolArray extends Contract { + staticBoolArray(): StaticArray { + const a: StaticArray = [true, false, true, true, false, false, true, false, false]; + + return a; + } +} + +class ABITestBoolTupleAccess extends Contract { + boolTupleAccess(): boolean { + const a: [ + boolean, boolean, boolean, boolean, boolean, boolean, boolean, boolean, boolean + ] = [ + false, false, false, false, false, false, false, false, true, + ]; + + return a[8]; + } +} + +class ABITestStaticBoolArrayAccess extends Contract { + staticBoolArrayAccess(): boolean { + const a: StaticArray = [true, false, true, true, false, false, true, false, false]; + + return a[8]; + } +} + +class ABITestDynamicBoolArray extends Contract { + dynamicBoolArray(): boolean[] { + const a: boolean[] = [true, false, true, true, false, false, true, false, false]; + + return a; + } +} + +class ABITestDynamicBoolArrayAccess extends Contract { + dynamicBoolArrayAccess(): boolean { + const a: boolean[] = [true, false, true, true, false, false, true, false, false]; + + return a[8]; + } +} + +class ABITestStaticBoolArrayUpdate extends Contract { + staticBoolArrayUpdate(): StaticArray { + const a: StaticArray = [true, false, true, true, false, false, true, false, false]; + + a[8] = true; + + return a; + } +} + +class ABITestDynamicBoolArrayUpdate extends Contract { + dynamicBoolArrayUpdate(): boolean[] { + const a: boolean[] = [true, false, true, true, false, false, true, false, false]; + + a[8] = true; + + return a; + } +} + +class ABITestBoolTupleUpdate extends Contract { + boolTupleUpdate(): [ + boolean, boolean, boolean, boolean, boolean, boolean, boolean, boolean, boolean + ] { + const a: [ + boolean, boolean, boolean, boolean, boolean, boolean, boolean, boolean, boolean + ] = [true, false, true, true, false, false, true, false, false]; + + a[8] = true; + return a; + } +} diff --git a/tests/contracts/artifacts/ABITestBoolTuple.abi.json b/tests/contracts/artifacts/ABITestBoolTuple.abi.json new file mode 100644 index 000000000..7f77ca5e0 --- /dev/null +++ b/tests/contracts/artifacts/ABITestBoolTuple.abi.json @@ -0,0 +1,15 @@ +{ + "name": "ABITestBoolTuple", + "desc": "", + "methods": [ + { + "name": "boolTuple", + "args": [], + "desc": "", + "returns": { + "type": "(bool,bool,bool,bool,bool,bool,bool,bool,bool)", + "desc": "" + } + } + ] +} \ No newline at end of file diff --git a/tests/contracts/artifacts/ABITestBoolTuple.approval.teal b/tests/contracts/artifacts/ABITestBoolTuple.approval.teal new file mode 100644 index 000000000..914e014c9 --- /dev/null +++ b/tests/contracts/artifacts/ABITestBoolTuple.approval.teal @@ -0,0 +1,95 @@ +#pragma version 8 + b main + +abi_route_boolTuple: + txn OnCompletion + int NoOp + == + txn ApplicationID + int 0 + != + && + assert + byte 0x + callsub boolTuple + int 1 + return + +boolTuple: + proto 1 0 + + // tests/contracts/abi.algo.ts:846 + // a: [boolean, boolean, boolean, boolean, boolean, boolean, boolean, boolean, boolean] = [ + byte 0x // initial head + byte 0x // initial tail + byte 0x0002 // initial head offset + byte 0x0000 + int 0 + int 1 + setbit + int 1 + int 0 + setbit + int 2 + int 1 + setbit + int 3 + int 1 + setbit + int 4 + int 0 + setbit + int 5 + int 0 + setbit + int 6 + int 1 + setbit + int 7 + int 0 + setbit + int 8 + int 0 + setbit + callsub process_static_tuple_element + pop // pop head offset + concat // concat head and tail + frame_bury -1 // a: [bool,bool,bool,bool,bool,bool,bool,bool,bool] + + // tests/contracts/abi.algo.ts:850 + // return a; + frame_dig -1 // a: [bool,bool,bool,bool,bool,bool,bool,bool,bool] + byte 0x151f7c75 + swap + concat + log + retsub + +main: + txn NumAppArgs + bnz route_abi + + // default createApplication + txn ApplicationID + int 0 + == + txn OnCompletion + int NoOp + == + && + return + +route_abi: + method "boolTuple()(bool,bool,bool,bool,bool,bool,bool,bool,bool)" + txna ApplicationArgs 0 + match abi_route_boolTuple + err + +process_static_tuple_element: + proto 4 3 + frame_dig -4 // tuple head + frame_dig -1 // element + concat + frame_dig -3 // tuple tail + frame_dig -2 // head offset + retsub \ No newline at end of file diff --git a/tests/contracts/artifacts/ABITestBoolTuple.clear.teal b/tests/contracts/artifacts/ABITestBoolTuple.clear.teal new file mode 100644 index 000000000..31588a8ec --- /dev/null +++ b/tests/contracts/artifacts/ABITestBoolTuple.clear.teal @@ -0,0 +1,3 @@ +#pragma version 8 +int 1 +return \ No newline at end of file diff --git a/tests/contracts/artifacts/ABITestBoolTuple.json b/tests/contracts/artifacts/ABITestBoolTuple.json new file mode 100644 index 000000000..03e9b5d6c --- /dev/null +++ b/tests/contracts/artifacts/ABITestBoolTuple.json @@ -0,0 +1,51 @@ +{ + "hints": { + "boolTuple()(bool,bool,bool,bool,bool,bool,bool,bool,bool)": { + "call_config": { + "no_op": "CALL" + } + } + }, + "bare_call_config": { + "no_op": "CREATE" + }, + "schema": { + "local": { + "declared": {}, + "reserved": {} + }, + "global": { + "declared": {}, + "reserved": {} + } + }, + "state": { + "global": { + "num_byte_slices": 0, + "num_uints": 0 + }, + "local": { + "num_byte_slices": 0, + "num_uints": 0 + } + }, + "source": { + "approval": "I3ByYWdtYSB2ZXJzaW9uIDgKCWIgbWFpbgoKYWJpX3JvdXRlX2Jvb2xUdXBsZToKCXR4biBPbkNvbXBsZXRpb24KCWludCBOb09wCgk9PQoJdHhuIEFwcGxpY2F0aW9uSUQKCWludCAwCgkhPQoJJiYKCWFzc2VydAoJYnl0ZSAweAoJY2FsbHN1YiBib29sVHVwbGUKCWludCAxCglyZXR1cm4KCmJvb2xUdXBsZToKCXByb3RvIDEgMAoKCS8vIHRlc3RzL2NvbnRyYWN0cy9hYmkuYWxnby50czo4NDYKCS8vIGE6IFtib29sZWFuLCBib29sZWFuLCBib29sZWFuLCBib29sZWFuLCBib29sZWFuLCBib29sZWFuLCBib29sZWFuLCBib29sZWFuLCBib29sZWFuXSA9IFsKCWJ5dGUgMHggLy8gaW5pdGlhbCBoZWFkCglieXRlIDB4IC8vIGluaXRpYWwgdGFpbAoJYnl0ZSAweDAwMDIgLy8gaW5pdGlhbCBoZWFkIG9mZnNldAoJYnl0ZSAweDAwMDAKCWludCAwCglpbnQgMQoJc2V0Yml0CglpbnQgMQoJaW50IDAKCXNldGJpdAoJaW50IDIKCWludCAxCglzZXRiaXQKCWludCAzCglpbnQgMQoJc2V0Yml0CglpbnQgNAoJaW50IDAKCXNldGJpdAoJaW50IDUKCWludCAwCglzZXRiaXQKCWludCA2CglpbnQgMQoJc2V0Yml0CglpbnQgNwoJaW50IDAKCXNldGJpdAoJaW50IDgKCWludCAwCglzZXRiaXQKCWNhbGxzdWIgcHJvY2Vzc19zdGF0aWNfdHVwbGVfZWxlbWVudAoJcG9wIC8vIHBvcCBoZWFkIG9mZnNldAoJY29uY2F0IC8vIGNvbmNhdCBoZWFkIGFuZCB0YWlsCglmcmFtZV9idXJ5IC0xIC8vIGE6IFtib29sLGJvb2wsYm9vbCxib29sLGJvb2wsYm9vbCxib29sLGJvb2wsYm9vbF0KCgkvLyB0ZXN0cy9jb250cmFjdHMvYWJpLmFsZ28udHM6ODUwCgkvLyByZXR1cm4gYTsKCWZyYW1lX2RpZyAtMSAvLyBhOiBbYm9vbCxib29sLGJvb2wsYm9vbCxib29sLGJvb2wsYm9vbCxib29sLGJvb2xdCglieXRlIDB4MTUxZjdjNzUKCXN3YXAKCWNvbmNhdAoJbG9nCglyZXRzdWIKCm1haW46Cgl0eG4gTnVtQXBwQXJncwoJYm56IHJvdXRlX2FiaQoKCS8vIGRlZmF1bHQgY3JlYXRlQXBwbGljYXRpb24KCXR4biBBcHBsaWNhdGlvbklECglpbnQgMAoJPT0KCXR4biBPbkNvbXBsZXRpb24KCWludCBOb09wCgk9PQoJJiYKCXJldHVybgoKcm91dGVfYWJpOgoJbWV0aG9kICJib29sVHVwbGUoKShib29sLGJvb2wsYm9vbCxib29sLGJvb2wsYm9vbCxib29sLGJvb2wsYm9vbCkiCgl0eG5hIEFwcGxpY2F0aW9uQXJncyAwCgltYXRjaCBhYmlfcm91dGVfYm9vbFR1cGxlCgllcnIKCnByb2Nlc3Nfc3RhdGljX3R1cGxlX2VsZW1lbnQ6Cglwcm90byA0IDMKCWZyYW1lX2RpZyAtNCAvLyB0dXBsZSBoZWFkCglmcmFtZV9kaWcgLTEgLy8gZWxlbWVudAoJY29uY2F0CglmcmFtZV9kaWcgLTMgLy8gdHVwbGUgdGFpbAoJZnJhbWVfZGlnIC0yIC8vIGhlYWQgb2Zmc2V0CglyZXRzdWI=", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDgKaW50IDEKcmV0dXJu" + }, + "contract": { + "name": "ABITestBoolTuple", + "desc": "", + "methods": [ + { + "name": "boolTuple", + "args": [], + "desc": "", + "returns": { + "type": "(bool,bool,bool,bool,bool,bool,bool,bool,bool)", + "desc": "" + } + } + ] + } +} \ No newline at end of file diff --git a/tests/contracts/artifacts/ABITestBoolTupleAccess.abi.json b/tests/contracts/artifacts/ABITestBoolTupleAccess.abi.json new file mode 100644 index 000000000..cdb62f07b --- /dev/null +++ b/tests/contracts/artifacts/ABITestBoolTupleAccess.abi.json @@ -0,0 +1,15 @@ +{ + "name": "ABITestBoolTupleAccess", + "desc": "", + "methods": [ + { + "name": "boolTupleAccess", + "args": [], + "desc": "", + "returns": { + "type": "bool", + "desc": "" + } + } + ] +} \ No newline at end of file diff --git a/tests/contracts/artifacts/ABITestBoolTupleAccess.approval.teal b/tests/contracts/artifacts/ABITestBoolTupleAccess.approval.teal new file mode 100644 index 000000000..60c24429d --- /dev/null +++ b/tests/contracts/artifacts/ABITestBoolTupleAccess.approval.teal @@ -0,0 +1,110 @@ +#pragma version 8 + b main + +abi_route_boolTupleAccess: + txn OnCompletion + int NoOp + == + txn ApplicationID + int 0 + != + && + assert + byte 0x + callsub boolTupleAccess + int 1 + return + +boolTupleAccess: + proto 1 0 + + // tests/contracts/abi.algo.ts:864 + // a: [ + byte 0x // initial head + byte 0x // initial tail + byte 0x0002 // initial head offset + byte 0x0000 + int 0 + int 0 + setbit + int 1 + int 0 + setbit + int 2 + int 0 + setbit + int 3 + int 0 + setbit + int 4 + int 0 + setbit + int 5 + int 0 + setbit + int 6 + int 0 + setbit + int 7 + int 0 + setbit + int 8 + int 1 + setbit + callsub process_static_tuple_element + pop // pop head offset + concat // concat head and tail + frame_bury -1 // a: [bool,bool,bool,bool,bool,bool,bool,bool,bool] + + // tests/contracts/abi.algo.ts:870 + // return a[8]; + frame_dig -1 // a: [bool,bool,bool,bool,bool,bool,bool,bool,bool] + store 0 // full array + int 0 // initial offset + int 0 // headOffset + + + int 8 + * + int 8 + + + load 0 // full array + swap + getbit + byte 0x00 + int 0 + uncover 2 + setbit + byte 0x151f7c75 + swap + concat + log + retsub + +main: + txn NumAppArgs + bnz route_abi + + // default createApplication + txn ApplicationID + int 0 + == + txn OnCompletion + int NoOp + == + && + return + +route_abi: + method "boolTupleAccess()bool" + txna ApplicationArgs 0 + match abi_route_boolTupleAccess + err + +process_static_tuple_element: + proto 4 3 + frame_dig -4 // tuple head + frame_dig -1 // element + concat + frame_dig -3 // tuple tail + frame_dig -2 // head offset + retsub \ No newline at end of file diff --git a/tests/contracts/artifacts/ABITestBoolTupleAccess.clear.teal b/tests/contracts/artifacts/ABITestBoolTupleAccess.clear.teal new file mode 100644 index 000000000..31588a8ec --- /dev/null +++ b/tests/contracts/artifacts/ABITestBoolTupleAccess.clear.teal @@ -0,0 +1,3 @@ +#pragma version 8 +int 1 +return \ No newline at end of file diff --git a/tests/contracts/artifacts/ABITestBoolTupleAccess.json b/tests/contracts/artifacts/ABITestBoolTupleAccess.json new file mode 100644 index 000000000..4c1413c28 --- /dev/null +++ b/tests/contracts/artifacts/ABITestBoolTupleAccess.json @@ -0,0 +1,51 @@ +{ + "hints": { + "boolTupleAccess()bool": { + "call_config": { + "no_op": "CALL" + } + } + }, + "bare_call_config": { + "no_op": "CREATE" + }, + "schema": { + "local": { + "declared": {}, + "reserved": {} + }, + "global": { + "declared": {}, + "reserved": {} + } + }, + "state": { + "global": { + "num_byte_slices": 0, + "num_uints": 0 + }, + "local": { + "num_byte_slices": 0, + "num_uints": 0 + } + }, + "source": { + "approval": "I3ByYWdtYSB2ZXJzaW9uIDgKCWIgbWFpbgoKYWJpX3JvdXRlX2Jvb2xUdXBsZUFjY2VzczoKCXR4biBPbkNvbXBsZXRpb24KCWludCBOb09wCgk9PQoJdHhuIEFwcGxpY2F0aW9uSUQKCWludCAwCgkhPQoJJiYKCWFzc2VydAoJYnl0ZSAweAoJY2FsbHN1YiBib29sVHVwbGVBY2Nlc3MKCWludCAxCglyZXR1cm4KCmJvb2xUdXBsZUFjY2VzczoKCXByb3RvIDEgMAoKCS8vIHRlc3RzL2NvbnRyYWN0cy9hYmkuYWxnby50czo4NjQKCS8vIGE6IFsKCWJ5dGUgMHggLy8gaW5pdGlhbCBoZWFkCglieXRlIDB4IC8vIGluaXRpYWwgdGFpbAoJYnl0ZSAweDAwMDIgLy8gaW5pdGlhbCBoZWFkIG9mZnNldAoJYnl0ZSAweDAwMDAKCWludCAwCglpbnQgMAoJc2V0Yml0CglpbnQgMQoJaW50IDAKCXNldGJpdAoJaW50IDIKCWludCAwCglzZXRiaXQKCWludCAzCglpbnQgMAoJc2V0Yml0CglpbnQgNAoJaW50IDAKCXNldGJpdAoJaW50IDUKCWludCAwCglzZXRiaXQKCWludCA2CglpbnQgMAoJc2V0Yml0CglpbnQgNwoJaW50IDAKCXNldGJpdAoJaW50IDgKCWludCAxCglzZXRiaXQKCWNhbGxzdWIgcHJvY2Vzc19zdGF0aWNfdHVwbGVfZWxlbWVudAoJcG9wIC8vIHBvcCBoZWFkIG9mZnNldAoJY29uY2F0IC8vIGNvbmNhdCBoZWFkIGFuZCB0YWlsCglmcmFtZV9idXJ5IC0xIC8vIGE6IFtib29sLGJvb2wsYm9vbCxib29sLGJvb2wsYm9vbCxib29sLGJvb2wsYm9vbF0KCgkvLyB0ZXN0cy9jb250cmFjdHMvYWJpLmFsZ28udHM6ODcwCgkvLyByZXR1cm4gYVs4XTsKCWZyYW1lX2RpZyAtMSAvLyBhOiBbYm9vbCxib29sLGJvb2wsYm9vbCxib29sLGJvb2wsYm9vbCxib29sLGJvb2xdCglzdG9yZSAwIC8vIGZ1bGwgYXJyYXkKCWludCAwIC8vIGluaXRpYWwgb2Zmc2V0CglpbnQgMCAvLyBoZWFkT2Zmc2V0CgkrCglpbnQgOAoJKgoJaW50IDgKCSsKCWxvYWQgMCAvLyBmdWxsIGFycmF5Cglzd2FwCglnZXRiaXQKCWJ5dGUgMHgwMAoJaW50IDAKCXVuY292ZXIgMgoJc2V0Yml0CglieXRlIDB4MTUxZjdjNzUKCXN3YXAKCWNvbmNhdAoJbG9nCglyZXRzdWIKCm1haW46Cgl0eG4gTnVtQXBwQXJncwoJYm56IHJvdXRlX2FiaQoKCS8vIGRlZmF1bHQgY3JlYXRlQXBwbGljYXRpb24KCXR4biBBcHBsaWNhdGlvbklECglpbnQgMAoJPT0KCXR4biBPbkNvbXBsZXRpb24KCWludCBOb09wCgk9PQoJJiYKCXJldHVybgoKcm91dGVfYWJpOgoJbWV0aG9kICJib29sVHVwbGVBY2Nlc3MoKWJvb2wiCgl0eG5hIEFwcGxpY2F0aW9uQXJncyAwCgltYXRjaCBhYmlfcm91dGVfYm9vbFR1cGxlQWNjZXNzCgllcnIKCnByb2Nlc3Nfc3RhdGljX3R1cGxlX2VsZW1lbnQ6Cglwcm90byA0IDMKCWZyYW1lX2RpZyAtNCAvLyB0dXBsZSBoZWFkCglmcmFtZV9kaWcgLTEgLy8gZWxlbWVudAoJY29uY2F0CglmcmFtZV9kaWcgLTMgLy8gdHVwbGUgdGFpbAoJZnJhbWVfZGlnIC0yIC8vIGhlYWQgb2Zmc2V0CglyZXRzdWI=", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDgKaW50IDEKcmV0dXJu" + }, + "contract": { + "name": "ABITestBoolTupleAccess", + "desc": "", + "methods": [ + { + "name": "boolTupleAccess", + "args": [], + "desc": "", + "returns": { + "type": "bool", + "desc": "" + } + } + ] + } +} \ No newline at end of file diff --git a/tests/contracts/artifacts/ABITestBoolTupleUpdate.abi.json b/tests/contracts/artifacts/ABITestBoolTupleUpdate.abi.json new file mode 100644 index 000000000..bd291143d --- /dev/null +++ b/tests/contracts/artifacts/ABITestBoolTupleUpdate.abi.json @@ -0,0 +1,15 @@ +{ + "name": "ABITestBoolTupleUpdate", + "desc": "", + "methods": [ + { + "name": "boolTupleUpdate", + "args": [], + "desc": "", + "returns": { + "type": "(bool,bool,bool,bool,bool,bool,bool,bool,bool)", + "desc": "" + } + } + ] +} \ No newline at end of file diff --git a/tests/contracts/artifacts/ABITestBoolTupleUpdate.approval.teal b/tests/contracts/artifacts/ABITestBoolTupleUpdate.approval.teal new file mode 100644 index 000000000..77152a90b --- /dev/null +++ b/tests/contracts/artifacts/ABITestBoolTupleUpdate.approval.teal @@ -0,0 +1,112 @@ +#pragma version 8 + b main + +abi_route_boolTupleUpdate: + txn OnCompletion + int NoOp + == + txn ApplicationID + int 0 + != + && + assert + byte 0x + callsub boolTupleUpdate + int 1 + return + +boolTupleUpdate: + proto 1 0 + + // tests/contracts/abi.algo.ts:922 + // a: [ + byte 0x // initial head + byte 0x // initial tail + byte 0x0002 // initial head offset + byte 0x0000 + int 0 + int 1 + setbit + int 1 + int 0 + setbit + int 2 + int 1 + setbit + int 3 + int 1 + setbit + int 4 + int 0 + setbit + int 5 + int 0 + setbit + int 6 + int 1 + setbit + int 7 + int 0 + setbit + int 8 + int 0 + setbit + callsub process_static_tuple_element + pop // pop head offset + concat // concat head and tail + frame_bury -1 // a: [bool,bool,bool,bool,bool,bool,bool,bool,bool] + + // tests/contracts/abi.algo.ts:926 + // a[8] = true + frame_dig -1 // a: [bool,bool,bool,bool,bool,bool,bool,bool,bool] + store 0 // full array + int 0 // initial offset + int 0 // headOffset + + + int 8 + * // get bit offset + int 8 + + // add accessor bits + load 0 // full array + swap + int 1 + setbit + frame_bury -1 // a: [bool,bool,bool,bool,bool,bool,bool,bool,bool] + + // tests/contracts/abi.algo.ts:927 + // return a; + frame_dig -1 // a: [bool,bool,bool,bool,bool,bool,bool,bool,bool] + byte 0x151f7c75 + swap + concat + log + retsub + +main: + txn NumAppArgs + bnz route_abi + + // default createApplication + txn ApplicationID + int 0 + == + txn OnCompletion + int NoOp + == + && + return + +route_abi: + method "boolTupleUpdate()(bool,bool,bool,bool,bool,bool,bool,bool,bool)" + txna ApplicationArgs 0 + match abi_route_boolTupleUpdate + err + +process_static_tuple_element: + proto 4 3 + frame_dig -4 // tuple head + frame_dig -1 // element + concat + frame_dig -3 // tuple tail + frame_dig -2 // head offset + retsub \ No newline at end of file diff --git a/tests/contracts/artifacts/ABITestBoolTupleUpdate.clear.teal b/tests/contracts/artifacts/ABITestBoolTupleUpdate.clear.teal new file mode 100644 index 000000000..31588a8ec --- /dev/null +++ b/tests/contracts/artifacts/ABITestBoolTupleUpdate.clear.teal @@ -0,0 +1,3 @@ +#pragma version 8 +int 1 +return \ No newline at end of file diff --git a/tests/contracts/artifacts/ABITestBoolTupleUpdate.json b/tests/contracts/artifacts/ABITestBoolTupleUpdate.json new file mode 100644 index 000000000..213d19376 --- /dev/null +++ b/tests/contracts/artifacts/ABITestBoolTupleUpdate.json @@ -0,0 +1,51 @@ +{ + "hints": { + "boolTupleUpdate()(bool,bool,bool,bool,bool,bool,bool,bool,bool)": { + "call_config": { + "no_op": "CALL" + } + } + }, + "bare_call_config": { + "no_op": "CREATE" + }, + "schema": { + "local": { + "declared": {}, + "reserved": {} + }, + "global": { + "declared": {}, + "reserved": {} + } + }, + "state": { + "global": { + "num_byte_slices": 0, + "num_uints": 0 + }, + "local": { + "num_byte_slices": 0, + "num_uints": 0 + } + }, + "source": { + "approval": "I3ByYWdtYSB2ZXJzaW9uIDgKCWIgbWFpbgoKYWJpX3JvdXRlX2Jvb2xUdXBsZVVwZGF0ZToKCXR4biBPbkNvbXBsZXRpb24KCWludCBOb09wCgk9PQoJdHhuIEFwcGxpY2F0aW9uSUQKCWludCAwCgkhPQoJJiYKCWFzc2VydAoJYnl0ZSAweAoJY2FsbHN1YiBib29sVHVwbGVVcGRhdGUKCWludCAxCglyZXR1cm4KCmJvb2xUdXBsZVVwZGF0ZToKCXByb3RvIDEgMAoKCS8vIHRlc3RzL2NvbnRyYWN0cy9hYmkuYWxnby50czo5MjIKCS8vIGE6IFsKCWJ5dGUgMHggLy8gaW5pdGlhbCBoZWFkCglieXRlIDB4IC8vIGluaXRpYWwgdGFpbAoJYnl0ZSAweDAwMDIgLy8gaW5pdGlhbCBoZWFkIG9mZnNldAoJYnl0ZSAweDAwMDAKCWludCAwCglpbnQgMQoJc2V0Yml0CglpbnQgMQoJaW50IDAKCXNldGJpdAoJaW50IDIKCWludCAxCglzZXRiaXQKCWludCAzCglpbnQgMQoJc2V0Yml0CglpbnQgNAoJaW50IDAKCXNldGJpdAoJaW50IDUKCWludCAwCglzZXRiaXQKCWludCA2CglpbnQgMQoJc2V0Yml0CglpbnQgNwoJaW50IDAKCXNldGJpdAoJaW50IDgKCWludCAwCglzZXRiaXQKCWNhbGxzdWIgcHJvY2Vzc19zdGF0aWNfdHVwbGVfZWxlbWVudAoJcG9wIC8vIHBvcCBoZWFkIG9mZnNldAoJY29uY2F0IC8vIGNvbmNhdCBoZWFkIGFuZCB0YWlsCglmcmFtZV9idXJ5IC0xIC8vIGE6IFtib29sLGJvb2wsYm9vbCxib29sLGJvb2wsYm9vbCxib29sLGJvb2wsYm9vbF0KCgkvLyB0ZXN0cy9jb250cmFjdHMvYWJpLmFsZ28udHM6OTI2CgkvLyBhWzhdID0gdHJ1ZQoJZnJhbWVfZGlnIC0xIC8vIGE6IFtib29sLGJvb2wsYm9vbCxib29sLGJvb2wsYm9vbCxib29sLGJvb2wsYm9vbF0KCXN0b3JlIDAgLy8gZnVsbCBhcnJheQoJaW50IDAgLy8gaW5pdGlhbCBvZmZzZXQKCWludCAwIC8vIGhlYWRPZmZzZXQKCSsKCWludCA4CgkqIC8vIGdldCBiaXQgb2Zmc2V0CglpbnQgOAoJKyAvLyBhZGQgYWNjZXNzb3IgYml0cwoJbG9hZCAwIC8vIGZ1bGwgYXJyYXkKCXN3YXAKCWludCAxCglzZXRiaXQKCWZyYW1lX2J1cnkgLTEgLy8gYTogW2Jvb2wsYm9vbCxib29sLGJvb2wsYm9vbCxib29sLGJvb2wsYm9vbCxib29sXQoKCS8vIHRlc3RzL2NvbnRyYWN0cy9hYmkuYWxnby50czo5MjcKCS8vIHJldHVybiBhOwoJZnJhbWVfZGlnIC0xIC8vIGE6IFtib29sLGJvb2wsYm9vbCxib29sLGJvb2wsYm9vbCxib29sLGJvb2wsYm9vbF0KCWJ5dGUgMHgxNTFmN2M3NQoJc3dhcAoJY29uY2F0Cglsb2cKCXJldHN1YgoKbWFpbjoKCXR4biBOdW1BcHBBcmdzCglibnogcm91dGVfYWJpCgoJLy8gZGVmYXVsdCBjcmVhdGVBcHBsaWNhdGlvbgoJdHhuIEFwcGxpY2F0aW9uSUQKCWludCAwCgk9PQoJdHhuIE9uQ29tcGxldGlvbgoJaW50IE5vT3AKCT09CgkmJgoJcmV0dXJuCgpyb3V0ZV9hYmk6CgltZXRob2QgImJvb2xUdXBsZVVwZGF0ZSgpKGJvb2wsYm9vbCxib29sLGJvb2wsYm9vbCxib29sLGJvb2wsYm9vbCxib29sKSIKCXR4bmEgQXBwbGljYXRpb25BcmdzIDAKCW1hdGNoIGFiaV9yb3V0ZV9ib29sVHVwbGVVcGRhdGUKCWVycgoKcHJvY2Vzc19zdGF0aWNfdHVwbGVfZWxlbWVudDoKCXByb3RvIDQgMwoJZnJhbWVfZGlnIC00IC8vIHR1cGxlIGhlYWQKCWZyYW1lX2RpZyAtMSAvLyBlbGVtZW50Cgljb25jYXQKCWZyYW1lX2RpZyAtMyAvLyB0dXBsZSB0YWlsCglmcmFtZV9kaWcgLTIgLy8gaGVhZCBvZmZzZXQKCXJldHN1Yg==", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDgKaW50IDEKcmV0dXJu" + }, + "contract": { + "name": "ABITestBoolTupleUpdate", + "desc": "", + "methods": [ + { + "name": "boolTupleUpdate", + "args": [], + "desc": "", + "returns": { + "type": "(bool,bool,bool,bool,bool,bool,bool,bool,bool)", + "desc": "" + } + } + ] + } +} \ No newline at end of file diff --git a/tests/contracts/artifacts/ABITestBooleanArgAndReturn.abi.json b/tests/contracts/artifacts/ABITestBooleanArgAndReturn.abi.json new file mode 100644 index 000000000..609498125 --- /dev/null +++ b/tests/contracts/artifacts/ABITestBooleanArgAndReturn.abi.json @@ -0,0 +1,21 @@ +{ + "name": "ABITestBooleanArgAndReturn", + "desc": "", + "methods": [ + { + "name": "booleanArgAndReturn", + "args": [ + { + "name": "a", + "type": "bool", + "desc": "" + } + ], + "desc": "", + "returns": { + "type": "bool", + "desc": "" + } + } + ] +} \ No newline at end of file diff --git a/tests/contracts/artifacts/ABITestBooleanArgAndReturn.approval.teal b/tests/contracts/artifacts/ABITestBooleanArgAndReturn.approval.teal new file mode 100644 index 000000000..0835bbe41 --- /dev/null +++ b/tests/contracts/artifacts/ABITestBooleanArgAndReturn.approval.teal @@ -0,0 +1,56 @@ +#pragma version 8 + b main + +abi_route_booleanArgAndReturn: + txn OnCompletion + int NoOp + == + txn ApplicationID + int 0 + != + && + assert + + // no dupn needed + txna ApplicationArgs 1 + int 0 + getbit + callsub booleanArgAndReturn + int 1 + return + +booleanArgAndReturn: + proto 1 0 + + // tests/contracts/abi.algo.ts:840 + // return a; + frame_dig -1 // a: bool + byte 0x00 + int 0 + uncover 2 + setbit + byte 0x151f7c75 + swap + concat + log + retsub + +main: + txn NumAppArgs + bnz route_abi + + // default createApplication + txn ApplicationID + int 0 + == + txn OnCompletion + int NoOp + == + && + return + +route_abi: + method "booleanArgAndReturn(bool)bool" + txna ApplicationArgs 0 + match abi_route_booleanArgAndReturn + err \ No newline at end of file diff --git a/tests/contracts/artifacts/ABITestBooleanArgAndReturn.clear.teal b/tests/contracts/artifacts/ABITestBooleanArgAndReturn.clear.teal new file mode 100644 index 000000000..31588a8ec --- /dev/null +++ b/tests/contracts/artifacts/ABITestBooleanArgAndReturn.clear.teal @@ -0,0 +1,3 @@ +#pragma version 8 +int 1 +return \ No newline at end of file diff --git a/tests/contracts/artifacts/ABITestBooleanArgAndReturn.json b/tests/contracts/artifacts/ABITestBooleanArgAndReturn.json new file mode 100644 index 000000000..9f6b97b86 --- /dev/null +++ b/tests/contracts/artifacts/ABITestBooleanArgAndReturn.json @@ -0,0 +1,57 @@ +{ + "hints": { + "booleanArgAndReturn(bool)bool": { + "call_config": { + "no_op": "CALL" + } + } + }, + "bare_call_config": { + "no_op": "CREATE" + }, + "schema": { + "local": { + "declared": {}, + "reserved": {} + }, + "global": { + "declared": {}, + "reserved": {} + } + }, + "state": { + "global": { + "num_byte_slices": 0, + "num_uints": 0 + }, + "local": { + "num_byte_slices": 0, + "num_uints": 0 + } + }, + "source": { + "approval": "I3ByYWdtYSB2ZXJzaW9uIDgKCWIgbWFpbgoKYWJpX3JvdXRlX2Jvb2xlYW5BcmdBbmRSZXR1cm46Cgl0eG4gT25Db21wbGV0aW9uCglpbnQgTm9PcAoJPT0KCXR4biBBcHBsaWNhdGlvbklECglpbnQgMAoJIT0KCSYmCglhc3NlcnQKCgkvLyBubyBkdXBuIG5lZWRlZAoJdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQoJaW50IDAKCWdldGJpdAoJY2FsbHN1YiBib29sZWFuQXJnQW5kUmV0dXJuCglpbnQgMQoJcmV0dXJuCgpib29sZWFuQXJnQW5kUmV0dXJuOgoJcHJvdG8gMSAwCgoJLy8gdGVzdHMvY29udHJhY3RzL2FiaS5hbGdvLnRzOjg0MAoJLy8gcmV0dXJuIGE7CglmcmFtZV9kaWcgLTEgLy8gYTogYm9vbAoJYnl0ZSAweDAwCglpbnQgMAoJdW5jb3ZlciAyCglzZXRiaXQKCWJ5dGUgMHgxNTFmN2M3NQoJc3dhcAoJY29uY2F0Cglsb2cKCXJldHN1YgoKbWFpbjoKCXR4biBOdW1BcHBBcmdzCglibnogcm91dGVfYWJpCgoJLy8gZGVmYXVsdCBjcmVhdGVBcHBsaWNhdGlvbgoJdHhuIEFwcGxpY2F0aW9uSUQKCWludCAwCgk9PQoJdHhuIE9uQ29tcGxldGlvbgoJaW50IE5vT3AKCT09CgkmJgoJcmV0dXJuCgpyb3V0ZV9hYmk6CgltZXRob2QgImJvb2xlYW5BcmdBbmRSZXR1cm4oYm9vbClib29sIgoJdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMAoJbWF0Y2ggYWJpX3JvdXRlX2Jvb2xlYW5BcmdBbmRSZXR1cm4KCWVycg==", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDgKaW50IDEKcmV0dXJu" + }, + "contract": { + "name": "ABITestBooleanArgAndReturn", + "desc": "", + "methods": [ + { + "name": "booleanArgAndReturn", + "args": [ + { + "name": "a", + "type": "bool", + "desc": "" + } + ], + "desc": "", + "returns": { + "type": "bool", + "desc": "" + } + } + ] + } +} \ No newline at end of file diff --git a/tests/contracts/artifacts/ABITestDynamicBoolArray.abi.json b/tests/contracts/artifacts/ABITestDynamicBoolArray.abi.json new file mode 100644 index 000000000..644654b36 --- /dev/null +++ b/tests/contracts/artifacts/ABITestDynamicBoolArray.abi.json @@ -0,0 +1,15 @@ +{ + "name": "ABITestDynamicBoolArray", + "desc": "", + "methods": [ + { + "name": "dynamicBoolArray", + "args": [], + "desc": "", + "returns": { + "type": "bool[]", + "desc": "" + } + } + ] +} \ No newline at end of file diff --git a/tests/contracts/artifacts/ABITestDynamicBoolArray.approval.teal b/tests/contracts/artifacts/ABITestDynamicBoolArray.approval.teal new file mode 100644 index 000000000..2820dfd8d --- /dev/null +++ b/tests/contracts/artifacts/ABITestDynamicBoolArray.approval.teal @@ -0,0 +1,82 @@ +#pragma version 8 + b main + +abi_route_dynamicBoolArray: + txn OnCompletion + int NoOp + == + txn ApplicationID + int 0 + != + && + assert + byte 0x + callsub dynamicBoolArray + int 1 + return + +dynamicBoolArray: + proto 1 0 + + // tests/contracts/abi.algo.ts:884 + // a: boolean[] = [true, false, true, true, false, false, true, false, false] + byte 0x0009 + byte 0x0000 + int 0 + int 1 + setbit + int 1 + int 0 + setbit + int 2 + int 1 + setbit + int 3 + int 1 + setbit + int 4 + int 0 + setbit + int 5 + int 0 + setbit + int 6 + int 1 + setbit + int 7 + int 0 + setbit + int 8 + int 0 + setbit + concat + frame_bury -1 // a: bool[] + + // tests/contracts/abi.algo.ts:886 + // return a; + frame_dig -1 // a: bool[] + byte 0x151f7c75 + swap + concat + log + retsub + +main: + txn NumAppArgs + bnz route_abi + + // default createApplication + txn ApplicationID + int 0 + == + txn OnCompletion + int NoOp + == + && + return + +route_abi: + method "dynamicBoolArray()bool[]" + txna ApplicationArgs 0 + match abi_route_dynamicBoolArray + err \ No newline at end of file diff --git a/tests/contracts/artifacts/ABITestDynamicBoolArray.clear.teal b/tests/contracts/artifacts/ABITestDynamicBoolArray.clear.teal new file mode 100644 index 000000000..31588a8ec --- /dev/null +++ b/tests/contracts/artifacts/ABITestDynamicBoolArray.clear.teal @@ -0,0 +1,3 @@ +#pragma version 8 +int 1 +return \ No newline at end of file diff --git a/tests/contracts/artifacts/ABITestDynamicBoolArray.json b/tests/contracts/artifacts/ABITestDynamicBoolArray.json new file mode 100644 index 000000000..b33314578 --- /dev/null +++ b/tests/contracts/artifacts/ABITestDynamicBoolArray.json @@ -0,0 +1,51 @@ +{ + "hints": { + "dynamicBoolArray()bool[]": { + "call_config": { + "no_op": "CALL" + } + } + }, + "bare_call_config": { + "no_op": "CREATE" + }, + "schema": { + "local": { + "declared": {}, + "reserved": {} + }, + "global": { + "declared": {}, + "reserved": {} + } + }, + "state": { + "global": { + "num_byte_slices": 0, + "num_uints": 0 + }, + "local": { + "num_byte_slices": 0, + "num_uints": 0 + } + }, + "source": { + "approval": "I3ByYWdtYSB2ZXJzaW9uIDgKCWIgbWFpbgoKYWJpX3JvdXRlX2R5bmFtaWNCb29sQXJyYXk6Cgl0eG4gT25Db21wbGV0aW9uCglpbnQgTm9PcAoJPT0KCXR4biBBcHBsaWNhdGlvbklECglpbnQgMAoJIT0KCSYmCglhc3NlcnQKCWJ5dGUgMHgKCWNhbGxzdWIgZHluYW1pY0Jvb2xBcnJheQoJaW50IDEKCXJldHVybgoKZHluYW1pY0Jvb2xBcnJheToKCXByb3RvIDEgMAoKCS8vIHRlc3RzL2NvbnRyYWN0cy9hYmkuYWxnby50czo4ODQKCS8vIGE6IGJvb2xlYW5bXSA9IFt0cnVlLCBmYWxzZSwgdHJ1ZSwgdHJ1ZSwgZmFsc2UsIGZhbHNlLCB0cnVlLCBmYWxzZSwgZmFsc2VdCglieXRlIDB4MDAwOQoJYnl0ZSAweDAwMDAKCWludCAwCglpbnQgMQoJc2V0Yml0CglpbnQgMQoJaW50IDAKCXNldGJpdAoJaW50IDIKCWludCAxCglzZXRiaXQKCWludCAzCglpbnQgMQoJc2V0Yml0CglpbnQgNAoJaW50IDAKCXNldGJpdAoJaW50IDUKCWludCAwCglzZXRiaXQKCWludCA2CglpbnQgMQoJc2V0Yml0CglpbnQgNwoJaW50IDAKCXNldGJpdAoJaW50IDgKCWludCAwCglzZXRiaXQKCWNvbmNhdAoJZnJhbWVfYnVyeSAtMSAvLyBhOiBib29sW10KCgkvLyB0ZXN0cy9jb250cmFjdHMvYWJpLmFsZ28udHM6ODg2CgkvLyByZXR1cm4gYTsKCWZyYW1lX2RpZyAtMSAvLyBhOiBib29sW10KCWJ5dGUgMHgxNTFmN2M3NQoJc3dhcAoJY29uY2F0Cglsb2cKCXJldHN1YgoKbWFpbjoKCXR4biBOdW1BcHBBcmdzCglibnogcm91dGVfYWJpCgoJLy8gZGVmYXVsdCBjcmVhdGVBcHBsaWNhdGlvbgoJdHhuIEFwcGxpY2F0aW9uSUQKCWludCAwCgk9PQoJdHhuIE9uQ29tcGxldGlvbgoJaW50IE5vT3AKCT09CgkmJgoJcmV0dXJuCgpyb3V0ZV9hYmk6CgltZXRob2QgImR5bmFtaWNCb29sQXJyYXkoKWJvb2xbXSIKCXR4bmEgQXBwbGljYXRpb25BcmdzIDAKCW1hdGNoIGFiaV9yb3V0ZV9keW5hbWljQm9vbEFycmF5CgllcnI=", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDgKaW50IDEKcmV0dXJu" + }, + "contract": { + "name": "ABITestDynamicBoolArray", + "desc": "", + "methods": [ + { + "name": "dynamicBoolArray", + "args": [], + "desc": "", + "returns": { + "type": "bool[]", + "desc": "" + } + } + ] + } +} \ No newline at end of file diff --git a/tests/contracts/artifacts/ABITestDynamicBoolArrayAccess.abi.json b/tests/contracts/artifacts/ABITestDynamicBoolArrayAccess.abi.json new file mode 100644 index 000000000..eea82d6ab --- /dev/null +++ b/tests/contracts/artifacts/ABITestDynamicBoolArrayAccess.abi.json @@ -0,0 +1,15 @@ +{ + "name": "ABITestDynamicBoolArrayAccess", + "desc": "", + "methods": [ + { + "name": "dynamicBoolArrayAccess", + "args": [], + "desc": "", + "returns": { + "type": "bool", + "desc": "" + } + } + ] +} \ No newline at end of file diff --git a/tests/contracts/artifacts/ABITestDynamicBoolArrayAccess.approval.teal b/tests/contracts/artifacts/ABITestDynamicBoolArrayAccess.approval.teal new file mode 100644 index 000000000..81b32c0ba --- /dev/null +++ b/tests/contracts/artifacts/ABITestDynamicBoolArrayAccess.approval.teal @@ -0,0 +1,97 @@ +#pragma version 8 + b main + +abi_route_dynamicBoolArrayAccess: + txn OnCompletion + int NoOp + == + txn ApplicationID + int 0 + != + && + assert + byte 0x + callsub dynamicBoolArrayAccess + int 1 + return + +dynamicBoolArrayAccess: + proto 1 0 + + // tests/contracts/abi.algo.ts:892 + // a: boolean[] = [true, false, true, true, false, false, true, false, false] + byte 0x0009 + byte 0x0000 + int 0 + int 1 + setbit + int 1 + int 0 + setbit + int 2 + int 1 + setbit + int 3 + int 1 + setbit + int 4 + int 0 + setbit + int 5 + int 0 + setbit + int 6 + int 1 + setbit + int 7 + int 0 + setbit + int 8 + int 0 + setbit + concat + frame_bury -1 // a: bool[] + + // tests/contracts/abi.algo.ts:894 + // return a[8]; + frame_dig -1 // a: bool[] + store 0 // full array + int 0 // initial offset + int 0 // headOffset + + + int 8 + * + int 8 + + + load 0 // full array + swap + getbit + byte 0x00 + int 0 + uncover 2 + setbit + byte 0x151f7c75 + swap + concat + log + retsub + +main: + txn NumAppArgs + bnz route_abi + + // default createApplication + txn ApplicationID + int 0 + == + txn OnCompletion + int NoOp + == + && + return + +route_abi: + method "dynamicBoolArrayAccess()bool" + txna ApplicationArgs 0 + match abi_route_dynamicBoolArrayAccess + err \ No newline at end of file diff --git a/tests/contracts/artifacts/ABITestDynamicBoolArrayAccess.clear.teal b/tests/contracts/artifacts/ABITestDynamicBoolArrayAccess.clear.teal new file mode 100644 index 000000000..31588a8ec --- /dev/null +++ b/tests/contracts/artifacts/ABITestDynamicBoolArrayAccess.clear.teal @@ -0,0 +1,3 @@ +#pragma version 8 +int 1 +return \ No newline at end of file diff --git a/tests/contracts/artifacts/ABITestDynamicBoolArrayAccess.json b/tests/contracts/artifacts/ABITestDynamicBoolArrayAccess.json new file mode 100644 index 000000000..9d028ada7 --- /dev/null +++ b/tests/contracts/artifacts/ABITestDynamicBoolArrayAccess.json @@ -0,0 +1,51 @@ +{ + "hints": { + "dynamicBoolArrayAccess()bool": { + "call_config": { + "no_op": "CALL" + } + } + }, + "bare_call_config": { + "no_op": "CREATE" + }, + "schema": { + "local": { + "declared": {}, + "reserved": {} + }, + "global": { + "declared": {}, + "reserved": {} + } + }, + "state": { + "global": { + "num_byte_slices": 0, + "num_uints": 0 + }, + "local": { + "num_byte_slices": 0, + "num_uints": 0 + } + }, + "source": { + "approval": "I3ByYWdtYSB2ZXJzaW9uIDgKCWIgbWFpbgoKYWJpX3JvdXRlX2R5bmFtaWNCb29sQXJyYXlBY2Nlc3M6Cgl0eG4gT25Db21wbGV0aW9uCglpbnQgTm9PcAoJPT0KCXR4biBBcHBsaWNhdGlvbklECglpbnQgMAoJIT0KCSYmCglhc3NlcnQKCWJ5dGUgMHgKCWNhbGxzdWIgZHluYW1pY0Jvb2xBcnJheUFjY2VzcwoJaW50IDEKCXJldHVybgoKZHluYW1pY0Jvb2xBcnJheUFjY2VzczoKCXByb3RvIDEgMAoKCS8vIHRlc3RzL2NvbnRyYWN0cy9hYmkuYWxnby50czo4OTIKCS8vIGE6IGJvb2xlYW5bXSA9IFt0cnVlLCBmYWxzZSwgdHJ1ZSwgdHJ1ZSwgZmFsc2UsIGZhbHNlLCB0cnVlLCBmYWxzZSwgZmFsc2VdCglieXRlIDB4MDAwOQoJYnl0ZSAweDAwMDAKCWludCAwCglpbnQgMQoJc2V0Yml0CglpbnQgMQoJaW50IDAKCXNldGJpdAoJaW50IDIKCWludCAxCglzZXRiaXQKCWludCAzCglpbnQgMQoJc2V0Yml0CglpbnQgNAoJaW50IDAKCXNldGJpdAoJaW50IDUKCWludCAwCglzZXRiaXQKCWludCA2CglpbnQgMQoJc2V0Yml0CglpbnQgNwoJaW50IDAKCXNldGJpdAoJaW50IDgKCWludCAwCglzZXRiaXQKCWNvbmNhdAoJZnJhbWVfYnVyeSAtMSAvLyBhOiBib29sW10KCgkvLyB0ZXN0cy9jb250cmFjdHMvYWJpLmFsZ28udHM6ODk0CgkvLyByZXR1cm4gYVs4XTsKCWZyYW1lX2RpZyAtMSAvLyBhOiBib29sW10KCXN0b3JlIDAgLy8gZnVsbCBhcnJheQoJaW50IDAgLy8gaW5pdGlhbCBvZmZzZXQKCWludCAwIC8vIGhlYWRPZmZzZXQKCSsKCWludCA4CgkqCglpbnQgOAoJKwoJbG9hZCAwIC8vIGZ1bGwgYXJyYXkKCXN3YXAKCWdldGJpdAoJYnl0ZSAweDAwCglpbnQgMAoJdW5jb3ZlciAyCglzZXRiaXQKCWJ5dGUgMHgxNTFmN2M3NQoJc3dhcAoJY29uY2F0Cglsb2cKCXJldHN1YgoKbWFpbjoKCXR4biBOdW1BcHBBcmdzCglibnogcm91dGVfYWJpCgoJLy8gZGVmYXVsdCBjcmVhdGVBcHBsaWNhdGlvbgoJdHhuIEFwcGxpY2F0aW9uSUQKCWludCAwCgk9PQoJdHhuIE9uQ29tcGxldGlvbgoJaW50IE5vT3AKCT09CgkmJgoJcmV0dXJuCgpyb3V0ZV9hYmk6CgltZXRob2QgImR5bmFtaWNCb29sQXJyYXlBY2Nlc3MoKWJvb2wiCgl0eG5hIEFwcGxpY2F0aW9uQXJncyAwCgltYXRjaCBhYmlfcm91dGVfZHluYW1pY0Jvb2xBcnJheUFjY2VzcwoJZXJy", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDgKaW50IDEKcmV0dXJu" + }, + "contract": { + "name": "ABITestDynamicBoolArrayAccess", + "desc": "", + "methods": [ + { + "name": "dynamicBoolArrayAccess", + "args": [], + "desc": "", + "returns": { + "type": "bool", + "desc": "" + } + } + ] + } +} \ No newline at end of file diff --git a/tests/contracts/artifacts/ABITestDynamicBoolArrayUpdate.abi.json b/tests/contracts/artifacts/ABITestDynamicBoolArrayUpdate.abi.json new file mode 100644 index 000000000..23c083a81 --- /dev/null +++ b/tests/contracts/artifacts/ABITestDynamicBoolArrayUpdate.abi.json @@ -0,0 +1,15 @@ +{ + "name": "ABITestDynamicBoolArrayUpdate", + "desc": "", + "methods": [ + { + "name": "dynamicBoolArrayUpdate", + "args": [], + "desc": "", + "returns": { + "type": "bool[]", + "desc": "" + } + } + ] +} \ No newline at end of file diff --git a/tests/contracts/artifacts/ABITestDynamicBoolArrayUpdate.approval.teal b/tests/contracts/artifacts/ABITestDynamicBoolArrayUpdate.approval.teal new file mode 100644 index 000000000..b2cf9ac20 --- /dev/null +++ b/tests/contracts/artifacts/ABITestDynamicBoolArrayUpdate.approval.teal @@ -0,0 +1,101 @@ +#pragma version 8 + b main + +abi_route_dynamicBoolArrayUpdate: + txn OnCompletion + int NoOp + == + txn ApplicationID + int 0 + != + && + assert + byte 0x + callsub dynamicBoolArrayUpdate + int 1 + return + +dynamicBoolArrayUpdate: + proto 1 0 + + // tests/contracts/abi.algo.ts:910 + // a: boolean[] = [true, false, true, true, false, false, true, false, false] + byte 0x0009 + byte 0x0000 + int 0 + int 1 + setbit + int 1 + int 0 + setbit + int 2 + int 1 + setbit + int 3 + int 1 + setbit + int 4 + int 0 + setbit + int 5 + int 0 + setbit + int 6 + int 1 + setbit + int 7 + int 0 + setbit + int 8 + int 0 + setbit + concat + frame_bury -1 // a: bool[] + + // tests/contracts/abi.algo.ts:912 + // a[8] = true + frame_dig -1 // a: bool[] + store 0 // full array + int 0 // initial offset + int 0 // headOffset + + + int 8 + * // get bit offset + int 8 + + // add accessor bits + int 16 + + // 16 bits for length prefix + load 0 // full array + swap + int 1 + setbit + frame_bury -1 // a: bool[] + + // tests/contracts/abi.algo.ts:914 + // return a; + frame_dig -1 // a: bool[] + byte 0x151f7c75 + swap + concat + log + retsub + +main: + txn NumAppArgs + bnz route_abi + + // default createApplication + txn ApplicationID + int 0 + == + txn OnCompletion + int NoOp + == + && + return + +route_abi: + method "dynamicBoolArrayUpdate()bool[]" + txna ApplicationArgs 0 + match abi_route_dynamicBoolArrayUpdate + err \ No newline at end of file diff --git a/tests/contracts/artifacts/ABITestDynamicBoolArrayUpdate.clear.teal b/tests/contracts/artifacts/ABITestDynamicBoolArrayUpdate.clear.teal new file mode 100644 index 000000000..31588a8ec --- /dev/null +++ b/tests/contracts/artifacts/ABITestDynamicBoolArrayUpdate.clear.teal @@ -0,0 +1,3 @@ +#pragma version 8 +int 1 +return \ No newline at end of file diff --git a/tests/contracts/artifacts/ABITestDynamicBoolArrayUpdate.json b/tests/contracts/artifacts/ABITestDynamicBoolArrayUpdate.json new file mode 100644 index 000000000..2d8292a7a --- /dev/null +++ b/tests/contracts/artifacts/ABITestDynamicBoolArrayUpdate.json @@ -0,0 +1,51 @@ +{ + "hints": { + "dynamicBoolArrayUpdate()bool[]": { + "call_config": { + "no_op": "CALL" + } + } + }, + "bare_call_config": { + "no_op": "CREATE" + }, + "schema": { + "local": { + "declared": {}, + "reserved": {} + }, + "global": { + "declared": {}, + "reserved": {} + } + }, + "state": { + "global": { + "num_byte_slices": 0, + "num_uints": 0 + }, + "local": { + "num_byte_slices": 0, + "num_uints": 0 + } + }, + "source": { + "approval": "I3ByYWdtYSB2ZXJzaW9uIDgKCWIgbWFpbgoKYWJpX3JvdXRlX2R5bmFtaWNCb29sQXJyYXlVcGRhdGU6Cgl0eG4gT25Db21wbGV0aW9uCglpbnQgTm9PcAoJPT0KCXR4biBBcHBsaWNhdGlvbklECglpbnQgMAoJIT0KCSYmCglhc3NlcnQKCWJ5dGUgMHgKCWNhbGxzdWIgZHluYW1pY0Jvb2xBcnJheVVwZGF0ZQoJaW50IDEKCXJldHVybgoKZHluYW1pY0Jvb2xBcnJheVVwZGF0ZToKCXByb3RvIDEgMAoKCS8vIHRlc3RzL2NvbnRyYWN0cy9hYmkuYWxnby50czo5MTAKCS8vIGE6IGJvb2xlYW5bXSA9IFt0cnVlLCBmYWxzZSwgdHJ1ZSwgdHJ1ZSwgZmFsc2UsIGZhbHNlLCB0cnVlLCBmYWxzZSwgZmFsc2VdCglieXRlIDB4MDAwOQoJYnl0ZSAweDAwMDAKCWludCAwCglpbnQgMQoJc2V0Yml0CglpbnQgMQoJaW50IDAKCXNldGJpdAoJaW50IDIKCWludCAxCglzZXRiaXQKCWludCAzCglpbnQgMQoJc2V0Yml0CglpbnQgNAoJaW50IDAKCXNldGJpdAoJaW50IDUKCWludCAwCglzZXRiaXQKCWludCA2CglpbnQgMQoJc2V0Yml0CglpbnQgNwoJaW50IDAKCXNldGJpdAoJaW50IDgKCWludCAwCglzZXRiaXQKCWNvbmNhdAoJZnJhbWVfYnVyeSAtMSAvLyBhOiBib29sW10KCgkvLyB0ZXN0cy9jb250cmFjdHMvYWJpLmFsZ28udHM6OTEyCgkvLyBhWzhdID0gdHJ1ZQoJZnJhbWVfZGlnIC0xIC8vIGE6IGJvb2xbXQoJc3RvcmUgMCAvLyBmdWxsIGFycmF5CglpbnQgMCAvLyBpbml0aWFsIG9mZnNldAoJaW50IDAgLy8gaGVhZE9mZnNldAoJKwoJaW50IDgKCSogLy8gZ2V0IGJpdCBvZmZzZXQKCWludCA4CgkrIC8vIGFkZCBhY2Nlc3NvciBiaXRzCglpbnQgMTYKCSsgLy8gMTYgYml0cyBmb3IgbGVuZ3RoIHByZWZpeAoJbG9hZCAwIC8vIGZ1bGwgYXJyYXkKCXN3YXAKCWludCAxCglzZXRiaXQKCWZyYW1lX2J1cnkgLTEgLy8gYTogYm9vbFtdCgoJLy8gdGVzdHMvY29udHJhY3RzL2FiaS5hbGdvLnRzOjkxNAoJLy8gcmV0dXJuIGE7CglmcmFtZV9kaWcgLTEgLy8gYTogYm9vbFtdCglieXRlIDB4MTUxZjdjNzUKCXN3YXAKCWNvbmNhdAoJbG9nCglyZXRzdWIKCm1haW46Cgl0eG4gTnVtQXBwQXJncwoJYm56IHJvdXRlX2FiaQoKCS8vIGRlZmF1bHQgY3JlYXRlQXBwbGljYXRpb24KCXR4biBBcHBsaWNhdGlvbklECglpbnQgMAoJPT0KCXR4biBPbkNvbXBsZXRpb24KCWludCBOb09wCgk9PQoJJiYKCXJldHVybgoKcm91dGVfYWJpOgoJbWV0aG9kICJkeW5hbWljQm9vbEFycmF5VXBkYXRlKClib29sW10iCgl0eG5hIEFwcGxpY2F0aW9uQXJncyAwCgltYXRjaCBhYmlfcm91dGVfZHluYW1pY0Jvb2xBcnJheVVwZGF0ZQoJZXJy", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDgKaW50IDEKcmV0dXJu" + }, + "contract": { + "name": "ABITestDynamicBoolArrayUpdate", + "desc": "", + "methods": [ + { + "name": "dynamicBoolArrayUpdate", + "args": [], + "desc": "", + "returns": { + "type": "bool[]", + "desc": "" + } + } + ] + } +} \ No newline at end of file diff --git a/tests/contracts/artifacts/ABITestStaticBoolArray.abi.json b/tests/contracts/artifacts/ABITestStaticBoolArray.abi.json new file mode 100644 index 000000000..93c6583bb --- /dev/null +++ b/tests/contracts/artifacts/ABITestStaticBoolArray.abi.json @@ -0,0 +1,15 @@ +{ + "name": "ABITestStaticBoolArray", + "desc": "", + "methods": [ + { + "name": "staticBoolArray", + "args": [], + "desc": "", + "returns": { + "type": "bool[9]", + "desc": "" + } + } + ] +} \ No newline at end of file diff --git a/tests/contracts/artifacts/ABITestStaticBoolArray.approval.teal b/tests/contracts/artifacts/ABITestStaticBoolArray.approval.teal new file mode 100644 index 000000000..4a44191c7 --- /dev/null +++ b/tests/contracts/artifacts/ABITestStaticBoolArray.approval.teal @@ -0,0 +1,80 @@ +#pragma version 8 + b main + +abi_route_staticBoolArray: + txn OnCompletion + int NoOp + == + txn ApplicationID + int 0 + != + && + assert + byte 0x + callsub staticBoolArray + int 1 + return + +staticBoolArray: + proto 1 0 + + // tests/contracts/abi.algo.ts:856 + // a: StaticArray = [true, false, true, true, false, false, true, false, false] + byte 0x0000 + int 0 + int 1 + setbit + int 1 + int 0 + setbit + int 2 + int 1 + setbit + int 3 + int 1 + setbit + int 4 + int 0 + setbit + int 5 + int 0 + setbit + int 6 + int 1 + setbit + int 7 + int 0 + setbit + int 8 + int 0 + setbit + frame_bury -1 // a: bool[9] + + // tests/contracts/abi.algo.ts:858 + // return a; + frame_dig -1 // a: bool[9] + byte 0x151f7c75 + swap + concat + log + retsub + +main: + txn NumAppArgs + bnz route_abi + + // default createApplication + txn ApplicationID + int 0 + == + txn OnCompletion + int NoOp + == + && + return + +route_abi: + method "staticBoolArray()bool[9]" + txna ApplicationArgs 0 + match abi_route_staticBoolArray + err \ No newline at end of file diff --git a/tests/contracts/artifacts/ABITestStaticBoolArray.clear.teal b/tests/contracts/artifacts/ABITestStaticBoolArray.clear.teal new file mode 100644 index 000000000..31588a8ec --- /dev/null +++ b/tests/contracts/artifacts/ABITestStaticBoolArray.clear.teal @@ -0,0 +1,3 @@ +#pragma version 8 +int 1 +return \ No newline at end of file diff --git a/tests/contracts/artifacts/ABITestStaticBoolArray.json b/tests/contracts/artifacts/ABITestStaticBoolArray.json new file mode 100644 index 000000000..357b93a24 --- /dev/null +++ b/tests/contracts/artifacts/ABITestStaticBoolArray.json @@ -0,0 +1,51 @@ +{ + "hints": { + "staticBoolArray()bool[9]": { + "call_config": { + "no_op": "CALL" + } + } + }, + "bare_call_config": { + "no_op": "CREATE" + }, + "schema": { + "local": { + "declared": {}, + "reserved": {} + }, + "global": { + "declared": {}, + "reserved": {} + } + }, + "state": { + "global": { + "num_byte_slices": 0, + "num_uints": 0 + }, + "local": { + "num_byte_slices": 0, + "num_uints": 0 + } + }, + "source": { + "approval": "I3ByYWdtYSB2ZXJzaW9uIDgKCWIgbWFpbgoKYWJpX3JvdXRlX3N0YXRpY0Jvb2xBcnJheToKCXR4biBPbkNvbXBsZXRpb24KCWludCBOb09wCgk9PQoJdHhuIEFwcGxpY2F0aW9uSUQKCWludCAwCgkhPQoJJiYKCWFzc2VydAoJYnl0ZSAweAoJY2FsbHN1YiBzdGF0aWNCb29sQXJyYXkKCWludCAxCglyZXR1cm4KCnN0YXRpY0Jvb2xBcnJheToKCXByb3RvIDEgMAoKCS8vIHRlc3RzL2NvbnRyYWN0cy9hYmkuYWxnby50czo4NTYKCS8vIGE6IFN0YXRpY0FycmF5PGJvb2xlYW4sIDk+ID0gW3RydWUsIGZhbHNlLCB0cnVlLCB0cnVlLCBmYWxzZSwgZmFsc2UsIHRydWUsIGZhbHNlLCBmYWxzZV0KCWJ5dGUgMHgwMDAwCglpbnQgMAoJaW50IDEKCXNldGJpdAoJaW50IDEKCWludCAwCglzZXRiaXQKCWludCAyCglpbnQgMQoJc2V0Yml0CglpbnQgMwoJaW50IDEKCXNldGJpdAoJaW50IDQKCWludCAwCglzZXRiaXQKCWludCA1CglpbnQgMAoJc2V0Yml0CglpbnQgNgoJaW50IDEKCXNldGJpdAoJaW50IDcKCWludCAwCglzZXRiaXQKCWludCA4CglpbnQgMAoJc2V0Yml0CglmcmFtZV9idXJ5IC0xIC8vIGE6IGJvb2xbOV0KCgkvLyB0ZXN0cy9jb250cmFjdHMvYWJpLmFsZ28udHM6ODU4CgkvLyByZXR1cm4gYTsKCWZyYW1lX2RpZyAtMSAvLyBhOiBib29sWzldCglieXRlIDB4MTUxZjdjNzUKCXN3YXAKCWNvbmNhdAoJbG9nCglyZXRzdWIKCm1haW46Cgl0eG4gTnVtQXBwQXJncwoJYm56IHJvdXRlX2FiaQoKCS8vIGRlZmF1bHQgY3JlYXRlQXBwbGljYXRpb24KCXR4biBBcHBsaWNhdGlvbklECglpbnQgMAoJPT0KCXR4biBPbkNvbXBsZXRpb24KCWludCBOb09wCgk9PQoJJiYKCXJldHVybgoKcm91dGVfYWJpOgoJbWV0aG9kICJzdGF0aWNCb29sQXJyYXkoKWJvb2xbOV0iCgl0eG5hIEFwcGxpY2F0aW9uQXJncyAwCgltYXRjaCBhYmlfcm91dGVfc3RhdGljQm9vbEFycmF5CgllcnI=", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDgKaW50IDEKcmV0dXJu" + }, + "contract": { + "name": "ABITestStaticBoolArray", + "desc": "", + "methods": [ + { + "name": "staticBoolArray", + "args": [], + "desc": "", + "returns": { + "type": "bool[9]", + "desc": "" + } + } + ] + } +} \ No newline at end of file diff --git a/tests/contracts/artifacts/ABITestStaticBoolArrayAccess.abi.json b/tests/contracts/artifacts/ABITestStaticBoolArrayAccess.abi.json new file mode 100644 index 000000000..05591c534 --- /dev/null +++ b/tests/contracts/artifacts/ABITestStaticBoolArrayAccess.abi.json @@ -0,0 +1,15 @@ +{ + "name": "ABITestStaticBoolArrayAccess", + "desc": "", + "methods": [ + { + "name": "staticBoolArrayAccess", + "args": [], + "desc": "", + "returns": { + "type": "bool", + "desc": "" + } + } + ] +} \ No newline at end of file diff --git a/tests/contracts/artifacts/ABITestStaticBoolArrayAccess.approval.teal b/tests/contracts/artifacts/ABITestStaticBoolArrayAccess.approval.teal new file mode 100644 index 000000000..30cb94d40 --- /dev/null +++ b/tests/contracts/artifacts/ABITestStaticBoolArrayAccess.approval.teal @@ -0,0 +1,95 @@ +#pragma version 8 + b main + +abi_route_staticBoolArrayAccess: + txn OnCompletion + int NoOp + == + txn ApplicationID + int 0 + != + && + assert + byte 0x + callsub staticBoolArrayAccess + int 1 + return + +staticBoolArrayAccess: + proto 1 0 + + // tests/contracts/abi.algo.ts:876 + // a: StaticArray = [true, false, true, true, false, false, true, false, false] + byte 0x0000 + int 0 + int 1 + setbit + int 1 + int 0 + setbit + int 2 + int 1 + setbit + int 3 + int 1 + setbit + int 4 + int 0 + setbit + int 5 + int 0 + setbit + int 6 + int 1 + setbit + int 7 + int 0 + setbit + int 8 + int 0 + setbit + frame_bury -1 // a: bool[9] + + // tests/contracts/abi.algo.ts:878 + // return a[8]; + frame_dig -1 // a: bool[9] + store 0 // full array + int 0 // initial offset + int 0 // headOffset + + + int 8 + * + int 8 + + + load 0 // full array + swap + getbit + byte 0x00 + int 0 + uncover 2 + setbit + byte 0x151f7c75 + swap + concat + log + retsub + +main: + txn NumAppArgs + bnz route_abi + + // default createApplication + txn ApplicationID + int 0 + == + txn OnCompletion + int NoOp + == + && + return + +route_abi: + method "staticBoolArrayAccess()bool" + txna ApplicationArgs 0 + match abi_route_staticBoolArrayAccess + err \ No newline at end of file diff --git a/tests/contracts/artifacts/ABITestStaticBoolArrayAccess.clear.teal b/tests/contracts/artifacts/ABITestStaticBoolArrayAccess.clear.teal new file mode 100644 index 000000000..31588a8ec --- /dev/null +++ b/tests/contracts/artifacts/ABITestStaticBoolArrayAccess.clear.teal @@ -0,0 +1,3 @@ +#pragma version 8 +int 1 +return \ No newline at end of file diff --git a/tests/contracts/artifacts/ABITestStaticBoolArrayAccess.json b/tests/contracts/artifacts/ABITestStaticBoolArrayAccess.json new file mode 100644 index 000000000..d725a1670 --- /dev/null +++ b/tests/contracts/artifacts/ABITestStaticBoolArrayAccess.json @@ -0,0 +1,51 @@ +{ + "hints": { + "staticBoolArrayAccess()bool": { + "call_config": { + "no_op": "CALL" + } + } + }, + "bare_call_config": { + "no_op": "CREATE" + }, + "schema": { + "local": { + "declared": {}, + "reserved": {} + }, + "global": { + "declared": {}, + "reserved": {} + } + }, + "state": { + "global": { + "num_byte_slices": 0, + "num_uints": 0 + }, + "local": { + "num_byte_slices": 0, + "num_uints": 0 + } + }, + "source": { + "approval": "I3ByYWdtYSB2ZXJzaW9uIDgKCWIgbWFpbgoKYWJpX3JvdXRlX3N0YXRpY0Jvb2xBcnJheUFjY2VzczoKCXR4biBPbkNvbXBsZXRpb24KCWludCBOb09wCgk9PQoJdHhuIEFwcGxpY2F0aW9uSUQKCWludCAwCgkhPQoJJiYKCWFzc2VydAoJYnl0ZSAweAoJY2FsbHN1YiBzdGF0aWNCb29sQXJyYXlBY2Nlc3MKCWludCAxCglyZXR1cm4KCnN0YXRpY0Jvb2xBcnJheUFjY2VzczoKCXByb3RvIDEgMAoKCS8vIHRlc3RzL2NvbnRyYWN0cy9hYmkuYWxnby50czo4NzYKCS8vIGE6IFN0YXRpY0FycmF5PGJvb2xlYW4sIDk+ID0gW3RydWUsIGZhbHNlLCB0cnVlLCB0cnVlLCBmYWxzZSwgZmFsc2UsIHRydWUsIGZhbHNlLCBmYWxzZV0KCWJ5dGUgMHgwMDAwCglpbnQgMAoJaW50IDEKCXNldGJpdAoJaW50IDEKCWludCAwCglzZXRiaXQKCWludCAyCglpbnQgMQoJc2V0Yml0CglpbnQgMwoJaW50IDEKCXNldGJpdAoJaW50IDQKCWludCAwCglzZXRiaXQKCWludCA1CglpbnQgMAoJc2V0Yml0CglpbnQgNgoJaW50IDEKCXNldGJpdAoJaW50IDcKCWludCAwCglzZXRiaXQKCWludCA4CglpbnQgMAoJc2V0Yml0CglmcmFtZV9idXJ5IC0xIC8vIGE6IGJvb2xbOV0KCgkvLyB0ZXN0cy9jb250cmFjdHMvYWJpLmFsZ28udHM6ODc4CgkvLyByZXR1cm4gYVs4XTsKCWZyYW1lX2RpZyAtMSAvLyBhOiBib29sWzldCglzdG9yZSAwIC8vIGZ1bGwgYXJyYXkKCWludCAwIC8vIGluaXRpYWwgb2Zmc2V0CglpbnQgMCAvLyBoZWFkT2Zmc2V0CgkrCglpbnQgOAoJKgoJaW50IDgKCSsKCWxvYWQgMCAvLyBmdWxsIGFycmF5Cglzd2FwCglnZXRiaXQKCWJ5dGUgMHgwMAoJaW50IDAKCXVuY292ZXIgMgoJc2V0Yml0CglieXRlIDB4MTUxZjdjNzUKCXN3YXAKCWNvbmNhdAoJbG9nCglyZXRzdWIKCm1haW46Cgl0eG4gTnVtQXBwQXJncwoJYm56IHJvdXRlX2FiaQoKCS8vIGRlZmF1bHQgY3JlYXRlQXBwbGljYXRpb24KCXR4biBBcHBsaWNhdGlvbklECglpbnQgMAoJPT0KCXR4biBPbkNvbXBsZXRpb24KCWludCBOb09wCgk9PQoJJiYKCXJldHVybgoKcm91dGVfYWJpOgoJbWV0aG9kICJzdGF0aWNCb29sQXJyYXlBY2Nlc3MoKWJvb2wiCgl0eG5hIEFwcGxpY2F0aW9uQXJncyAwCgltYXRjaCBhYmlfcm91dGVfc3RhdGljQm9vbEFycmF5QWNjZXNzCgllcnI=", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDgKaW50IDEKcmV0dXJu" + }, + "contract": { + "name": "ABITestStaticBoolArrayAccess", + "desc": "", + "methods": [ + { + "name": "staticBoolArrayAccess", + "args": [], + "desc": "", + "returns": { + "type": "bool", + "desc": "" + } + } + ] + } +} \ No newline at end of file diff --git a/tests/contracts/artifacts/ABITestStaticBoolArrayUpdate.abi.json b/tests/contracts/artifacts/ABITestStaticBoolArrayUpdate.abi.json new file mode 100644 index 000000000..a4aad0c73 --- /dev/null +++ b/tests/contracts/artifacts/ABITestStaticBoolArrayUpdate.abi.json @@ -0,0 +1,15 @@ +{ + "name": "ABITestStaticBoolArrayUpdate", + "desc": "", + "methods": [ + { + "name": "staticBoolArrayUpdate", + "args": [], + "desc": "", + "returns": { + "type": "bool[9]", + "desc": "" + } + } + ] +} \ No newline at end of file diff --git a/tests/contracts/artifacts/ABITestStaticBoolArrayUpdate.approval.teal b/tests/contracts/artifacts/ABITestStaticBoolArrayUpdate.approval.teal new file mode 100644 index 000000000..39303b0c6 --- /dev/null +++ b/tests/contracts/artifacts/ABITestStaticBoolArrayUpdate.approval.teal @@ -0,0 +1,97 @@ +#pragma version 8 + b main + +abi_route_staticBoolArrayUpdate: + txn OnCompletion + int NoOp + == + txn ApplicationID + int 0 + != + && + assert + byte 0x + callsub staticBoolArrayUpdate + int 1 + return + +staticBoolArrayUpdate: + proto 1 0 + + // tests/contracts/abi.algo.ts:900 + // a: StaticArray = [true, false, true, true, false, false, true, false, false] + byte 0x0000 + int 0 + int 1 + setbit + int 1 + int 0 + setbit + int 2 + int 1 + setbit + int 3 + int 1 + setbit + int 4 + int 0 + setbit + int 5 + int 0 + setbit + int 6 + int 1 + setbit + int 7 + int 0 + setbit + int 8 + int 0 + setbit + frame_bury -1 // a: bool[9] + + // tests/contracts/abi.algo.ts:902 + // a[8] = true + frame_dig -1 // a: bool[9] + store 0 // full array + int 0 // initial offset + int 0 // headOffset + + + int 8 + * // get bit offset + int 8 + + // add accessor bits + load 0 // full array + swap + int 1 + setbit + frame_bury -1 // a: bool[9] + + // tests/contracts/abi.algo.ts:904 + // return a; + frame_dig -1 // a: bool[9] + byte 0x151f7c75 + swap + concat + log + retsub + +main: + txn NumAppArgs + bnz route_abi + + // default createApplication + txn ApplicationID + int 0 + == + txn OnCompletion + int NoOp + == + && + return + +route_abi: + method "staticBoolArrayUpdate()bool[9]" + txna ApplicationArgs 0 + match abi_route_staticBoolArrayUpdate + err \ No newline at end of file diff --git a/tests/contracts/artifacts/ABITestStaticBoolArrayUpdate.clear.teal b/tests/contracts/artifacts/ABITestStaticBoolArrayUpdate.clear.teal new file mode 100644 index 000000000..31588a8ec --- /dev/null +++ b/tests/contracts/artifacts/ABITestStaticBoolArrayUpdate.clear.teal @@ -0,0 +1,3 @@ +#pragma version 8 +int 1 +return \ No newline at end of file diff --git a/tests/contracts/artifacts/ABITestStaticBoolArrayUpdate.json b/tests/contracts/artifacts/ABITestStaticBoolArrayUpdate.json new file mode 100644 index 000000000..023c8fbb2 --- /dev/null +++ b/tests/contracts/artifacts/ABITestStaticBoolArrayUpdate.json @@ -0,0 +1,51 @@ +{ + "hints": { + "staticBoolArrayUpdate()bool[9]": { + "call_config": { + "no_op": "CALL" + } + } + }, + "bare_call_config": { + "no_op": "CREATE" + }, + "schema": { + "local": { + "declared": {}, + "reserved": {} + }, + "global": { + "declared": {}, + "reserved": {} + } + }, + "state": { + "global": { + "num_byte_slices": 0, + "num_uints": 0 + }, + "local": { + "num_byte_slices": 0, + "num_uints": 0 + } + }, + "source": { + "approval": "I3ByYWdtYSB2ZXJzaW9uIDgKCWIgbWFpbgoKYWJpX3JvdXRlX3N0YXRpY0Jvb2xBcnJheVVwZGF0ZToKCXR4biBPbkNvbXBsZXRpb24KCWludCBOb09wCgk9PQoJdHhuIEFwcGxpY2F0aW9uSUQKCWludCAwCgkhPQoJJiYKCWFzc2VydAoJYnl0ZSAweAoJY2FsbHN1YiBzdGF0aWNCb29sQXJyYXlVcGRhdGUKCWludCAxCglyZXR1cm4KCnN0YXRpY0Jvb2xBcnJheVVwZGF0ZToKCXByb3RvIDEgMAoKCS8vIHRlc3RzL2NvbnRyYWN0cy9hYmkuYWxnby50czo5MDAKCS8vIGE6IFN0YXRpY0FycmF5PGJvb2xlYW4sIDk+ID0gW3RydWUsIGZhbHNlLCB0cnVlLCB0cnVlLCBmYWxzZSwgZmFsc2UsIHRydWUsIGZhbHNlLCBmYWxzZV0KCWJ5dGUgMHgwMDAwCglpbnQgMAoJaW50IDEKCXNldGJpdAoJaW50IDEKCWludCAwCglzZXRiaXQKCWludCAyCglpbnQgMQoJc2V0Yml0CglpbnQgMwoJaW50IDEKCXNldGJpdAoJaW50IDQKCWludCAwCglzZXRiaXQKCWludCA1CglpbnQgMAoJc2V0Yml0CglpbnQgNgoJaW50IDEKCXNldGJpdAoJaW50IDcKCWludCAwCglzZXRiaXQKCWludCA4CglpbnQgMAoJc2V0Yml0CglmcmFtZV9idXJ5IC0xIC8vIGE6IGJvb2xbOV0KCgkvLyB0ZXN0cy9jb250cmFjdHMvYWJpLmFsZ28udHM6OTAyCgkvLyBhWzhdID0gdHJ1ZQoJZnJhbWVfZGlnIC0xIC8vIGE6IGJvb2xbOV0KCXN0b3JlIDAgLy8gZnVsbCBhcnJheQoJaW50IDAgLy8gaW5pdGlhbCBvZmZzZXQKCWludCAwIC8vIGhlYWRPZmZzZXQKCSsKCWludCA4CgkqIC8vIGdldCBiaXQgb2Zmc2V0CglpbnQgOAoJKyAvLyBhZGQgYWNjZXNzb3IgYml0cwoJbG9hZCAwIC8vIGZ1bGwgYXJyYXkKCXN3YXAKCWludCAxCglzZXRiaXQKCWZyYW1lX2J1cnkgLTEgLy8gYTogYm9vbFs5XQoKCS8vIHRlc3RzL2NvbnRyYWN0cy9hYmkuYWxnby50czo5MDQKCS8vIHJldHVybiBhOwoJZnJhbWVfZGlnIC0xIC8vIGE6IGJvb2xbOV0KCWJ5dGUgMHgxNTFmN2M3NQoJc3dhcAoJY29uY2F0Cglsb2cKCXJldHN1YgoKbWFpbjoKCXR4biBOdW1BcHBBcmdzCglibnogcm91dGVfYWJpCgoJLy8gZGVmYXVsdCBjcmVhdGVBcHBsaWNhdGlvbgoJdHhuIEFwcGxpY2F0aW9uSUQKCWludCAwCgk9PQoJdHhuIE9uQ29tcGxldGlvbgoJaW50IE5vT3AKCT09CgkmJgoJcmV0dXJuCgpyb3V0ZV9hYmk6CgltZXRob2QgInN0YXRpY0Jvb2xBcnJheVVwZGF0ZSgpYm9vbFs5XSIKCXR4bmEgQXBwbGljYXRpb25BcmdzIDAKCW1hdGNoIGFiaV9yb3V0ZV9zdGF0aWNCb29sQXJyYXlVcGRhdGUKCWVycg==", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDgKaW50IDEKcmV0dXJu" + }, + "contract": { + "name": "ABITestStaticBoolArrayUpdate", + "desc": "", + "methods": [ + { + "name": "staticBoolArrayUpdate", + "args": [], + "desc": "", + "returns": { + "type": "bool[9]", + "desc": "" + } + } + ] + } +} \ No newline at end of file diff --git a/types/global.d.ts b/types/global.d.ts index f42a18802..4397f65cc 100644 --- a/types/global.d.ts +++ b/types/global.d.ts @@ -674,7 +674,9 @@ declare class handle { type StaticArray< T extends BytesLike | IntLike | StaticArray, N extends number -> = (T extends byte ? string : (N extends 0 ? never[] : T[])) & {__type?: T, __length?: N} +> = ( + T extends byte ? string : (N extends 0 ? never[] : T extends boolean ? (true | false)[] : T[]) +) & {__type?: T, __length?: N} // eslint-disable-next-line no-shadow enum TransactionType {