{
let _pool;
let _adapter;
let _adapterAddress;
let _maturity;
let _seriesObj;
for (let [adapter, pools] of Object.entries(poolData)) {
for (let [maturity, pool] of Object.entries(pools)) {
if (pool.poolID === selectedPoolID) {
_pool = pool;
_adapterAddress = adapter;
_adapter = adapterData[adapter];
_maturity = maturity;
_seriesObj = seriesData[adapter][maturity];
break;
}
}
}
const [spaceAddress] = await balancerVault.getPool(selectedPoolID);
const space = new ethers.Contract(
spaceAddress,
SPACE_ABI,
provider
);
const adapter = new ethers.Contract(
_adapterAddress,
["function scale() external view returns (uint256)"],
provider
);
let blockNumber = entryBlock;
let targetReserve;
let targetReserveVal;
let ptReserve;
const pti = await space.pti();
const tsInYears = new Bignumber(1)
.div(
new Bignumber((await space.ts()).toString()).div(
new Bignumber(10).pow(18)
)
)
.div(SECONDS_IN_A_YEAR);
const scalePre = new Bignumber(await adapter.scale({ blockTag: blockNumber }).then(t => t.toString())).div("1e18");
const totalSupplyPre = await space.totalSupply({ blockTag:blockNumber });
const { tokens, balances: balancesPre } = await balancerVault.getPoolTokens(selectedPoolID, { blockTag:blockNumber });
if (ethers.utils.getAddress(tokens[0]) === ethers.utils.getAddress(_adapter.targetAddress)) {
targetReserve = balancesPre[0].toString();
targetReserveVal = new Bignumber(targetReserve).times(scalePre);
ptReserve = balancesPre[1].toString();
} else {
targetReserve = balancesPre[1].toString();
targetReserveVal = new Bignumber(targetReserve).times(scalePre);
ptReserve = balancesPre[0].toString();
}
const ptPricePre = await calculatePTPrice(balancesPre, _seriesObj, totalSupplyPre.toString(), tsInYears, pti, space, blockNumber);
const targetBalPre = new Bignumber(targetReserveVal).div(totalSupplyPre.toString()).toString();
const targetValPre = new Bignumber(targetReserveVal).div(totalSupplyPre.toString()).toString();
const ptBalPre = new Bignumber(ptReserve).div(totalSupplyPre.toString()).toString();
const ytBal = ptBalPre;
const valPre = new Bignumber(targetValPre).plus(new Bignumber(ptBalPre).times(ptPricePre).times(scalePre)).plus(new Bignumber(ytBal).times(new Bignumber(1).minus(new Bignumber(ptPricePre).times(scalePre))));
const toBlock = _seriesObj.settled ? _seriesObj.settlementBlock : CURRENT_BLOCK;
const { balances: balancesCurrent } = await balancerVault.getPoolTokens(selectedPoolID, { blockTag:toBlock });
const totalSupplyCurrent = await space.totalSupply({ blockTag:toBlock });
const scaleCurrent = new Bignumber(await adapter.scale({ blockTag:toBlock }).then(t => t.toString())).div("1e18");
if (ethers.utils.getAddress(tokens[0]) === ethers.utils.getAddress(_adapter.targetAddress)) {
targetReserve = balancesCurrent[0].toString();
targetReserveVal = new Bignumber(targetReserve).times(scaleCurrent);
ptReserve = balancesCurrent[1].toString();
} else {
targetReserve = balancesCurrent[1].toString();
targetReserveVal = new Bignumber(targetReserve).times(scaleCurrent);
ptReserve = balancesCurrent[0].toString();
}
const ptPriceCurrent = await calculatePTPrice(balancesCurrent, _seriesObj, totalSupplyCurrent.toString(), tsInYears, pti, space, toBlock);
const targetBalCurrent = new Bignumber(targetReserve).div(totalSupplyCurrent.toString()).toString();
const targetValCurrent = new Bignumber(targetReserveVal).div(totalSupplyCurrent.toString()).toString();
const ptBalCurrent = new Bignumber(ptReserve).div(totalSupplyCurrent.toString()).toString();
const ytValCurrent = new Bignumber(ytBal).times(new Bignumber(1).minus(new Bignumber(ptPriceCurrent).times(scaleCurrent)));
const targetAccrued = scaleCurrent.minus(scalePre).times(ytBal).div(scalePre);
const valCurrent = new Bignumber(targetValCurrent).plus(new Bignumber(ptBalCurrent).times(ptPriceCurrent).times(scaleCurrent)).plus(ytValCurrent).plus(targetAccrued);
const { timestamp: startingBlockTS } = await provider.getBlock(blockNumber);
// Comment this block out to view the raw intermediate values
return `1 LP Share minted at block ${blockNumber} (${dayjs(startingBlockTS * 1000)})
* corresponded to ${new Bignumber(targetBalPre).toFormat(12)} ${_seriesObj.targetSymbol} ${new Bignumber(ptBalPre).toFormat(12)} PTs and ${new Bignumber(ytBal).toFormat(12)} YTs with scale ${new Bignumber(scalePre).toFormat(12)}
* and was worth ${valPre.toFormat(12)} underlying initially
* That position ${_seriesObj.settled ? `was worth ${valCurrent.toFormat(12)} underlying at maturity (${dayjs(_maturity * 1000)})`: `is worth ${valCurrent.toFormat(12)} underlying now`} with scale ${new Bignumber(scaleCurrent).toFormat(12)}
* and corresponds to ${new Bignumber(targetBalCurrent).toFormat(12)} ${_seriesObj.targetSymbol} ${new Bignumber(ptBalCurrent).toFormat(12)} PTs ${new Bignumber(ytBal).toFormat(12)} YTs and ${targetAccrued.toFormat(12)} accrued Target
* Scale diff: ${new Bignumber(scaleCurrent).div(scalePre).toFormat(12)}
* LP Share value diff: ${new Bignumber(valCurrent).div(valPre).toFormat(12)}`
return {
ytValCurrent: ytValCurrent.toString(),
ptPricePre: new Bignumber(ptPricePre).times(scalePre).toString(), ptPriceCurrent: new Bignumber(ptPriceCurrent).times(scaleCurrent).toString(), targetAccrued: targetAccrued.toString(),
targetBalPre: targetBalPre.toString(), ptBalPre, scalePre: scalePre.toString(), targetBalCurrent: targetBalCurrent.toString(), ptBalCurrent, scaleCurrent: scaleCurrent.toString(), ytBal
};
}