Skip to content

Commit 20b215b

Browse files
authored
Merge pull request #592 from algorandfoundation/fix/large_extract
fix: extract when one of the args > 255
2 parents 1e3f245 + 2918663 commit 20b215b

7 files changed

Lines changed: 3721 additions & 0 deletions

src/lib/optimize.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,21 @@ export function optimizeOpcodes(inputTeal: TEALInfo[]): TEALInfo[] {
250250
pushTeal(`int ${length}`, node);
251251
pushTeal('box_extract', node);
252252
optimized = true;
253+
} else if (start > 255 || length > 255) {
254+
// The extract opcode uses 0 to indicate that the length is the rest of the bytes
255+
// So when the length is 0 we need to calculate the bytes length and use substring3 instead
256+
if (length === 0) {
257+
pushTeal('dup', node);
258+
pushTeal('len', node);
259+
pushTeal(`int ${start}`, node);
260+
pushTeal('swap', node);
261+
pushTeal('substring3', node);
262+
} else {
263+
pushTeal(`int ${start}`, node);
264+
pushTeal(`int ${length}`, node);
265+
pushTeal('extract3', node);
266+
}
267+
optimized = true;
253268
}
254269
} else if (teal.startsWith('substring ') && outputTeal.at(-1)?.teal.startsWith('byte 0x')) {
255270
const bytes = outputTeal.at(-1)!.teal.split(' ')[1].slice(2);
Lines changed: 256 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,256 @@
1+
#pragma version 10
2+
intcblock 256 1024 0 1
3+
bytecblock 0x 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0x0000000000000000
4+
5+
// This TEAL was generated by TEALScript v0.107.1
6+
// https://github.com/algorandfoundation/TEALScript
7+
8+
// This contract is compliant with and/or implements the following ARCs: [ ARC4 ]
9+
10+
// The following ten lines of TEAL handle initial program flow
11+
// This pattern is used to make it easy for anyone to parse the start of the program and determine if a specific action is allowed
12+
// Here, action refers to the OnComplete in combination with whether the app is being created or called
13+
// Every possible action for this contract is represented in the switch statement
14+
// If the action is not implemented in the contract, its respective branch will be "*NOT_IMPLEMENTED" which just contains "err"
15+
txn ApplicationID
16+
!
17+
pushint 6
18+
*
19+
txn OnCompletion
20+
+
21+
switch *call_NoOp *NOT_IMPLEMENTED *NOT_IMPLEMENTED *NOT_IMPLEMENTED *NOT_IMPLEMENTED *NOT_IMPLEMENTED *create_NoOp *NOT_IMPLEMENTED *NOT_IMPLEMENTED *NOT_IMPLEMENTED *NOT_IMPLEMENTED *NOT_IMPLEMENTED
22+
23+
*NOT_IMPLEMENTED:
24+
// The requested action is not implemented in this contract. Are you using the correct OnComplete? Did you set your app ID?
25+
err
26+
27+
// doMath(uint64,string,string,string,string,string,string,string,string,uint64)void
28+
*abi_route_doMath:
29+
// mintedAsset: uint64
30+
txna ApplicationArgs 10
31+
btoi
32+
33+
// socialX: string
34+
txna ApplicationArgs 9
35+
extract 2 0
36+
37+
// socialDiscord: string
38+
txna ApplicationArgs 8
39+
extract 2 0
40+
41+
// socialTelegram: string
42+
txna ApplicationArgs 7
43+
extract 2 0
44+
45+
// socialWebsite: string
46+
txna ApplicationArgs 6
47+
extract 2 0
48+
49+
// description: string
50+
txna ApplicationArgs 5
51+
extract 2 0
52+
53+
// assetUrl: string
54+
txna ApplicationArgs 4
55+
extract 2 0
56+
57+
// name: string
58+
txna ApplicationArgs 3
59+
extract 2 0
60+
61+
// symbol: string
62+
txna ApplicationArgs 2
63+
extract 2 0
64+
65+
// k: uint64
66+
txna ApplicationArgs 1
67+
btoi
68+
69+
// execute doMath(uint64,string,string,string,string,string,string,string,string,uint64)void
70+
callsub doMath
71+
intc 3 // 1
72+
return
73+
74+
// doMath(k: uint64, symbol: string, name: string, assetUrl: string, description: string, socialWebsite: string, socialTelegram: string, socialDiscord: string, socialX: string, mintedAsset: AssetID): void
75+
doMath:
76+
proto 10 0
77+
78+
// Push empty bytes after the frame pointer to reserve space for local variables
79+
bytec 0 // 0x
80+
81+
// tests/contracts/token_info.algo.ts:57
82+
// tokenData: TokenInfo = {
83+
// tokenCreator: this.txn.sender,
84+
// currentBonding: 0,
85+
// bondingOn: BOND_PLATFORM_UNBONDED,
86+
// p0: P0,
87+
// pQ: PQ,
88+
// k: k,
89+
// Q: this.bondSupply.value,
90+
// launchQ: this.createSupply.value,
91+
// feeBpsPlatform: this.feeBpsPlatform.value,
92+
// feeBpsCreator: this.feeBpsCreator.value,
93+
// assetId: AssetID.fromUint64(mintedAsset.id),
94+
// symbol: symbol as bytes<8>,
95+
// name: name as bytes<32>,
96+
// assetUrl: assetUrl as bytes<96>,
97+
// description: description as bytes<1024>,
98+
// socialWebsite: socialWebsite as bytes<256>,
99+
// socialX: socialX as bytes<64>,
100+
// socialTelegram: socialTelegram as bytes<64>,
101+
// socialDiscord: socialDiscord as bytes<64>,
102+
// }
103+
txn Sender
104+
pushbytes 0x00000000000003e8
105+
concat
106+
pushbytes 0x00000000000001f4
107+
concat
108+
pushbytes 0x626f6e64537570706c79 // "bondSupply"
109+
app_global_get
110+
itob
111+
concat
112+
frame_dig -1 // k: uint64
113+
itob
114+
concat
115+
pushbytes 0x637265617465537570706c79 // "createSupply"
116+
app_global_get
117+
itob
118+
concat
119+
pushbytes 0x666565427073506c6174666f726d // "feeBpsPlatform"
120+
app_global_get
121+
itob
122+
concat
123+
pushbytes 0x66656542707343726561746f72 // "feeBpsCreator"
124+
app_global_get
125+
itob
126+
concat
127+
bytec 2 // 0x0000000000000000
128+
concat
129+
pushbytes 0x000000000000007b
130+
concat
131+
frame_dig -10 // mintedAsset: AssetID
132+
itob
133+
concat
134+
frame_dig -2 // symbol: string
135+
bytec 2 // 0x0000000000000000
136+
concat
137+
dup
138+
extract 8 0
139+
bytec 0 // 0x
140+
b==
141+
assert
142+
extract 0 8
143+
concat
144+
frame_dig -3 // name: string
145+
pushbytes 0x0000000000000000000000000000000000000000000000000000000000000000
146+
concat
147+
dup
148+
extract 32 0
149+
bytec 0 // 0x
150+
b==
151+
assert
152+
extract 0 32
153+
concat
154+
frame_dig -4 // assetUrl: string
155+
pushbytes 0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
156+
concat
157+
dup
158+
extract 96 0
159+
bytec 0 // 0x
160+
b==
161+
assert
162+
extract 0 96
163+
concat
164+
frame_dig -5 // description: string
165+
pushbytes 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
166+
concat
167+
dup
168+
dup
169+
len
170+
intc 1 // 1024
171+
swap
172+
substring3
173+
bytec 0 // 0x
174+
b==
175+
assert
176+
intc 2 // 0
177+
intc 1 // 1024
178+
extract3
179+
concat
180+
frame_dig -6 // socialWebsite: string
181+
pushbytes 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
182+
concat
183+
dup
184+
dup
185+
len
186+
intc 0 // 256
187+
swap
188+
substring3
189+
bytec 0 // 0x
190+
b==
191+
assert
192+
intc 2 // 0
193+
intc 0 // 256
194+
extract3
195+
concat
196+
frame_dig -9 // socialX: string
197+
bytec 1 // 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
198+
concat
199+
dup
200+
extract 64 0
201+
bytec 0 // 0x
202+
b==
203+
assert
204+
extract 0 64
205+
concat
206+
frame_dig -7 // socialTelegram: string
207+
bytec 1 // 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
208+
concat
209+
dup
210+
extract 64 0
211+
bytec 0 // 0x
212+
b==
213+
assert
214+
extract 0 64
215+
concat
216+
frame_dig -8 // socialDiscord: string
217+
bytec 1 // 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
218+
concat
219+
dup
220+
extract 64 0
221+
bytec 0 // 0x
222+
b==
223+
assert
224+
extract 0 64
225+
concat
226+
frame_bury 0 // tokenData: TokenInfo
227+
228+
// tests/contracts/token_info.algo.ts:78
229+
// this.tokenMap(mintedAsset).value = tokenData
230+
pushbytes 0x74 // "t"
231+
frame_dig -10 // mintedAsset: AssetID
232+
itob
233+
concat
234+
frame_dig 0 // tokenData: TokenInfo
235+
box_put
236+
retsub
237+
238+
*abi_route_createApplication:
239+
intc 3 // 1
240+
return
241+
242+
*create_NoOp:
243+
pushbytes 0xb8447b36 // method "createApplication()void"
244+
txna ApplicationArgs 0
245+
match *abi_route_createApplication
246+
247+
// this contract does not implement the given ABI method for create NoOp
248+
err
249+
250+
*call_NoOp:
251+
pushbytes 0x5370f8d9 // method "doMath(uint64,string,string,string,string,string,string,string,string,uint64)void"
252+
txna ApplicationArgs 0
253+
match *abi_route_doMath
254+
255+
// this contract does not implement the given ABI method for call NoOp
256+
err

0 commit comments

Comments
 (0)