Skip to content

Commit 12a55da

Browse files
Merge pull request #58 from SundaeSwap-finance/pi/SSW-306-efficient-sqrt
Resolve SSW-306
2 parents db3d33e + 15f443c commit 12a55da

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
@@ -132,6 +132,19 @@ pub fn count_orders(tx_inputs: List<Input>) -> Int {
132132
}
133133
}
134134

135+
// Taken from unmerged PR: https://github.com/aiken-lang/stdlib/pull/73/files
136+
pub fn is_sqrt(self: Int, x: Int) -> Bool {
137+
x * x <= self && ( x + 1 ) * ( x + 1 ) > self
138+
}
139+
140+
test is_sqrt1() {
141+
is_sqrt(44203, 210)
142+
}
143+
144+
test is_sqrt2() {
145+
is_sqrt(975461057789971041, 987654321)
146+
}
147+
135148
/// Check whether a specific value has *exactly* the right amount of tokens
136149
/// This is important to, for example, efficiently check the pool output has the correct value
137150
/// 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
@@ -3,7 +3,6 @@ use aiken/dict
33
use aiken/hash
44
use aiken/interval
55
use aiken/list
6-
use aiken/math
76
use aiken/transaction.{
87
InlineDatum, Input, Mint, Output, OutputReference,
98
ScriptContext, Transaction, TransactionId,
@@ -387,11 +386,14 @@ validator(settings_policy_id: PolicyId) {
387386
coin_a_amt
388387
}
389388

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

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

0 commit comments

Comments
 (0)