1 | import chai, {expect} from 'chai'
|
2 | import {Contract, BigNumber} from 'ethers'
|
3 | import {solidity, MockProvider, deployContract} from 'ethereum-waffle'
|
4 |
|
5 | import FixedPointTest from '../build/FixedPointTest.json'
|
6 |
|
7 | chai.use(solidity)
|
8 |
|
9 | const overrides = {
|
10 | gasLimit: 9999999,
|
11 | }
|
12 |
|
13 | const Q112 = BigNumber.from(2).pow(112)
|
14 |
|
15 | describe('FixedPoint', () => {
|
16 | const provider = new MockProvider({
|
17 | ganacheOptions: {
|
18 | hardfork: 'istanbul',
|
19 | mnemonic: 'horn horn horn horn horn horn horn horn horn horn horn horn',
|
20 | gasLimit: 9999999,
|
21 | },
|
22 | })
|
23 | const [wallet] = provider.getWallets()
|
24 |
|
25 | let fixedPoint: Contract
|
26 | before('deploy FixedPointTest', async () => {
|
27 | fixedPoint = await deployContract(wallet, FixedPointTest, [], overrides)
|
28 | })
|
29 |
|
30 | describe('#encode', () => {
|
31 | it('shifts left by 112', async () => {
|
32 | expect((await fixedPoint.encode('0x01'))[0]).to.eq(Q112.toHexString())
|
33 | })
|
34 | it('will not take >uint112(-1)', async () => {
|
35 | expect(() => fixedPoint.encode(BigNumber.from(2).pow(113).sub(1))).to.throw
|
36 | })
|
37 | })
|
38 |
|
39 | describe('#encode144', () => {
|
40 | it('shifts left by 112', async () => {
|
41 | expect((await fixedPoint.encode144('0x01'))[0]).to.eq(Q112.toHexString())
|
42 | })
|
43 | it('will not take >uint144(-1)', async () => {
|
44 | expect(() => fixedPoint.encode144(BigNumber.from(2).pow(145).sub(1))).to.throw
|
45 | })
|
46 | })
|
47 |
|
48 | describe('#decode', () => {
|
49 | it('shifts right by 112', async () => {
|
50 | expect(await fixedPoint.decode([BigNumber.from(3).mul(Q112)])).to.eq(BigNumber.from(3))
|
51 | })
|
52 | it('will not take >uint224(-1)', async () => {
|
53 | expect(() => fixedPoint.decode([BigNumber.from(2).pow(225).sub(1)])).to.throw
|
54 | })
|
55 | })
|
56 |
|
57 | describe('#decode144', () => {
|
58 | it('shifts right by 112', async () => {
|
59 | expect(await fixedPoint.decode([BigNumber.from(3).mul(Q112)])).to.eq(BigNumber.from(3))
|
60 | })
|
61 |
|
62 | it('will not take >uint256(-1)', async () => {
|
63 | expect(() => fixedPoint.decode([BigNumber.from(2).pow(257).sub(1)])).to.throw
|
64 | })
|
65 | })
|
66 |
|
67 | describe('#mul', () => {
|
68 | it('works for 0', async () => {
|
69 | expect((await fixedPoint.mul([0], 1))[0]).to.eq(0)
|
70 | expect((await fixedPoint.mul([1], 0))[0]).to.eq(0)
|
71 | })
|
72 |
|
73 | it('correct multiplication', async () => {
|
74 | expect((await fixedPoint.mul([BigNumber.from(3).mul(Q112)], BigNumber.from(2)))[0]).to.eq(
|
75 | BigNumber.from(3).mul(2).mul(Q112)
|
76 | )
|
77 | })
|
78 |
|
79 | it('overflow', async () => {
|
80 | await expect(fixedPoint.mul([BigNumber.from(1).mul(Q112)], BigNumber.from(2).pow(144))).to.be.revertedWith(
|
81 | 'FixedPoint::mul: overflow'
|
82 | )
|
83 | })
|
84 |
|
85 | it('max of q112x112', async () => {
|
86 | expect((await fixedPoint.mul([BigNumber.from(2).pow(112)], BigNumber.from(2).pow(112)))[0]).to.eq(
|
87 | BigNumber.from(2).pow(224)
|
88 | )
|
89 | })
|
90 |
|
91 | it('max without overflow, largest fixed point', async () => {
|
92 | const maxMultiplier = BigNumber.from(2).pow(32)
|
93 | expect((await fixedPoint.mul([BigNumber.from(2).pow(224).sub(1)], maxMultiplier))[0]).to.eq(
|
94 | BigNumber.from('115792089237316195423570985008687907853269984665640564039457584007908834672640')
|
95 | )
|
96 | await expect(fixedPoint.mul([BigNumber.from(2).pow(224).sub(1)], maxMultiplier.add(1))).to.be.revertedWith(
|
97 | 'FixedPoint::mul: overflow'
|
98 | )
|
99 | })
|
100 |
|
101 | it('max without overflow, smallest fixed point', async () => {
|
102 | const maxUint = BigNumber.from(2).pow(256).sub(1)
|
103 | expect((await fixedPoint.mul([BigNumber.from(1)], maxUint))[0]).to.eq(maxUint)
|
104 | await expect(fixedPoint.mul([BigNumber.from(2)], maxUint)).to.be.revertedWith('FixedPoint::mul: overflow')
|
105 | })
|
106 | })
|
107 |
|
108 | describe('#muli', () => {
|
109 | it('works for 0', async () => {
|
110 | expect(await fixedPoint.muli([BigNumber.from(0).mul(Q112)], BigNumber.from(1))).to.eq(BigNumber.from(0))
|
111 | expect(await fixedPoint.muli([BigNumber.from(1).mul(Q112)], BigNumber.from(0))).to.eq(BigNumber.from(0))
|
112 | })
|
113 |
|
114 | it('works for 3*2', async () => {
|
115 | expect(await fixedPoint.muli([BigNumber.from(3).mul(Q112)], BigNumber.from(2))).to.eq(BigNumber.from(6))
|
116 | })
|
117 |
|
118 | it('works for 3*-2', async () => {
|
119 | expect(await fixedPoint.muli([BigNumber.from(3).mul(Q112)], BigNumber.from(-2))).to.eq(BigNumber.from(-6))
|
120 | })
|
121 |
|
122 | it('max without overflow, largest int', async () => {
|
123 | const maxInt = BigNumber.from(2).pow(255).sub(1)
|
124 | expect(await fixedPoint.muli([BigNumber.from(1).mul(Q112)], maxInt)).to.be.eq(maxInt)
|
125 |
|
126 | const minInt = BigNumber.from(2).pow(255).mul(-1)
|
127 | await expect(fixedPoint.muli([BigNumber.from(1).mul(Q112)], minInt)).to.be.revertedWith(
|
128 | 'FixedPoint::muli: overflow'
|
129 | )
|
130 |
|
131 | expect(await fixedPoint.muli([BigNumber.from(1).mul(Q112).sub(1)], minInt)).to.be.eq(
|
132 | '-57896044618658097711785492504343942776262393067508711251869655679775811829760'
|
133 | )
|
134 | expect(await fixedPoint.muli([BigNumber.from(1).mul(Q112)], minInt.add(1))).to.be.eq(minInt.add(1))
|
135 | })
|
136 | it('max without overflow, largest fixed point', async () => {
|
137 | const maxMultiplier = BigNumber.from(2)
|
138 | .pow(255 + 112)
|
139 | .div(BigNumber.from(2).pow(224).sub(1))
|
140 | expect(await fixedPoint.muli([BigNumber.from(2).pow(224).sub(1)], maxMultiplier)).to.eq(
|
141 | BigNumber.from('57896044618658097711785492504343953926634992332820282019728792003954417336320')
|
142 | )
|
143 | await expect(fixedPoint.muli([BigNumber.from(2).pow(224).sub(1)], maxMultiplier.add(1))).to.be.revertedWith(
|
144 | 'FixedPoint::muli: overflow'
|
145 | )
|
146 |
|
147 |
|
148 | expect(await fixedPoint.muli([BigNumber.from(2).pow(224).sub(1)], maxMultiplier.mul(-1))).to.eq(
|
149 | BigNumber.from('57896044618658097711785492504343953926634992332820282019728792003954417336320').mul(-1)
|
150 | )
|
151 | await expect(
|
152 | fixedPoint.muli([BigNumber.from(2).pow(224).sub(1)], maxMultiplier.add(1).mul(-1))
|
153 | ).to.be.revertedWith('FixedPoint::muli: overflow')
|
154 | })
|
155 | })
|
156 |
|
157 | describe('#muluq', () => {
|
158 | it('works for 0', async () => {
|
159 | expect((await fixedPoint.muluq([BigNumber.from(0)], [Q112]))[0]).to.eq(BigNumber.from(0))
|
160 | expect((await fixedPoint.muluq([Q112], [BigNumber.from(0)]))[0]).to.eq(BigNumber.from(0))
|
161 | })
|
162 |
|
163 | it('multiplies 3*2', async () => {
|
164 | expect((await fixedPoint.muluq([BigNumber.from(3).mul(Q112)], [BigNumber.from(2).mul(Q112)]))[0]).to.eq(
|
165 | BigNumber.from(3).mul(2).mul(Q112)
|
166 | )
|
167 | })
|
168 | function multiplyExpanded(self: BigNumber, other: BigNumber): BigNumber {
|
169 | const upper = self.shr(112).mul(other.shr(112))
|
170 | const lower = self.mask(112).mul(other.mask(112))
|
171 | const uppersLowero = self.shr(112).mul(other.mask(112))
|
172 | const upperoLowers = self.mask(112).mul(other.shr(112))
|
173 | return upper.mul(Q112).add(uppersLowero).add(upperoLowers).add(lower.div(Q112))
|
174 | }
|
175 | it('multiplies 4/3*4/3', async () => {
|
176 | const multiplier = BigNumber.from(4).mul(Q112).div(3)
|
177 | const expectedResult = multiplyExpanded(multiplier, multiplier)
|
178 | expect((await fixedPoint.muluq([multiplier], [multiplier]))[0]).to.eq(expectedResult)
|
179 | expect(expectedResult.add(1)).to.eq(BigNumber.from(16).mul(Q112).div(9))
|
180 | })
|
181 |
|
182 | it('overflow upper', async () => {
|
183 | const multiplier1 = Q112.mul(2)
|
184 | const multiplier2 = Q112.mul(Q112).div(2)
|
185 | await expect(fixedPoint.muluq([multiplier1], [multiplier2])).to.be.revertedWith(
|
186 | 'FixedPoint::muluq: upper overflow'
|
187 | )
|
188 | expect((await fixedPoint.muluq([multiplier1.sub(1)], [multiplier2]))[0]).to.eq(
|
189 | multiplyExpanded(multiplier1.sub(1), multiplier2)
|
190 | )
|
191 | expect((await fixedPoint.muluq([multiplier1], [multiplier2.sub(1)]))[0]).to.eq(
|
192 | multiplyExpanded(multiplier1, multiplier2.sub(1))
|
193 | )
|
194 | })
|
195 |
|
196 | it('gas for short circuit where one multiplicand is 0', async () => {
|
197 | expect(await fixedPoint.getGasCostOfMuluq([BigNumber.from(0)], [BigNumber.from(30).mul(Q112)])).to.eq(671)
|
198 | expect(await fixedPoint.getGasCostOfMuluq([BigNumber.from(50).mul(Q112)], [BigNumber.from(0)])).to.eq(688)
|
199 | })
|
200 |
|
201 | it('gas', async () => {
|
202 | expect(await fixedPoint.getGasCostOfMuluq([BigNumber.from(30).mul(Q112)], [BigNumber.from(30).mul(Q112)])).to.eq(
|
203 | 992
|
204 | )
|
205 | })
|
206 | })
|
207 |
|
208 | describe('#divuq', () => {
|
209 | it('works for 0 numerator', async () => {
|
210 | expect((await fixedPoint.divuq([BigNumber.from(0)], [Q112]))[0]).to.eq(BigNumber.from(0))
|
211 | })
|
212 |
|
213 | it('throws for 0 denominator', async () => {
|
214 | await expect(fixedPoint.divuq([Q112], [BigNumber.from(0)])).to.be.revertedWith(
|
215 | 'FixedPoint::divuq: division by zero'
|
216 | )
|
217 | })
|
218 |
|
219 | it('equality 30/30', async () => {
|
220 | expect((await fixedPoint.divuq([BigNumber.from(30).mul(Q112)], [BigNumber.from(30).mul(Q112)]))[0]).to.eq(Q112)
|
221 | })
|
222 |
|
223 | it('divides 30/10', async () => {
|
224 | expect((await fixedPoint.divuq([BigNumber.from(30).mul(Q112)], [BigNumber.from(10).mul(Q112)]))[0]).to.eq(
|
225 | BigNumber.from(3).mul(Q112)
|
226 | )
|
227 | })
|
228 |
|
229 | it('divides 35/8', async () => {
|
230 | expect((await fixedPoint.divuq([BigNumber.from(35).mul(Q112)], [BigNumber.from(8).mul(Q112)]))[0]).to.eq(
|
231 | BigNumber.from(4375).mul(Q112).div(1000)
|
232 | )
|
233 | })
|
234 |
|
235 | it('divides 1/3', async () => {
|
236 | expect((await fixedPoint.divuq([BigNumber.from(1).mul(Q112)], [BigNumber.from(3).mul(Q112)]))[0]).to.eq(
|
237 |
|
238 | '1730765619511609209510165443073365'
|
239 | )
|
240 | })
|
241 |
|
242 | it('divides 1e15/3e15 (long division, repeating)', async () => {
|
243 | expect(
|
244 | (
|
245 | await fixedPoint.divuq(
|
246 | [BigNumber.from(10).pow(15).mul(Q112)],
|
247 | [BigNumber.from(3).mul(BigNumber.from(10).pow(15)).mul(Q112)]
|
248 | )
|
249 | )[0]
|
250 | ).to.eq('1730765619511609209510165443073365')
|
251 | })
|
252 |
|
253 | it('boundary of full precision', async () => {
|
254 | const maxNumeratorFullPrecision = BigNumber.from(2).pow(144).sub(1)
|
255 | const minDenominatorFullPrecision = BigNumber.from('4294967296')
|
256 |
|
257 | expect((await fixedPoint.divuq([maxNumeratorFullPrecision], [minDenominatorFullPrecision]))[0]).to.eq(
|
258 | BigNumber.from('26959946667150639794667015087019630673637143213614752866474435543040')
|
259 | )
|
260 |
|
261 | await expect(
|
262 | fixedPoint.divuq([maxNumeratorFullPrecision.add(1)], [minDenominatorFullPrecision])
|
263 | ).to.be.revertedWith('FixedPoint::divuq: overflow')
|
264 |
|
265 | await expect(
|
266 | fixedPoint.divuq([maxNumeratorFullPrecision], [minDenominatorFullPrecision.sub(1)])
|
267 | ).to.be.revertedWith('FixedPoint::divuq: overflow')
|
268 | })
|
269 |
|
270 | it('precision', async () => {
|
271 | const numerator = BigNumber.from(2).pow(144)
|
272 |
|
273 | expect((await fixedPoint.divuq([numerator], [numerator.sub(1)]))[0]).to.eq(
|
274 | BigNumber.from('5192296858534827628530496329220096')
|
275 | )
|
276 |
|
277 | expect((await fixedPoint.divuq([numerator], [numerator.add(1)]))[0]).to.eq(
|
278 | BigNumber.from('5192296858534827628530496329220095')
|
279 | )
|
280 | })
|
281 |
|
282 | it('gas cost of dividend = divisor short circuit', async () => {
|
283 | expect(await fixedPoint.getGasCostOfDivuq([BigNumber.from(30).mul(Q112)], [BigNumber.from(30).mul(Q112)])).to.eq(
|
284 | 698
|
285 | )
|
286 | })
|
287 |
|
288 | it('divuq overflow with smaller numbers', async () => {
|
289 | const numerator = BigNumber.from(2).pow(143)
|
290 | const denominator = BigNumber.from(2).pow(29)
|
291 | await expect(fixedPoint.divuq([numerator], [denominator])).to.be.revertedWith('FixedPoint::divuq: overflow')
|
292 | })
|
293 |
|
294 | it('divuq overflow with large numbers', async () => {
|
295 | const numerator = BigNumber.from(2).pow(145)
|
296 | const denominator = BigNumber.from(2).pow(32)
|
297 | await expect(fixedPoint.divuq([numerator], [denominator])).to.be.revertedWith('FixedPoint::divuq: overflow')
|
298 | })
|
299 |
|
300 | it('gas cost of full precision small dividend short circuit', async () => {
|
301 | expect(await fixedPoint.getGasCostOfDivuq([BigNumber.from(125).mul(Q112)], [BigNumber.from(30).mul(Q112)])).to.eq(
|
302 | 838
|
303 | )
|
304 | expect(await fixedPoint.getGasCostOfDivuq([BigNumber.from(28).mul(Q112)], [BigNumber.from(280).mul(Q112)])).to.eq(
|
305 | 838
|
306 | )
|
307 | expect(await fixedPoint.getGasCostOfDivuq([BigNumber.from(1).mul(Q112)], [BigNumber.from(3).mul(Q112)])).to.eq(
|
308 | 838
|
309 | )
|
310 | })
|
311 |
|
312 | it('gas cost of long division with less than 112 iterations', async () => {
|
313 |
|
314 | expect(
|
315 | await fixedPoint.getGasCostOfDivuq([BigNumber.from(10).pow(10).mul(Q112)], [BigNumber.from(25).mul(Q112)])
|
316 | ).to.eq(1502)
|
317 | })
|
318 |
|
319 | it('gas cost of long division with all iterations', async () => {
|
320 |
|
321 | expect(
|
322 | await fixedPoint.getGasCostOfDivuq(
|
323 | [BigNumber.from(10).pow(10).mul(Q112)],
|
324 | [BigNumber.from(3).mul(BigNumber.from(10).pow(10)).mul(Q112)]
|
325 | )
|
326 | ).to.eq(1502)
|
327 | })
|
328 | })
|
329 |
|
330 | describe('#fraction', () => {
|
331 | it('correct computation less than 1', async () => {
|
332 | expect((await fixedPoint.fraction(4, 100))[0]).to.eq(BigNumber.from(4).mul(Q112).div(100))
|
333 | })
|
334 |
|
335 | it('correct computation greater than 1', async () => {
|
336 | expect((await fixedPoint.fraction(100, 4))[0]).to.eq(BigNumber.from(100).mul(Q112).div(4))
|
337 | })
|
338 |
|
339 | it('fails with 0 denominator', async () => {
|
340 | await expect(fixedPoint.fraction(BigNumber.from(1), BigNumber.from(0))).to.be.revertedWith(
|
341 | 'FixedPoint::fraction: division by zero'
|
342 | )
|
343 | })
|
344 | it('can be called with numerator exceeding uint112 max', async () => {
|
345 | expect((await fixedPoint.fraction(Q112.mul(2359), 6950))[0]).to.eq(Q112.mul(Q112).mul(2359).div(6950))
|
346 | })
|
347 | it('can be called with denominator exceeding uint112 max', async () => {
|
348 | expect((await fixedPoint.fraction(2359, Q112.mul(2359)))[0]).to.eq(1)
|
349 | })
|
350 | it('can be called with numerator exceeding uint144 max', async () => {
|
351 | expect((await fixedPoint.fraction(Q112.mul(2359).mul(BigNumber.from(2).pow(32)), Q112.mul(50)))[0]).to.eq(
|
352 | BigNumber.from(2359).mul(Q112).mul(BigNumber.from(2).pow(32)).div(50)
|
353 | )
|
354 | })
|
355 | it('can be called with numerator and denominator exceeding uint112 max', async () => {
|
356 | expect((await fixedPoint.fraction(Q112.mul(2359), Q112.mul(50)))[0]).to.eq(BigNumber.from(2359).mul(Q112).div(50))
|
357 | })
|
358 | it('short circuits for 0', async () => {
|
359 | expect((await fixedPoint.fraction(0, Q112.mul(Q112).mul(2360)))[0]).to.eq(0)
|
360 | })
|
361 | it('can overflow if result of division does not fit', async () => {
|
362 | await expect(fixedPoint.fraction(Q112.mul(2359), 50)).to.be.revertedWith('FixedPoint::fraction: overflow')
|
363 | })
|
364 | it('gas cost of 0', async () => {
|
365 | expect(await fixedPoint.getGasCostOfFraction(BigNumber.from(0), BigNumber.from(569))).to.eq(210)
|
366 | })
|
367 | it('gas cost of smaller numbers', async () => {
|
368 | expect(await fixedPoint.getGasCostOfFraction(BigNumber.from(239), BigNumber.from(569))).to.eq(314)
|
369 | })
|
370 | it('gas cost of number greater than Q112 numbers', async () => {
|
371 | expect(await fixedPoint.getGasCostOfFraction(Q112.mul(2359), Q112.mul(2360))).to.eq(314)
|
372 | })
|
373 | it('gas cost of number greater than Q112 numbers', async () => {
|
374 | expect(
|
375 | await fixedPoint.getGasCostOfFraction(Q112.mul(BigNumber.from(2).pow(32).mul(2359)), Q112.mul(2360))
|
376 | ).to.eq(996)
|
377 | })
|
378 | })
|
379 |
|
380 | describe('#reciprocal', () => {
|
381 | it('fails for 0', async () => {
|
382 | await expect(fixedPoint.reciprocal([BigNumber.from(0)])).to.be.revertedWith(
|
383 | 'FixedPoint::reciprocal: reciprocal of zero'
|
384 | )
|
385 | })
|
386 | it('fails for 1', async () => {
|
387 | await expect(fixedPoint.reciprocal([BigNumber.from(1)])).to.be.revertedWith('FixedPoint::reciprocal: overflow')
|
388 | })
|
389 | it('works for 0.25', async () => {
|
390 | expect((await fixedPoint.reciprocal([Q112.mul(BigNumber.from(25)).div(100)]))[0]).to.eq(Q112.mul(4))
|
391 | })
|
392 | it('works for 5', async () => {
|
393 | expect((await fixedPoint.reciprocal([Q112.mul(BigNumber.from(5))]))[0]).to.eq(Q112.mul(BigNumber.from(1)).div(5))
|
394 | })
|
395 | })
|
396 |
|
397 | describe('#sqrt', () => {
|
398 | it('works with 0', async () => {
|
399 | expect((await fixedPoint.sqrt([BigNumber.from(0)]))[0]).to.eq(BigNumber.from(0))
|
400 | })
|
401 |
|
402 | it('works with numbers less than 1', async () => {
|
403 | expect((await fixedPoint.sqrt([BigNumber.from(1225).mul(Q112).div(100)]))[0]).to.eq(
|
404 | BigNumber.from(35).mul(Q112).div(10)
|
405 | )
|
406 | })
|
407 |
|
408 | it('gas cost of less than 1', async () => {
|
409 | const input = BigNumber.from(1225).mul(Q112).div(100)
|
410 | expect(await fixedPoint.getGasCostOfSqrt([input])).to.eq(1173)
|
411 | })
|
412 |
|
413 | it('works for 25', async () => {
|
414 | expect((await fixedPoint.sqrt([BigNumber.from(25).mul(Q112)]))[0]).to.eq(BigNumber.from(5).mul(Q112))
|
415 | })
|
416 |
|
417 | it('gas cost of 25', async () => {
|
418 | const input = BigNumber.from(25).mul(Q112)
|
419 | expect(await fixedPoint.getGasCostOfSqrt([input])).to.eq(1191)
|
420 | })
|
421 |
|
422 | it('works for max uint144', async () => {
|
423 | const input = BigNumber.from(2).pow(144).sub(1)
|
424 | const result = (await fixedPoint.sqrt([input]))[0]
|
425 | const expected = BigNumber.from('340282366920938463463374607431768211455')
|
426 | expect(result).to.eq(expected)
|
427 | })
|
428 |
|
429 | it('gas cost of max uint144', async () => {
|
430 | const input = BigNumber.from(2).pow(144).sub(1)
|
431 | expect(await fixedPoint.getGasCostOfSqrt([input])).to.eq(1235)
|
432 | })
|
433 |
|
434 | it('works for 2**144', async () => {
|
435 | const input = BigNumber.from(2).pow(144)
|
436 | const result = (await fixedPoint.sqrt([input]))[0]
|
437 | const expected = BigNumber.from('340282366920938463463374607431768211456')
|
438 | expect(result).to.eq(expected.shr(2).shl(2))
|
439 | })
|
440 |
|
441 | it('gas cost of 2**144', async () => {
|
442 | const input = BigNumber.from(2).pow(144)
|
443 | expect(await fixedPoint.getGasCostOfSqrt([input])).to.eq(1640)
|
444 | })
|
445 |
|
446 | it('works for encoded max uint112', async () => {
|
447 | const input = BigNumber.from(2).pow(112).sub(1).mul(Q112)
|
448 | const result = (await fixedPoint.sqrt([input]))[0]
|
449 | const expected = BigNumber.from('374144419156711147060143317175368417003121712037887')
|
450 | expect(result).to.eq(expected.shr(40).shl(40))
|
451 | })
|
452 |
|
453 | it('gas cost of encoded max uint112', async () => {
|
454 | const input = BigNumber.from(2).pow(112).sub(1).mul(Q112)
|
455 | expect(await fixedPoint.getGasCostOfSqrt([input])).to.eq(1723)
|
456 | })
|
457 |
|
458 | it('works for max uint224', async () => {
|
459 | const input = BigNumber.from(2).pow(224).sub(1)
|
460 | const result = (await fixedPoint.sqrt([input]))[0]
|
461 | const expected = BigNumber.from('374144419156711147060143317175368453031918731001855')
|
462 | expect(result).to.eq(expected.shr(40).shl(40))
|
463 | })
|
464 |
|
465 | it('gas cost of max uint224', async () => {
|
466 | const input = BigNumber.from(2).pow(224).sub(1)
|
467 | expect(await fixedPoint.getGasCostOfSqrt([input])).to.eq(1723)
|
468 | })
|
469 | })
|
470 | })
|