Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor get delta y and add tests #42

Merged
merged 3 commits into from
Apr 4, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions contracts/math/clamm.ral
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
Contract CLAMM() extends Log(){
Contract CLAMM(uints: Uints) extends Log() {
enum CLAMMError {
InvalidTickIndex = 800
InvalidTickSpacing = 801
CastOverflow = 802
}

pub fn computeSwapStep(
Expand Down Expand Up @@ -133,10 +134,19 @@ Contract CLAMM() extends Log(){
deltaSqrtPrice = sqrtPriceB - sqrtPriceA
}

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

if (roundingUp) {
return (mulUp(deltaSqrtPrice, liquidity, LiquidityScale) + almostOne(SqrtPriceScale)) / one(SqrtPriceScale)
result = uints.bigMulUp(deltaSqrtPrice, liquidity, one(LiquidityScale))
result = uints.bigAdd512(result, almostOne(SqrtPriceScale))
result = uints.bigDiv(result, one(SqrtPriceScale), 1)
assert!(result.higher == 0, CLAMMError.CastOverflow)
return result.lower
zielvna marked this conversation as resolved.
Show resolved Hide resolved
} else {
return mul(deltaSqrtPrice, liquidity, LiquidityScale) / one(SqrtPriceScale)
result = uints.bigMulUp(deltaSqrtPrice, liquidity, one(LiquidityScale))
result = uints.bigDiv(result, one(SqrtPriceScale), 1)
assert!(result.higher == 0, CLAMMError.CastOverflow)
zielvna marked this conversation as resolved.
Show resolved Hide resolved
return result.lower
zielvna marked this conversation as resolved.
Show resolved Hide resolved
}
}

Expand Down
10 changes: 5 additions & 5 deletions contracts/math/uints.ral
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,10 @@ Contract Uints () {
return div(a, b, bDenominator, true)
}

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 }
pub fn bigAdd512(a: U512, b: U256) -> U512 {
let (aLowerB, overflow) = overflowingAdd(a.lower, b)
let aHigherOverflow = wrappingAdd(a.higher, overflow)
return U512 { lower: aLowerB, higher: aHigherOverflow }
}

pub fn mul(a: U256, b: U256) -> U512 {
Expand Down Expand Up @@ -117,7 +117,7 @@ Contract Uints () {
pub fn bigMulUp(a: U256, b: U256, bDenominator: U256) -> U512 {
let mut result = mul(a, b)

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

return result
Expand Down
6 changes: 5 additions & 1 deletion src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -319,9 +319,13 @@ export async function deployPositionsCounter(signer: SignerProvider) {
}

export async function deployCLAMM(signer: SignerProvider) {
const uints = await deployUints(signer)

return await waitTxConfirmed(
CLAMM.deploy(signer, {
initialFields: {}
initialFields: {
uints: uints.contractInstance.contractId
}
})
)
}
Expand Down
151 changes: 138 additions & 13 deletions test/clamm.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { ONE_ALPH, web3 } from '@alephium/web3'
import { getSigner } from '@alephium/web3-test'
import { PrivateKeyWallet } from '@alephium/web3-wallet'
import { assert } from 'console'
import { deployCLAMM } from '../src/utils'
import { CLAMMInstance } from '../artifacts/ts'
import { deployCLAMM, expectError } from '../src/utils'

web3.setCurrentNodeProvider('http://127.0.0.1:22973')

Expand Down Expand Up @@ -211,19 +212,143 @@ describe('math tests', () => {
expect(resultUp).toEqual(70109n)
expect(resultDown).toEqual(70108n)
})
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
4 changes: 2 additions & 2 deletions test/uints.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,13 +166,13 @@ describe('uints tests', () => {
const uints = await deployUints(sender)
{
const a = { higher: 0n, lower: 10n }
const b = { higher: 0n, lower: 20n }
const b = 20n
const result = (await uints.contractInstance.methods.bigAdd512({ args: { a, b } })).returns
expect(result).toStrictEqual({ higher: 0n, lower: 30n })
}
{
const a = { higher: 0n, lower: 115792089237316195423570985008687907853269984665640564039457584007913129639935n }
const b = { higher: 0n, lower: 20n }
const b = 20n
const result = (await uints.contractInstance.methods.bigAdd512({ args: { a, b } })).returns
expect(result).toStrictEqual({ higher: 1n, lower: 19n })
}
Expand Down
Loading