AMM 初始流动性生成器(GCASH / PETRO)
AMM 初始流动性生成器(GCASH / PETRO)
数据可视化(按 tokens_bought_cumulative 作为横轴):
function solveStartForTargetAvgWithSchedule(p0, p1, dx, steps, schedule, interval, targetAvg, xbEarly) {
const { x0, y0, k } = computeInitialReservesByGCASH(p0, p1, dx, steps);
function avgForStart(s) {
let x = x0;
let y = y0;
let tokens = 0;
let spent = 0;
let schedIdx = 0;
if (xbEarly > 0) {
const xE = x + xbEarly;
const yE = k / xE;
tokens += y - yE;
spent += xbEarly;
x = xE;
y = yE;
}
for (let t = 1; t <= steps; t++) {
const x1 = x + dx;
const y1 = k / x1;
if (t >= s && ((t - s) % Math.max(1, interval) === 0) && schedIdx < schedule.length) {
const amount = Number(schedule[schedIdx] || 0);
const x2 = x1 + amount;
const y2 = k / x2;
tokens += y1 - y2;
spent += amount;
x = x2;
y = y2;
schedIdx += 1;
} else {
x = x1;
y = y1;
}
}
return spent > 0 ? spent / tokens : 0;
}
let events = schedule.length;
let lo = 1;
let hi = Math.max(1, steps - Math.max(0, events - 1) * Math.max(1, interval));
const aLo = avgForStart(lo);
const aHi = avgForStart(hi);
if (targetAvg <= aLo) return lo;
if (targetAvg >= aHi) return hi;
for (let i = 0; i < 50; i++) {
const mid = Math.floor((lo + hi) / 2);
const am = avgForStart(mid);
if (am < targetAvg) lo = mid + 1; else hi = mid - 1;
}
return Math.floor((lo + hi) / 2);
}