Skip to content

Commit

Permalink
Aligned with master
Browse files Browse the repository at this point in the history
  • Loading branch information
Sniezka1927 committed Jul 9, 2024
2 parents 0c8dc33 + d5962fd commit e27c44b
Show file tree
Hide file tree
Showing 17 changed files with 357 additions and 122 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ node_modules
coverage
artifacts
.project.json
dist
dist
.ralph-lsp
8 changes: 4 additions & 4 deletions contracts/invariant.ral
Original file line number Diff line number Diff line change
Expand Up @@ -469,16 +469,16 @@ Contract Invariant(

if (xToY) {
if (pool.reserveX == pool.reserveY) {
Reserve(pool.reserveX).swap{caller -> tokenX: amount}(caller, tokenX, tokenY, calculateSwapResult.amountIn, calculateSwapResult.amountOut)
Reserve(pool.reserveX).swap{caller -> tokenX: calculateSwapResult.amountIn}(caller, tokenX, tokenY, calculateSwapResult.amountIn, calculateSwapResult.amountOut)
} else {
Reserve(pool.reserveX).depositSingleAsset{caller -> tokenX: amount}(caller, tokenX, calculateSwapResult.amountIn)
Reserve(pool.reserveX).depositSingleAsset{caller -> tokenX: calculateSwapResult.amountIn}(caller, tokenX, calculateSwapResult.amountIn)
Reserve(pool.reserveY).withdrawSingleAsset(caller, tokenY, calculateSwapResult.amountOut)
}
} else {
if (pool.reserveX == pool.reserveY) {
Reserve(pool.reserveX).swap{caller -> tokenY: amount}(caller, tokenY, tokenX, calculateSwapResult.amountIn, calculateSwapResult.amountOut)
Reserve(pool.reserveX).swap{caller -> tokenY: calculateSwapResult.amountIn}(caller, tokenY, tokenX, calculateSwapResult.amountIn, calculateSwapResult.amountOut)
} else {
Reserve(pool.reserveX).depositSingleAsset{caller -> tokenY: amount}(caller, tokenY, calculateSwapResult.amountIn)
Reserve(pool.reserveX).depositSingleAsset{caller -> tokenY: calculateSwapResult.amountIn}(caller, tokenY, calculateSwapResult.amountIn)
Reserve(pool.reserveY).withdrawSingleAsset(caller, tokenX, calculateSwapResult.amountOut)
}
}
Expand Down
4 changes: 2 additions & 2 deletions contracts/math/clamm.ral
Original file line number Diff line number Diff line change
Expand Up @@ -276,8 +276,8 @@ Contract CLAMM() extends Uints(), Log(){
}

let mut nextSqrtPrice = 0
if (byAmountIn == true) {
let amountAfterFee = toU256(bigMulDiv256(amount, (one(PercentageScale) - fee), PercentageScale))
if (byAmountIn) {
let amountAfterFee = toU256(bigMulDiv256(amount, (one(PercentageScale) - fee), one(PercentageScale)))
nextSqrtPrice = getNextSqrtPriceFromInput(startingSqrtPrice, liquidity, amountAfterFee, xToY)
} else {
nextSqrtPrice = getNextSqrtPriceFromOutput(startingSqrtPrice, liquidity, amount, xToY)
Expand Down
12 changes: 8 additions & 4 deletions contracts/scripts/invariant_tx.ral
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,15 @@ TxScript ClaimFee(invariant: Invariant, index: U256) {
invariant.claimFee(index)
}

TxScript Swap(invariant: Invariant, poolKey: PoolKey, xToY: Bool, amount: U256, byAmountIn: Bool, sqrtPriceLimit: U256) {
if(xToY) {
let _ = invariant.swap{callerAddress!() -> poolKey.tokenX: amount}(poolKey, xToY, amount, byAmountIn, sqrtPriceLimit)
TxScript Swap(invariant: Invariant, poolKey: PoolKey, xToY: Bool, amount: U256, byAmountIn: Bool, sqrtPriceLimit: U256, approvedAmount: U256) {
let mut tokensApproved = amount
if (!byAmountIn) {
tokensApproved = approvedAmount
}
if (xToY) {
let _ = invariant.swap{callerAddress!() -> poolKey.tokenX: tokensApproved}(poolKey, xToY, amount, byAmountIn, sqrtPriceLimit)
} else {
let _ = invariant.swap{callerAddress!() -> poolKey.tokenY: amount}(poolKey, xToY, amount, byAmountIn, sqrtPriceLimit)
let _ = invariant.swap{callerAddress!() -> poolKey.tokenY: tokensApproved}(poolKey, xToY, amount, byAmountIn, sqrtPriceLimit)
}
}

Expand Down
11 changes: 7 additions & 4 deletions src/snippets.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Address, SignerProvider } from '@alephium/web3'
import { InvariantInstance, TokenFaucetInstance } from '../artifacts/ts'
import { LiquidityScale, MinSqrtPrice, PercentageScale } from './consts'
import { MinSqrtPrice, PercentageScale } from './consts'
import {
getPool,
getReserveBalances,
Expand All @@ -9,12 +9,14 @@ import {
initPosition,
initSwap,
initTokensXY,
toLiquidity,
transferPosition,
verifyPositionList,
withdrawTokens
} from './testUtils'
import { balanceOf, deployInvariant, newFeeTier, newPoolKey } from './utils'
import { PrivateKeyWallet } from '@alephium/web3-wallet'
import { calculateSqrtPrice } from './math'

type TokenInstance = TokenFaucetInstance

Expand Down Expand Up @@ -44,12 +46,13 @@ export const initBasicPool = async (
tokenX: TokenInstance,
tokenY: TokenInstance
) => {
const initSqrtPrice = 10n ** 24n
const initTick = 0n
const initSqrtPrice = await calculateSqrtPrice(initTick)
const feeTier = await newFeeTier(fee, tickSpacing)
const tx = await initPool(invariant, admin, tokenX, tokenY, feeTier, initSqrtPrice, 0n)
const poolKey = await newPoolKey(tokenX.contractId, tokenY.contractId, feeTier)
const pool = await getPool(invariant, poolKey)
expect(pool).toMatchObject({ poolKey, sqrtPrice: initSqrtPrice, exist: true })
expect(pool).toMatchObject({ poolKey, sqrtPrice: initSqrtPrice, exists: true })
return tx
}

Expand All @@ -67,7 +70,7 @@ export const initBasicPosition = async (
const poolKey = await newPoolKey(tokenX.contractId, tokenY.contractId, feeTier)

const poolBefore = await getPool(invariant, poolKey)
const liquidityDelta = 1000000n * 10n ** LiquidityScale
const liquidityDelta = toLiquidity(1000000n)
const slippageLimit = poolBefore.sqrtPrice
const [lowerTick, upperTick] = [-20n, 10n]
const tx = await initPosition(
Expand Down
20 changes: 13 additions & 7 deletions src/testUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import {
TokenFaucetInstance,
WithdrawProtocolFee,
CreatePosition,
Reserve,
TransferPosition
} from '../artifacts/ts'
import {
Expand All @@ -33,7 +32,7 @@ import {
} from './utils'
import { expectAssertionError } from '@alephium/web3-test'
import { PrivateKeyWallet } from '@alephium/web3-wallet'
import { VMError } from './consts'
import { LiquidityScale, VMError } from './consts'
import { FeeTier, Pool, PoolKey } from '../artifacts/ts/types'

type TokenInstance = TokenFaucetInstance
Expand Down Expand Up @@ -318,24 +317,26 @@ export const verifyPositionList = async (
isWhole = false
) => {
for (let n = 1n; n <= length; ++n) {
const { exist: positionExists } = await getPosition(invariant, owner, n)
const { exists: positionExists } = await getPosition(invariant, owner, n)
expect(positionExists).toBeTruthy()
}

if (isWhole) {
const { exist: positionExists } = await getPosition(invariant, owner, length + 1n)
const { exists: positionExists } = await getPosition(invariant, owner, length + 1n)
expect(positionExists).toBeFalsy()
}
}

/** When not using `byAmountIn` set approvedTokens manually via the last parameter. */
export async function initSwap(
invariant: InvariantInstance,
signer: SignerProvider,
poolKey: PoolKey,
xToY: boolean,
amount: bigint,
byAmountIn: boolean,
sqrtPriceLimit: bigint
sqrtPriceLimit: bigint,
approvedAmount = amount
) {
const id = xToY ? poolKey.tokenX : poolKey.tokenY
return await Swap.execute(signer, {
Expand All @@ -345,9 +346,10 @@ export async function initSwap(
xToY,
amount,
byAmountIn,
sqrtPriceLimit
sqrtPriceLimit,
approvedAmount
},
tokens: [{ id, amount }],
tokens: [{ id, amount: approvedAmount }],
attoAlphAmount: DUST_AMOUNT
})
}
Expand Down Expand Up @@ -391,3 +393,7 @@ export const getReserveBalances = async (invariant: InvariantInstance, poolKey:
const y = await balanceOf(poolKey.tokenY, reserveY)
return { x, y }
}

export const toLiquidity = (value: bigint) => {
return value * 10n ** LiquidityScale
}
29 changes: 17 additions & 12 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,25 +134,30 @@ export function decodePools(string: string) {
return pools
}

function createEntityProxy<T>(entity: T, exists: boolean) {
return new Proxy(
{ ...entity, exists },
{
get(target, prop, receiver) {
if (!exists && prop !== 'exists' && prop in target) {
throw new Error(`Entity does not exist, cannot access property "${String(prop)}"`)
}
return Reflect.get(target, prop, receiver)
}
}
)
}

export function decodePool(array: [boolean, Pool]) {
return {
exist: array[0],
...array[1]
}
return createEntityProxy(array[1], array[0])
}

export function decodeTick(array: [boolean, Tick]) {
return {
exist: array[0],
...array[1]
}
return createEntityProxy(array[1], array[0])
}

export function decodePosition(array: [boolean, Position]) {
return {
exist: array[0],
...array[1]
}
return createEntityProxy(array[1], array[0])
}

export function hexToBytes(hex: string): Uint8Array {
Expand Down
2 changes: 1 addition & 1 deletion test/create_pool.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ describe('invariant tests', () => {
liquidity: 0n,
poolKey,
feeReceiver: admin.address,
exist: true
exists: true
}
expect(pool).toMatchObject(expectedPool)
})
Expand Down
7 changes: 4 additions & 3 deletions test/cross.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ import {
initDexAndTokens
} from '../src/snippets'
import { balanceOf, newFeeTier, newPoolKey } from '../src/utils'
import { LiquidityScale, MinSqrtPrice } from '../src/consts'
import { MinSqrtPrice } from '../src/consts'
import {
getPool,
getReserveBalances,
getTick,
initFeeTier,
initPosition,
initSwap,
toLiquidity,
withdrawTokens
} from '../src/testUtils'

Expand All @@ -37,7 +38,7 @@ describe('cross tests', () => {
await initBasicPosition(invariant, positionsOwner, tokenX, tokenY)

// cross position
const liquidityDelta = 1_000_000n * 10n ** LiquidityScale
const liquidityDelta = toLiquidity(1_000_000n)
{
// definitely enough for the given liquidity/ticks
const approvedAmount = liquidityDelta
Expand Down Expand Up @@ -97,7 +98,7 @@ describe('cross tests', () => {
}
expect(swapperBalance).toMatchObject({ tokenX: 0n, tokenY: 990n })

const liquidityChange = 1000000n * 10n ** LiquidityScale
const liquidityChange = toLiquidity(1000000n)
const lowerTick = await getTick(invariant, poolKey, -20n)
const middleTick = await getTick(invariant, poolKey, -10n)
const upperTick = await getTick(invariant, poolKey, 10n)
Expand Down
Loading

0 comments on commit e27c44b

Please sign in to comment.