Skip to content

Commit

Permalink
Merge pull request #49 from invariant-labs/revert-48-revert-42-refact…
Browse files Browse the repository at this point in the history
…or-get-delta-y

Revert "Revert "refactor get delta y and add tests""
  • Loading branch information
zielvna authored Apr 9, 2024
2 parents d74f490 + fa48f94 commit f442e81
Show file tree
Hide file tree
Showing 3 changed files with 150 additions and 21 deletions.
15 changes: 10 additions & 5 deletions contracts/math/clamm.ral
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
Contract CLAMM(
uints: Uints
) extends Log(){
Contract CLAMM(uints: Uints) extends Log() {
enum CLAMMError {
InvalidTickIndex = 800
InvalidTickSpacing = 801
Expand Down Expand Up @@ -131,10 +129,17 @@ Contract CLAMM(
deltaSqrtPrice = sqrtPriceB - sqrtPriceA
}

let mut result = U512 { lower: 0, higher: 0 }

if (roundingUp) {
return (mulUp(deltaSqrtPrice, liquidity, LiquidityScale) + almostOne(SqrtPriceScale)) / one(SqrtPriceScale)
result = uints.bigMulDiv256(deltaSqrtPrice, liquidity, one(LiquidityScale))
result = uints.bigAdd512(result, uints.toU512(almostOne(SqrtPriceScale)))
result = uints.bigDiv512(result, one(SqrtPriceScale), 1)
return uints.toU256(result)
} else {
return mul(deltaSqrtPrice, liquidity, LiquidityScale) / one(SqrtPriceScale)
result = uints.bigMulDiv256(deltaSqrtPrice, liquidity, one(LiquidityScale))
result = uints.bigDiv512(result, one(SqrtPriceScale), 1)
return uints.toU256(result)
}
}

Expand Down
8 changes: 4 additions & 4 deletions contracts/math/uints.ral
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ Contract Uints () {
}

pub fn bigAdd512(a: U512, b: U512) -> U512 {
let (aLowerBLower, overflow) = overflowingAdd(a.lower, b.lower)
let aHigherBHigherOverflow = wrappingAdd(wrappingAdd(a.higher, b.higher), overflow)
return U512 { lower: aLowerBLower, higher: aHigherBHigherOverflow }
let (aLowerB, overflow) = overflowingAdd(a.lower, b.lower)
let aHigherOverflow = wrappingAdd(wrappingAdd(a.higher, b.higher), overflow)
return U512 { lower: aLowerB, higher: aHigherOverflow }
}

pub fn bigDivWrapper(a: U512, b: U256, bDenominator: U256, up: Bool) -> U512 {
Expand Down Expand Up @@ -133,7 +133,7 @@ Contract Uints () {
pub fn bigMulDivUp256(a: U256, b: U256, bDenominator: U256) -> U512 {
let mut result = bigMul256(a, b)

result = bigAdd512(result, U512 { higher: 0, lower: bDenominator - 1 })
result = bigAdd512(result, toU512(bDenominator - 1))
result = bigDiv512(result, bDenominator, 1)

return result
Expand Down
148 changes: 136 additions & 12 deletions test/clamm.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -536,19 +536,143 @@ describe('math tests', () => {
expect(resultDown).toEqual(0n)
})
})
test('get delta y', async () => {
const clamm = await deployCLAMM(sender)
const sqrtPriceA = 234878324943782000000000000n
const sqrtPriceB = 87854456421658000000000000n
const liquidity = 983983249092n
const paramsUp = { args: { sqrtPriceA, sqrtPriceB, liquidity, roundingUp: true } }
const paramsDown = { args: { sqrtPriceA, sqrtPriceB, liquidity, roundingUp: false } }
const resultUp = (await clamm.contractInstance.methods.getDeltaY(paramsUp)).returns
const resultDown = (await clamm.contractInstance.methods.getDeltaY(paramsDown)).returns
// 144669023.842474597804911408
expect(resultUp).toEqual(1446690239n)
expect(resultDown).toEqual(1446690238n)

describe('get delta y', () => {
let clamm: CLAMMInstance

beforeEach(async () => {
clamm = (await deployCLAMM(sender)).contractInstance
})

test('zero at zero liquidity', async () => {
const sqrtPriceA = 1_000000000000000000000000n
const sqrtPriceB = 1_000000000000000000000000n
const liquidity = 0n

const params = { args: { sqrtPriceA, sqrtPriceB, liquidity, roundingUp: false } }
const result = await clamm.methods.getDeltaY(params)

expect(result.returns).toEqual(0n)
})

test('equal at equal liquidity', async () => {
const sqrtPriceA = 1_000000000000000000000000n
const sqrtPriceB = 2_000000000000000000000000n
const liquidity = 2_00000n

const params = { args: { sqrtPriceA, sqrtPriceB, liquidity, roundingUp: false } }
const result = await clamm.methods.getDeltaY(params)

expect(result.returns).toEqual(2n)
})

test('big numbers', async () => {
const sqrtPriceA = 234_878324943782000000000000n
const sqrtPriceB = 87_854456421658000000000000n
const liquidity = 9839832_49092n

const paramsUp = { args: { sqrtPriceA, sqrtPriceB, liquidity, roundingUp: true } }
const paramsDown = { args: { sqrtPriceA, sqrtPriceB, liquidity, roundingUp: false } }
const resultUp = await clamm.methods.getDeltaY(paramsUp)
const resultDown = await clamm.methods.getDeltaY(paramsDown)

expect(resultUp.returns).toEqual(1446690239n)
expect(resultDown.returns).toEqual(1446690238n)
})

test('big', async () => {
const sqrtPriceA = 1_000000000000000000000000n
const sqrtPriceB = 2_000000000000000000000000n
const liquidity = (2n ** 64n - 1n) * 1_00000n

const paramsUp = { args: { sqrtPriceA, sqrtPriceB, liquidity, roundingUp: true } }
const paramsDown = { args: { sqrtPriceA, sqrtPriceB, liquidity, roundingUp: false } }
const resultUp = await clamm.methods.getDeltaY(paramsUp)
const resultDown = await clamm.methods.getDeltaY(paramsDown)

expect(resultUp.returns).toEqual(liquidity / 1_00000n)
expect(resultDown.returns).toEqual(liquidity / 1_00000n)
})

test('overflow', async () => {
const sqrtPriceA = 1_000000000000000000000000n
const sqrtPriceB = 2n ** 256n - 1n
const liquidity = 2n ** 256n - 1n

const paramsUp = { args: { sqrtPriceA, sqrtPriceB, liquidity, roundingUp: true } }
const paramsDown = { args: { sqrtPriceA, sqrtPriceB, liquidity, roundingUp: false } }
await expectError(clamm.methods.getDeltaY(paramsUp))
await expectError(clamm.methods.getDeltaY(paramsDown))
})

test('huge liquidity', async () => {
const sqrtPriceA = 1_000000000000000000000000n
const sqrtPriceB = 1_000000000000000001000000n
const liquidity = 2n ** 256n - 1n

const paramsUp = { args: { sqrtPriceA, sqrtPriceB, liquidity, roundingUp: true } }
const paramsDown = { args: { sqrtPriceA, sqrtPriceB, liquidity, roundingUp: false } }
const resultUp = await clamm.methods.getDeltaY(paramsUp)
const resultDown = await clamm.methods.getDeltaY(paramsDown)

expect(resultUp.returns).toEqual(1157920892373161954235709850086879078532699846656405641n)
expect(resultDown.returns).toEqual(1157920892373161954235709850086879078532699846656405640n)
})
})

describe('get delta y - domain', () => {
let clamm: CLAMMInstance
const minSqrtPrice = 15258932000000000000n
const maxSqrtPrice = 65535_383934512647000000000000n
const minLiquidity = 1n
const maxLiquidity = 2n ** 256n - 1n

beforeEach(async () => {
clamm = (await deployCLAMM(sender)).contractInstance
})

it('maximize delta sqrt price and liquidity', async () => {
const paramsUp = {
args: { sqrtPriceA: maxSqrtPrice, sqrtPriceB: minSqrtPrice, liquidity: maxLiquidity, roundingUp: true }
}
const paramsDown = {
args: { sqrtPriceA: maxSqrtPrice, sqrtPriceB: minSqrtPrice, liquidity: maxLiquidity, roundingUp: false }
}
const resultUp = await clamm.methods.getDeltaY(paramsUp)
const resultDown = await clamm.methods.getDeltaY(paramsDown)

expect(resultUp.returns).toEqual(75884790229800029582010010030152469040784228171629896039591333116952600000001n)
expect(resultDown.returns).toEqual(75884790229800029582010010030152469040784228171629896039591333116952599999999n)
})

it('can be zero', async () => {
const params = {
args: { sqrtPriceA: maxSqrtPrice, sqrtPriceB: maxSqrtPrice - 1n, liquidity: minLiquidity, roundingUp: false }
}
const result = await clamm.methods.getDeltaY(params)

expect(result.returns).toEqual(0n)
})

it('liquidity is zero', async () => {
const params = {
args: { sqrtPriceA: maxSqrtPrice, sqrtPriceB: minSqrtPrice, liquidity: 0n, roundingUp: true }
}
const result = await clamm.methods.getDeltaY(params)

expect(result.returns).toEqual(0n)
})

it('all max', async () => {
const params = {
args: { sqrtPriceA: maxSqrtPrice, sqrtPriceB: maxSqrtPrice, liquidity: maxLiquidity, roundingUp: true }
}
const result = await clamm.methods.getDeltaY(params)

expect(result.returns).toEqual(0n)
})
})

test('get next sqrt price x up', async () => {
const clamm = await deployCLAMM(sender)
{
Expand Down

0 comments on commit f442e81

Please sign in to comment.