Skip to content

Commit 91c1330

Browse files
Resolve SSW-306
Since we already know the number of LP tokens being minted, we can check that it is correct with an is_sqrt function, rather than calculating the sqrt directly. We're not overly concerned with the pool creation, but it was simple enough to implement. Base: │ PASS [mem: 1173694, cpu: 470849067] mint_test Fixed: │ PASS [mem: 1056495, cpu: 395561132] mint_test
1 parent 2487900 commit 91c1330

File tree

2 files changed

+19
-4
lines changed

2 files changed

+19
-4
lines changed

lib/shared.ak

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,19 @@ pub fn count_orders(tx_inputs: List<Input>) -> Int {
128128
)
129129
}
130130

131+
// Taken from unmerged PR: https://github.com/aiken-lang/stdlib/pull/73/files
132+
pub fn is_sqrt(self: Int, x: Int) -> Bool {
133+
x * x <= self && ( x + 1 ) * ( x + 1 ) > self
134+
}
135+
136+
test is_sqrt1() {
137+
is_sqrt(44203, 210)
138+
}
139+
140+
test is_sqrt2() {
141+
is_sqrt(975461057789971041, 987654321)
142+
}
143+
131144
/// Check whether a specific value has *exactly* the right amount of tokens
132145
/// This is important to, for example, efficiently check the pool output has the correct value
133146
/// Check where this is used, because it's a very subtle bit of logic for where this is safe to do

validators/pool.ak

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use aiken/dict
44
use aiken/hash
55
use aiken/interval
66
use aiken/list
7-
use aiken/math
87
use aiken/option
98
use aiken/transaction.{
109
Datum, InlineDatum, Input, Mint, NoDatum, Output, OutputReference,
@@ -388,11 +387,14 @@ validator(settings_policy_id: PolicyId) {
388387
coin_a_amt
389388
}
390389

391-
// Calculate the initial number of LP tokens; In particular, we adopt Uniswaps convention of
392-
// computing this value as the square root of the product of the two values.
390+
// Check that the quantity of LP tokens is correct; In particular, we adopt Uniswaps convention of
391+
// using the sqrt of the product of the two values for the initial number of LP tokens to mint..
393392
// This helps minimize precision loss: it gives decent initial liquidity values for a range of
394393
// sizes of pools, such that an individual LP token is granular enough for depositing and withdrawing for most users.
395-
expect Some(initial_lq) = math.sqrt(coin_a_amt_sans_protocol_fees * coin_b_amt)
394+
// In particular, though, we don't calculate the sqrt here, which is an expensive function; we instead verify that the
395+
// amount minted is valid by checking that it squares to the correct product
396+
let initial_lq = pool_output_datum.circulating_lp
397+
expect shared.is_sqrt(coin_a_amt_sans_protocol_fees * coin_b_amt, initial_lq)
396398

397399
// And check that we mint the correct tokens, and nothing else.
398400
let expected_mint =

0 commit comments

Comments
 (0)