@@ -153,6 +153,94 @@ examples:
153153
154154 - # example template reference
155155 define :
156- " contract-variable-slot " : 0
156+ " string-storage- contract-variable-slot" : 0
157157 in :
158- template : " solidity-string-storage"
158+ group :
159+ # for short strings, the length is stored as 2n in the last byte of slot
160+ - name : " length-flag"
161+ location : storage
162+ slot : " string-storage-contract-variable-slot"
163+ offset :
164+ $difference : [$wordsize, 1]
165+ length : 1
166+
167+ # define the region representing the string data itself conditionally
168+ # based on odd or even length data
169+ - if :
170+ $remainder :
171+ - $sum :
172+ - $read : " length-flag"
173+ - 1
174+ - 2
175+
176+ # short string case (flag is even)
177+ then :
178+ define :
179+ " string-length " :
180+ $quotient : [{ $read: "length-flag" }, 2]
181+ in :
182+ name : " string"
183+ location : storage
184+ slot : " string-storage-contract-variable-slot"
185+ offset : 0
186+ length : " string-length"
187+
188+ # long string case (flag is odd)
189+ else :
190+ group :
191+ # long strings may use full word to describe length as 2n+1
192+ - name : " long-string-length-data"
193+ location : storage
194+ slot : " string-storage-contract-variable-slot"
195+ offset : 0
196+ length : $wordsize
197+
198+ - define :
199+ " string-length " :
200+ $quotient :
201+ - $difference :
202+ - $read : " long-string-length-data"
203+ - 1
204+ - 2
205+
206+ " start-slot " :
207+ $keccak256 :
208+ - $wordsized : " string-storage-contract-variable-slot"
209+
210+ " total-slots " :
211+ # account for both zero and nonzero slot remainders by adding
212+ # $wordsize-1 to the length before dividing
213+ $quotient :
214+ - $sum : ["string-length", { $difference: [$wordsize, 1] }]
215+ - $wordsize
216+ in :
217+ list :
218+ count : " total-slots"
219+ each : " i"
220+ is :
221+ define :
222+ " current-slot " :
223+ $sum : ["start-slot", "i"]
224+ " previous-length " :
225+ $product : ["i", $wordsize]
226+ in :
227+ # conditional based on whether this is the last slot:
228+ # is the string length longer than the previous length
229+ # plus this whole slot?
230+ if :
231+ $difference :
232+ - " string-length"
233+ - $sum : ["previous-length", "$wordsize"]
234+ then :
235+ # include the whole slot
236+ name : " string"
237+ location : storage
238+ slot : " current-slot"
239+ else :
240+ # include only what's left in the string
241+ name : " string"
242+ location : storage
243+ slot : " current-slot"
244+ offset : 0
245+ length :
246+ $difference : ["string-length", "previous-length"]
0 commit comments