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 getNextSqrtPriceYDown #51

Merged
merged 15 commits into from
Apr 13, 2024
10 changes: 5 additions & 5 deletions contracts/math/clamm.ral
Original file line number Diff line number Diff line change
Expand Up @@ -233,13 +233,13 @@ Contract CLAMM(uints: Uints) extends Log(uints){
y: U256,
addY: Bool
) -> U256 {
let numerator = rescale(y, TokenAmountScale, SqrtPriceScale)
let denominator = rescale(liquidity, LiquidityScale, SqrtPriceScale)

let numerator = uints.bigRescale(y, TokenAmountScale, SqrtPriceScale)
let denominator = uints.bigRescale(liquidity, LiquidityScale, SqrtPriceScale)
if (addY) {
return startingSqrtPrice + div(numerator, denominator)
return startingSqrtPrice + uints.unwrapU256(uints.toU256(uints.unwrapU512(uints.bigDiv512(numerator, denominator, one(SqrtPriceScale)))))
} else {
return startingSqrtPrice - divUp(numerator, denominator)
return startingSqrtPrice - uints.unwrapU256(uints.toU256(uints.unwrapU512(uints.bigDivUp512(numerator, denominator, one(SqrtPriceScale)))))
}

}
Expand Down
139 changes: 61 additions & 78 deletions contracts/math/uints.ral
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ Contract Uints () {
}
}

pub fn isZero(a: U512) -> Bool {
return a.higher == 0 && a.lower == 0
}

pub fn toU256(value: U512) -> ResultU256 {
if(value.higher > 0) {
return ResultU256 { value: MaxU256, error: ArithmeticError.CastOverflow }
Expand Down Expand Up @@ -195,6 +199,60 @@ Contract Uints () {
return bigDivWrapper(result, b, 1)
}

pub fn bigDiv512(dividend: U512, divisor: U512, divisorDenominator: U256) -> ResultU512 {
let mut q = U512 { higher: 0, lower: 0 }
let mut r = U512 { higher: 0, lower: 0 }

if(isZero(divisor)) {
return ResultU512 { value: U512 { higher: MaxU256, lower: MaxU256 }, error: ArithmeticError.DivNotPositiveDivisor }
}

if(divisorDenominator == 0) {
return ResultU512 { value: U512 { higher: MaxU256, lower: MaxU256 }, error: ArithmeticError.DivNotPositiveDenominator }
}

let extDividend = unwrapU512(bigMul(dividend, divisorDenominator))
let mut uHigh = extDividend.higher
let mut uLow = extDividend.lower

let v = divisor

let mut j = 512
while (j > 0) {
j = j - 1
r = bigShl(r, 1)

if (((uHigh >> 255) & 1) != 0) {
r = bitOrLower(r, 1)
}

uHigh = uHigh << 1

if ((uLow >> 255) != 0) {
uHigh = uHigh | 1
}
uLow = uLow << 1

if (isGreaterEqual(r,v)) {
r = unwrapU512(bigSub512(r, v))
if (j >= 256) {
q.higher = q.higher | (1 << (j - 256))
} else {
q.lower = q.lower | (1 << j)
}
}
}

return ResultU512 { value: q, error: 0 }
}

pub fn bigDivUp512(dividend: U512, divisor: U512, divisorDenominator: U256) -> ResultU512 {
let mut result = unwrapU512(bigMul(dividend, divisorDenominator))
result = unwrapU512(bigAdd512(result, divisor))
result.lower = result.lower - 1
return bigDiv512(result, divisor, 1)
}

pub fn bigMul256(a: U256, b: U256) -> U512 {
let aLower = low128(a)
let aHigher = high128(a)
Expand Down Expand Up @@ -260,9 +318,8 @@ Contract Uints () {
pub fn overflowingAdd(a: U256, b: U256) -> (U256, U256) {
if (MaxU256 - a >= b) {
return a + b, 0
}

if (a > b) {
}
if (a > b){
return a - (MaxU256 - b) - 1, 1
} else {
return b - (MaxU256 - a) - 1, 1
Expand Down Expand Up @@ -379,78 +436,4 @@ Contract Uints () {
return bigDiv(toU512(fromValue), 10 ** denominatorScale, 1).value
}
}

pub fn isZero(a: U512) -> Bool {
return a.higher == 0 && a.lower == 0
}

pub fn bigDiv512(dividend: U512, divisor: U512, divisorDenominator: U256) -> ResultU512 {
let mut q = U512 { higher: 0, lower: 0 }
let mut r = U512 { higher: 0, lower: 0 }

if(isZero(divisor)) {
return ResultU512 { value: U512 { higher: MaxU256, lower: MaxU256 }, error: ArithmeticError.DivNotPositiveDivisor }
}

if(divisorDenominator == 0) {
return ResultU512 { value: U512 { higher: MaxU256, lower: MaxU256 }, error: ArithmeticError.DivNotPositiveDenominator }
}

if (dividend.higher == 0) {
let mulResult = bigMul256(dividend.lower, divisorDenominator)

if (mulResult.higher == 0) {
return ResultU512 { value: U512 { higher: 0, lower: mulResult.lower / divisor.lower }, error: 0 }
}
let divResult = bigDiv512(mulResult, divisor, 1)
return divResult
}

let mut uHigh = dividend.higher * divisorDenominator
let mut uLow = dividend.lower * divisorDenominator
let v = divisor

for (let mut j = 511; j > 0; j = j - 1) {
r.lower = r.lower << 1 | (r.higher >> 255)
r.higher = r.higher << 1

if (((uHigh >> 255) & 1) != 0) {
r.lower = r.lower | 1
}

uHigh = uHigh << 1

if ((uLow >> 255) != 0) {
uHigh = uHigh | 1
}
uLow = uLow << 1

if (r.higher > v.higher || (r.higher == v.higher && r.lower >= v.lower)) {
let mut borrow = 1

if (r.lower >= v.lower) {
borrow = 0
}

r.lower = r.lower - (v.lower + borrow)
r.higher = r.higher - (v.higher + borrow)

if (j >= 256) {
q.higher = q.higher | (1 << (j - 256))
} else {
q.lower = q.lower | (1 << j)
}
}
}

return ResultU512 { value: q, error: 0 }
}

pub fn bigDivUp512(dividend: U512, divisor: U512, divisorDenominator: U256) -> ResultU512 {
let mut result = unwrapU512(bigMul(dividend, divisorDenominator))
result = unwrapU512(bigAdd512(result, divisor))
result.lower = result.lower - 1
return bigDiv512(result, divisor, 1)
}
}

}
Loading