ghost-dao-contracts/src/StandardBondingCalculator.sol
Uncle Fatso 9dfd10aff7
draft fixes for native-only support; tests broken
Signed-off-by: Uncle Fatso <uncle.fatso@ghostchain.io>
2025-10-06 15:34:25 +03:00

78 lines
2.7 KiB
Solidity

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "./libraries/FixedPoint.sol";
import "@openzeppelin-contracts/utils/Address.sol";
import "@openzeppelin-contracts/token/ERC20/IERC20.sol";
import "@openzeppelin-contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin-contracts/token/ERC20/extensions/IERC20Metadata.sol";
import "@uniswap-v2-core/interfaces/IUniswapV2ERC20.sol";
import "@uniswap-v2-core/interfaces/IUniswapV2Pair.sol";
import "./interfaces/IBondingCalculator.sol";
contract GhostBondingCalculator is IBondingCalculator {
using FixedPoint for *;
uint256 public override immutable fraction;
address internal immutable ftso;
constructor(address _ftso, uint256 _numerator, uint256 _denominator) {
ftso = _ftso;
fraction = FixedPoint.fraction(_numerator, _denominator).decode112with18();
}
function getKValue(address pair, bool isCoefficient) public view returns (uint256 k) {
uint256 token0 = IERC20Metadata(IUniswapV2Pair(pair).token0()).decimals();
uint256 token1 = IERC20Metadata(IUniswapV2Pair(pair).token1()).decimals();
uint256 decimals = token0 + token1 - IERC20Metadata(pair).decimals();
(uint256 reserve0, uint256 reserve1, ) = IUniswapV2Pair(pair).getReserves();
k = reserve0 * reserve1 / (10**decimals);
if (isCoefficient) {
k = k * 1e18 / fraction;
}
}
function getTotalValue(address pair, bool isCoefficient) public view returns (uint256) {
return _sqrt(getKValue(pair, isCoefficient)) * 2;
}
function valuation(address pair, uint256 amount) external view override returns (uint256 value) {
uint256 totalValue = getTotalValue(pair, true);
uint256 totalSupply = IUniswapV2Pair(pair).totalSupply();
value = totalValue * FixedPoint.fraction(amount, totalSupply).decode112with18() / 1e18;
}
function markdown(address pair) external view override returns (uint256 reserve) {
(uint256 reserve0, uint256 reserve1, ) = IUniswapV2Pair(pair).getReserves();
if (IUniswapV2Pair(pair).token0() == ftso) {
reserve = reserve1;
} else {
if (IUniswapV2Pair(pair).token1() != ftso) revert InvalidPair();
reserve = reserve0;
}
reserve = reserve * (2 * 1e9) / getTotalValue(pair, false);
reserve = reserve * _sqrt(fraction) / 1e9;
}
function _sqrt(uint256 a) private pure returns (uint256 c) {
if (a > 3) {
c = a;
uint256 b = (a / 2) + 1;
while (b < c) {
c = b;
b = ((a / b) + b) / 2;
}
} else if (a != 0) {
c = 1;
}
}
}