Skip to content

Commit

Permalink
add transfer position entrypoint
Browse files Browse the repository at this point in the history
  • Loading branch information
zielvna committed Feb 24, 2024
1 parent f61bfd9 commit d28dc37
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 73 deletions.
94 changes: 48 additions & 46 deletions contracts/collections/positions.ral
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
Contract Positions(positionTemplateContractId: ByteVec, positionsCounterTemplateId: ByteVec) {
Contract Positions(positionTemplateContractId: ByteVec, positionsCounterContractId: ByteVec) {
enum PositionsError {
NotOwner = 500
PositionNotExist = 501
}

@using(preapprovedAssets = true, checkExternalCaller = false)
pub fn add(
caller: Address,
Expand All @@ -12,20 +17,9 @@ Contract Positions(positionTemplateContractId: ByteVec, positionsCounterTemplate
tokensOwedX: U256,
tokensOwedY: U256
) -> () {
let length = getLength(caller)

if (length == 0) {
let (positionsCounterEncodedImmFields, positionsCounterEncodedMutFields) = PositionsCounter.encodeFields!(1)
copyCreateSubContract!{caller -> ALPH: 1 alph}(
toByteVec!(caller),
positionsCounterTemplateId,
positionsCounterEncodedImmFields,
positionsCounterEncodedMutFields
)
} else {
let contract = PositionsCounter(subContractId!(toByteVec!(caller)))
contract.set(contract.get() + 1)
}
let positionsCounter = PositionsCounter(positionsCounterContractId)
let length = positionsCounter.get()
positionsCounter.set(length + 1)

let (encodedImmFields, encodedMutFields) = Position.encodeFields!(
poolKey,
Expand All @@ -36,82 +30,91 @@ Contract Positions(positionTemplateContractId: ByteVec, positionsCounterTemplate
feeGrowthInsideY,
lastBlockNumber,
tokensOwedX,
tokensOwedY
tokensOwedY,
caller,
true
)
copyCreateSubContract!{caller -> ALPH: 1 alph}(
toByteVec!(caller) ++ toByteVec!(length + 1),
toByteVec!(length + 1),
positionTemplateContractId,
encodedImmFields,
encodedMutFields
)
}

fn getLength(owner: Address) -> U256 {
let subContractId = subContractId!(toByteVec!(owner))
@using(checkExternalCaller = false)
pub fn remove(caller: Address, index: U256) -> () {
let subContractId = subContractId!(toByteVec!(index))
assert!(contractExists!(subContractId), PositionsError.PositionNotExist)
let position = Position(subContractId)
assert!(position.getOwner() == caller, PositionsError.NotOwner)
position.setIsActive(false)
}

if(contractExists!(subContractId)) {
return PositionsCounter(subContractId).get()
} else {
return 0
}
@using(checkExternalCaller = false)
pub fn transfer(caller: Address, index: U256, newOwner: Address) -> () {
let subContractId = subContractId!(toByteVec!(index))
assert!(contractExists!(subContractId), PositionsError.PositionNotExist)
let position = Position(subContractId)
assert!(position.getOwner() == caller, PositionsError.NotOwner)
position.setOwner(newOwner)
}

pub fn getPoolKey(owner: Address, index: U256) -> ByteVec {
let subContractId = subContractId!(toByteVec!(owner) ++ toByteVec!(index))
pub fn getPoolKey(index: U256) -> ByteVec {
let subContractId = subContractId!(toByteVec!(index))
return Position(subContractId).getPoolKey()
}

pub fn getLowerTickIndex(owner: Address, index: U256) -> I256 {
let subContractId = subContractId!(toByteVec!(owner) ++ toByteVec!(index))
pub fn getLowerTickIndex(index: U256) -> I256 {
let subContractId = subContractId!(toByteVec!(index))
return Position(subContractId).getLowerTickIndex()
}

pub fn getUpperTickIndex(owner: Address, index: U256) -> I256 {
let subContractId = subContractId!(toByteVec!(owner) ++ toByteVec!(index))
pub fn getUpperTickIndex(index: U256) -> I256 {
let subContractId = subContractId!(toByteVec!(index))
return Position(subContractId).getUpperTickIndex()
}

pub fn getLiquidity(owner: Address, index: U256) -> U256 {
let subContractId = subContractId!(toByteVec!(owner) ++ toByteVec!(index))
pub fn getLiquidity(index: U256) -> U256 {
let subContractId = subContractId!(toByteVec!(index))
return Position(subContractId).getLiquidity()
}

pub fn getTokensOwedX(owner: Address, index: U256) -> U256 {
let subContractId = subContractId!(toByteVec!(owner) ++ toByteVec!(index))
pub fn getTokensOwedX(index: U256) -> U256 {
let subContractId = subContractId!(toByteVec!(index))
return Position(subContractId).getTokensOwedX()
}

pub fn getTokensOwedY(owner: Address, index: U256) -> U256 {
let subContractId = subContractId!(toByteVec!(owner) ++ toByteVec!(index))
pub fn getTokensOwedY(index: U256) -> U256 {
let subContractId = subContractId!(toByteVec!(index))
return Position(subContractId).getTokensOwedY()
}

@using(checkExternalCaller = false)
pub fn setTokensOwedX(owner: Address, index: U256, value: U256) -> () {
let subContractId = subContractId!(toByteVec!(owner) ++ toByteVec!(index))
pub fn setTokensOwedX(index: U256, value: U256) -> () {
let subContractId = subContractId!(toByteVec!(index))
Position(subContractId).setTokensOwedX(value)
}

@using(checkExternalCaller = false)
pub fn setTokensOwedY(owner: Address, index: U256, value: U256) -> () {
let subContractId = subContractId!(toByteVec!(owner) ++ toByteVec!(index))
pub fn setTokensOwedY(index: U256, value: U256) -> () {
let subContractId = subContractId!(toByteVec!(index))
Position(subContractId).setTokensOwedY(value)
}

@using(checkExternalCaller = false)
pub fn update(
owner: Address,
index: U256,
sign: Bool,
liquidityDelta: U256,
feeGrowthInsideX: U256,
feeGrowthInsideY: U256
) -> () {
Position(subContractId!(toByteVec!(owner) ++ toByteVec!(index))).update(sign, liquidityDelta, feeGrowthInsideX, feeGrowthInsideY)
Position(subContractId!(toByteVec!(index))).update(sign, liquidityDelta, feeGrowthInsideX, feeGrowthInsideY)
}

pub fn get(owner: Address, index: U256) -> (Bool, U256, I256, I256, U256, U256, U256, U256, U256) {
let subContractId = subContractId!(toByteVec!(owner) ++ toByteVec!(index))
pub fn get(index: U256) -> (Bool, U256, I256, I256, U256, U256, U256, U256, U256) {
let subContractId = subContractId!(toByteVec!(index))

if (!contractExists!(subContractId)) {
return false, 0, 0i, 0i, 0, 0, 0, 0, 0
Expand All @@ -122,7 +125,6 @@ Contract Positions(positionTemplateContractId: ByteVec, positionsCounterTemplate

@using(checkExternalCaller = false)
pub fn wrappedModify(
caller: Address,
index: U256,
poolsContractId: ByteVec,
ticksContractId: ByteVec,
Expand All @@ -135,6 +137,6 @@ Contract Positions(positionTemplateContractId: ByteVec, positionsCounterTemplate
currentTimestamp: U256,
tickSpacing: U256
) -> (U256, U256) {
return Position(subContractId!(toByteVec!(caller) ++ toByteVec!(index))).modify(poolsContractId, ticksContractId, clammContractId, poolKey, upperTick, lowerTick, liquidityDelta, add, currentTimestamp, tickSpacing)
return Position(subContractId!(toByteVec!(index))).modify(poolsContractId, ticksContractId, clammContractId, poolKey, upperTick, lowerTick, liquidityDelta, add, currentTimestamp, tickSpacing)
}
}
42 changes: 23 additions & 19 deletions contracts/invariant.ral
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,8 @@ Contract Invariant(
return Pools(poolsContractId).get(generatePoolKey(token0, token1, fee, tickSpacing))
}

pub fn getPosition(owner: Address, index: U256) -> (Bool, U256, I256, I256, U256, U256, U256, U256, U256) {
return Positions(positionsContractId).get(owner, index)
pub fn getPosition(index: U256) -> (Bool, U256, I256, I256, U256, U256, U256, U256, U256) {
return Positions(positionsContractId).get(index)
}

pub fn isTickInitialized(token0: Address, token1: Address, fee: U256, tickSpacing: U256, index: I256) -> Bool {
Expand Down Expand Up @@ -248,7 +248,6 @@ Contract Invariant(
slippageLimitUpper: U256
) -> () {
let pools = Pools(poolsContractId)
let caller = callerAddress!()
let currentTimestamp = blockTimeStamp!()

assert!(liquidityDelta != 0, InvariantError.ZeroLiquidity)
Expand All @@ -267,7 +266,7 @@ Contract Invariant(

assert!(poolCurrentSqrtPrice >= slippageLimitLower && poolCurrentSqrtPrice <= slippageLimitUpper, InvariantError.PriceLimitReached)

let (x, y) = Positions(positionsContractId).wrappedModify(caller, index, poolsContractId, ticksContractId, clammContractId, poolKey, upperTick, lowerTick, liquidityDelta, true, currentTimestamp, tickSpacing)
let (x, y) = Positions(positionsContractId).wrappedModify(index, poolsContractId, ticksContractId, clammContractId, poolKey, upperTick, lowerTick, liquidityDelta, true, currentTimestamp, tickSpacing)

let tokenXId = pools.getTokenXId(poolKey)
let tokenYId = pools.getTokenYId(poolKey)
Expand All @@ -281,21 +280,21 @@ Contract Invariant(
let caller = callerAddress!()
let positions = Positions(positionsContractId)

let poolKey = positions.getPoolKey(caller, index)
let upperTick = positions.getUpperTickIndex(caller, index)
let lowerTick = positions.getLowerTickIndex(caller, index)
let liquidity = positions.getLiquidity(caller, index)
let poolKey = positions.getPoolKey(index)
let upperTick = positions.getUpperTickIndex(index)
let lowerTick = positions.getLowerTickIndex(index)
let liquidity = positions.getLiquidity(index)

let tickSpacing = Pools(poolsContractId).getTickSpacing(poolKey)

let (mut x, mut y) = Positions(positionsContractId).wrappedModify(caller, index, poolsContractId, ticksContractId, clammContractId, poolKey, upperTick, lowerTick, liquidity, false, blockTimeStamp!(), tickSpacing)
let (mut x, mut y) = Positions(positionsContractId).wrappedModify(index, poolsContractId, ticksContractId, clammContractId, poolKey, upperTick, lowerTick, liquidity, false, blockTimeStamp!(), tickSpacing)

let pools = Pools(poolsContractId)

let tokenXId = pools.getTokenXId(poolKey)
let tokenYId = pools.getTokenYId(poolKey)
let tokensOwedX = positions.getTokensOwedX(caller, index)
let tokensOwedY = positions.getTokensOwedY(caller, index)
let tokensOwedX = positions.getTokensOwedX(index)
let tokensOwedY = positions.getTokensOwedY(index)

x = x + tokensOwedX
y = y + tokensOwedY
Expand All @@ -304,6 +303,11 @@ Contract Invariant(
transferTokenFromSelf!(caller, tokenYId, y)
}

@using(preapprovedAssets = true, assetsInContract = true, checkExternalCaller = false)
pub fn transferPosition(index: U256, newOwner: Address) -> () {
Positions(positionsContractId).transfer(callerAddress!(), index, newOwner)
}

@using(updateFields = false, checkExternalCaller = false)
pub fn quote(
token0: Address,
Expand Down Expand Up @@ -341,18 +345,18 @@ Contract Invariant(
let positions = Positions(positionsContractId)
let pools = Pools(poolsContractId)

let poolKey = positions.getPoolKey(caller, index)
let upperTick = positions.getUpperTickIndex(caller, index)
let lowerTick = positions.getLowerTickIndex(caller, index)
let poolKey = positions.getPoolKey(index)
let upperTick = positions.getUpperTickIndex(index)
let lowerTick = positions.getLowerTickIndex(index)
let tickSpacing = pools.getTickSpacing(poolKey)

positions.wrappedModify(caller, index, poolsContractId, ticksContractId, clammContractId, poolKey, upperTick, lowerTick, 0, false, blockTimeStamp!(), tickSpacing)
positions.wrappedModify(index, poolsContractId, ticksContractId, clammContractId, poolKey, upperTick, lowerTick, 0, false, blockTimeStamp!(), tickSpacing)

let tokensOwedX = positions.getTokensOwedX(caller, index)
let tokensOwedY = positions.getTokensOwedY(caller, index)
let tokensOwedX = positions.getTokensOwedX(index)
let tokensOwedY = positions.getTokensOwedY(index)

positions.setTokensOwedX(caller, index, 0)
positions.setTokensOwedY(caller, index, 0)
positions.setTokensOwedX(index, 0)
positions.setTokensOwedY(index, 0)

let tokenXId = pools.getTokenXId(poolKey)
let tokenYId = pools.getTokenYId(poolKey)
Expand Down
18 changes: 17 additions & 1 deletion contracts/storage/position.ral
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ Contract Position(
mut posFeeGrowthInsideY: U256,
posLastBlockNumber: U256,
mut posTokensOwedX: U256,
mut posTokensOwedY: U256
mut posTokensOwedY: U256,
mut posOwner: Address,
mut posIsActive: Bool
) extends Decimal() {
enum PositionError {
InsufficientLiquidity = 700
Expand Down Expand Up @@ -50,6 +52,10 @@ Contract Position(
return posTokensOwedY
}

pub fn getOwner() -> Address {
return posOwner
}

pub fn get() -> (U256, I256, I256, U256, U256, U256, U256, U256) {
return posLiquidity, posLowerTickIndex, posUpperTickIndex, posFeeGrowthInsideX, posFeeGrowthInsideY, posLastBlockNumber, posTokensOwedX, posTokensOwedY
}
Expand All @@ -64,6 +70,16 @@ Contract Position(
posTokensOwedY = tokensOwedY
}

@using(updateFields = true, checkExternalCaller = false)
pub fn setOwner(owner: Address) -> () {
posOwner = owner
}

@using(updateFields = true, checkExternalCaller = false)
pub fn setIsActive(isActive: Bool) -> () {
posIsActive = isActive
}

@using(updateFields = false, checkExternalCaller = false)
pub fn modify(
poolsContractId: ByteVec,
Expand Down
8 changes: 5 additions & 3 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,12 +141,12 @@ export async function deployFeeTiers(signer: SignerProvider, feeTier: string) {
)
}

export async function deployPositions(signer: SignerProvider, positionId: string, positionCounterId: string) {
export async function deployPositions(signer: SignerProvider, positionId: string, positionsCounterContractId: string) {
return await waitTxConfirmed(
Positions.deploy(signer, {
initialFields: {
positionTemplateContractId: positionId,
positionsCounterTemplateId: positionCounterId
positionsCounterContractId
}
})
)
Expand All @@ -164,7 +164,9 @@ export async function deployPosition(signer: SignerProvider) {
posFeeGrowthInsideY: 0n,
posLastBlockNumber: 0n,
posTokensOwedX: 0n,
posTokensOwedY: 0n
posTokensOwedY: 0n,
posOwner: ZERO_ADDRESS,
posIsActive: false
}
})
)
Expand Down
2 changes: 1 addition & 1 deletion test/position.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ describe('position tests', () => {
expect(invariantToken1BalanceAfter).toBe(50n)

const position = await invariant.methods.getPosition({
args: { owner: sender.address, index: 1n }
args: { index: 1n }
})

const parsedPosition = decodePosition(position.returns)
Expand Down
6 changes: 3 additions & 3 deletions test/swap.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ describe('swap tests', () => {
]
})
const position = await invariant.methods.getPosition({
args: { owner: sender.address, index: 1n }
args: { index: 1n }
})
const parsedPosition = decodePosition(position.returns)
expect(parsedPosition.exist).toBe(true)
Expand Down Expand Up @@ -538,7 +538,7 @@ describe('swap tests', () => {
]
})
const position = await invariant.methods.getPosition({
args: { owner: sender.address, index: 1n }
args: { index: 1n }
})
const parsedPosition = decodePosition(position.returns)
expect(parsedPosition.exist).toBe(true)
Expand Down Expand Up @@ -618,7 +618,7 @@ describe('swap tests', () => {
]
})
const position = await invariant.methods.getPosition({
args: { owner: sender.address, index }
args: { index }
})
const parsedPosition = decodePosition(position.returns)
expect(parsedPosition.exist).toBe(true)
Expand Down

0 comments on commit d28dc37

Please sign in to comment.