Skip to content

Commit

Permalink
curve Y for twa price
Browse files Browse the repository at this point in the history
  • Loading branch information
soilking committed Apr 17, 2024
1 parent 2e7884d commit 20d7d9c
Showing 1 changed file with 50 additions and 48 deletions.
98 changes: 50 additions & 48 deletions projects/subgraph-bean/src/utils/price/CurvePrice.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Address, BigDecimal, BigInt } from "@graphprotocol/graph-ts";
import { Address, BigDecimal, BigInt, log } from "@graphprotocol/graph-ts";
import { Bean3CRV } from "../../../generated/Bean3CRV-V1/Bean3CRV";
import { BI_10, ONE_BI, toDecimal, ZERO_BD, ZERO_BI } from "../../../../subgraph-core/utils/Decimals";
import { BD_10, BI_10, ONE_BI, toDecimal, ZERO_BD, ZERO_BI } from "../../../../subgraph-core/utils/Decimals";
import { BEAN_3CRV_V1, BEAN_LUSD_V1, CALCULATIONS_CURVE, CRV3_POOL_V1, LUSD, LUSD_3POOL } from "../../../../subgraph-core/utils/Constants";
import { CalculationsCurve } from "../../../generated/Bean3CRV-V1/CalculationsCurve";
import { ERC20 } from "../../../generated/Bean3CRV-V1/ERC20";
Expand Down Expand Up @@ -79,18 +79,27 @@ export function curveTwaDeltaBAndPrice(twaBalances: BigInt[], beanPool: Address,
const xp = [twaBalances[0].times(BI_10.pow(12)), twaBalances[1].times(other_A).div(BI_10.pow(18))];

const D = getD(xp, bean_A);
const y = getY(xp[0].plus(BI_10.pow(12)), xp, bean_A, D);

log.debug("curve D {}", [D.toString()]);
log.debug("curve y {}", [y.toString()]);
log.debug("curve deltaB calculated {}", [D.div(BigInt.fromU32(2)).div(BI_10.pow(12)).minus(twaBalances[0]).toString()]);
log.debug("curve deltaB simple {}", [curveDeltaB(beanPool, twaBalances[0]).toString()]);
log.debug("curve xp[0] {}", [xp[0].toString()]);
log.debug("curve xp[1] {}", [xp[1].toString()]);

return {
deltaB: D.div(BigInt.fromU32(2)).div(BI_10.pow(12)).minus(twaBalances[0]),
price: ZERO_BD // TODO
price: BigDecimal.fromString(xp[1].minus(y).minus(ONE_BI).toString()).div(BigDecimal.fromString("1000000000000000000"))
};
}

// These are the same for both the 3crv and lusd pools
const A_PRECISION = BigInt.fromU32(100);
const N_COINS = BigInt.fromU32(2);

// Generated from functions in LibCurve.sol
function getD(xp: BigInt[], a: BigInt): BigInt {
const A_PRECISION = BigInt.fromU32(100);
const N_COINS = BigInt.fromU32(2);

let S: BigInt = BigInt.fromString("0");
let Dprev: BigInt;
let D: BigInt = BigInt.fromString("0");
Expand Down Expand Up @@ -122,45 +131,38 @@ function getD(xp: BigInt[], a: BigInt): BigInt {
throw new Error("Price: Convergence false");
}

// // Based on get_y from dune query here https://dune.com/queries/3561823/5993924
// export function get_y(i: i32, j: i32, x: f64, xp: Array<f64>, amp: f64, n_coins: i32, a_precision: i32): f64 {
// let su: f64 = 0;
// let _x: f64 = 0;
// let y_prev: f64 = 0;
// let c: f64;
// let ann: f64;
// let d: f64;
// let b: f64;
// let y: f64;

// d = get_D(xp, amp, n_coins, a_precision);
// c = d;
// ann = amp * n_coins;

// for (let _i = 0; _i < n_coins; _i++) {
// if (_i == i) {
// _x = x;
// su += _x;
// c = c * d / (_x * n_coins);
// } else if (_i != j) {
// _x = xp[i];
// su += _x;
// c = c * d / (_x * n_coins);
// }
// }

// c = c * d * a_precision / (ann * n_coins);
// b = su + d * a_precision / ann;
// y = d;

// for (let _i = 0; _i < 255; _i++) {
// y_prev = y;
// y = (y * y + c) / (2 * y + b - d);

// if ((y > y_prev && y - y_prev <= 1) || (y_prev > y && y_prev - y <= 1)) {
// return y;
// }
// }

// return -1;
// }
const i = 0;
const j = 1;

function getY(x: BigInt, xp: BigInt[], a: BigInt, D: BigInt): BigInt {
let S_: BigInt = BigInt.fromString("0");
let _x: BigInt = BigInt.fromString("0");
let y_prev: BigInt;
let y: BigInt = D;
let c: BigInt = D;
let Ann: BigInt = a.times(N_COINS);

// Calculate c considering each element in xp
for (let _i = 0; _i < N_COINS.toU32(); ++_i) {
if (_i == i) _x = x;
else if (_i != j) _x = xp[_i];
else continue;
S_ = S_.plus(_x);
c = c.times(D).div(_x.times(N_COINS));
}

c = c.times(D).times(A_PRECISION).div(Ann.times(N_COINS));
let b: BigInt = S_.plus(D.times(A_PRECISION).div(Ann));

for (let _i = 0; _i < 255; ++_i) {
y_prev = y;
y = y
.times(y)
.plus(c)
.div(y.times(BigInt.fromString("2")).plus(b).minus(D));
if (y == y_prev || y.minus(y_prev) == ONE_BI || y_prev.minus(y) == ONE_BI) {
return y;
}
}
throw new Error("Price: Convergence false");
}

0 comments on commit 20d7d9c

Please sign in to comment.