Skip to content

Commit

Permalink
Bean Eth Price (#581)
Browse files Browse the repository at this point in the history
  • Loading branch information
Brean0 committed Aug 4, 2023
2 parents 72de183 + 1b1dd54 commit e1c74e9
Show file tree
Hide file tree
Showing 9 changed files with 509 additions and 17 deletions.
14 changes: 7 additions & 7 deletions protocol/abi/Beanstalk.json
Original file line number Diff line number Diff line change
Expand Up @@ -4375,9 +4375,9 @@
},
{
"indexed": false,
"internalType": "int128",
"internalType": "int96",
"name": "stem",
"type": "int128"
"type": "int96"
},
{
"indexed": false,
Expand Down Expand Up @@ -5692,7 +5692,7 @@
"type": "address"
}
],
"name": "getLastStem",
"name": "getLastMowedStem",
"outputs": [
{
"internalType": "int96",
Expand Down Expand Up @@ -6025,9 +6025,9 @@
"name": "seasonToStem",
"outputs": [
{
"internalType": "int128",
"internalType": "int96",
"name": "stem",
"type": "int128"
"type": "int96"
}
],
"stateMutability": "view",
Expand Down Expand Up @@ -6057,9 +6057,9 @@
"name": "stemTipForToken",
"outputs": [
{
"internalType": "int128",
"internalType": "int96",
"name": "_stemTip",
"type": "int128"
"type": "int96"
}
],
"stateMutability": "view",
Expand Down
1 change: 1 addition & 0 deletions protocol/contracts/beanstalk/init/InitDiamond.sol
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ contract InitDiamond {
s.season.withdrawSeasons = 25;
s.season.period = C.getSeasonPeriod();
s.season.timestamp = block.timestamp;
s.season.stemStartSeason = 0;
s.season.start = s.season.period > 0 ?
(block.timestamp / s.season.period) * s.season.period :
block.timestamp;
Expand Down
13 changes: 8 additions & 5 deletions protocol/contracts/ecosystem/price/BeanstalkPrice.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ pragma solidity =0.7.6;
pragma experimental ABIEncoderV2;

import "./CurvePrice.sol";
import {WellPrice, C, SafeMath} from "./WellPrice.sol";

contract BeanstalkPrice is CurvePrice {
contract BeanstalkPrice is CurvePrice, WellPrice {
using SafeMath for uint256;

struct Prices {
uint256 price;
Expand All @@ -14,15 +16,16 @@ contract BeanstalkPrice is CurvePrice {
}

function price() external view returns (Prices memory p) {
p.ps = new P.Pool[](1);
p.ps = new P.Pool[](2);
p.ps[0] = getCurve();
p.ps[1] = getConstantProductWell(C.BEAN_ETH_WELL);


// assumes that liquidity and prices on all pools uses the same precision.
for (uint256 i = 0; i < p.ps.length; i++) {
p.price += p.ps[i].price * p.ps[i].liquidity;
p.price += p.ps[i].price.mul(p.ps[i].liquidity);
p.liquidity += p.ps[i].liquidity;
p.deltaB += p.ps[i].deltaB;
}
p.price /= p.liquidity;
p.price = p.price.div(p.liquidity);
}
}
80 changes: 80 additions & 0 deletions protocol/contracts/ecosystem/price/WellPrice.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
//SPDX-License-Identifier: MIT
pragma solidity =0.7.6;
pragma experimental ABIEncoderV2;

import {P} from "./P.sol";
import {SafeMath} from "@openzeppelin/contracts/math/SafeMath.sol";
import {IWell, IERC20} from "../../interfaces/basin/IWell.sol";
import {IBeanstalkWellFunction} from "../../interfaces/basin/IBeanstalkWellFunction.sol";
import {LibUsdOracle} from "../../libraries/Oracle/LibUsdOracle.sol";
import {LibWellMinting} from "../../libraries/Minting/LibWellMinting.sol";
import {LibWell} from "../../libraries/Well/LibWell.sol";
import {C} from "../../C.sol";

interface IBEANSTALK {
function bdv(address token, uint256 amount) external view returns (uint256);

function poolDeltaB(address pool) external view returns (int256);
}

interface dec{
function decimals() external view returns (uint256);
}

contract WellPrice {

using SafeMath for uint256;

address private constant BEANSTALK = 0xC1E088fC1323b20BCBee9bd1B9fC9546db5624C5;
uint256 private constant WELL_DECIMALS = 1e18;
uint256 private constant PRICE_PRECISION = 1e6;

struct Pool {
address pool;
address[2] tokens;
uint256[2] balances;
uint256 price;
uint256 liquidity;
int256 deltaB;
uint256 lpUsd;
uint256 lpBdv;
}

function getConstantProductWell(address wellAddress) public view returns (P.Pool memory pool) {
IWell well = IWell(wellAddress);
pool.pool = wellAddress;

IERC20[] memory wellTokens = well.tokens();
pool.tokens = [address(wellTokens[0]), address(wellTokens[1])];

{
uint256[] memory wellBalances = well.getReserves();
pool.balances = [wellBalances[0], wellBalances[1]];
}

uint256 beanIndex = LibWell.getBeanIndex(wellTokens);
uint256 tknIndex = beanIndex == 0 ? 1 : 0;

// swap 1 bean of the opposite asset to get the usd price
// price = amtOut/tknOutPrice
pool.price =
well.getSwapOut(wellTokens[beanIndex], wellTokens[tknIndex], 1e6) // 1e18
.mul(PRICE_PRECISION) // 1e6
.div(LibUsdOracle.getUsdPrice(address(wellTokens[tknIndex]))); // 1e18

// liquidity is calculated by beanAmt * beanPrice * 2
pool.liquidity =
pool.balances[beanIndex] // 1e6
.mul(pool.price) // 1e6
.div(PRICE_PRECISION)
.mul(2);

pool.deltaB = IBEANSTALK(BEANSTALK).poolDeltaB(wellAddress);

pool.lpUsd = pool.liquidity.mul(WELL_DECIMALS).div(IERC20(wellAddress).totalSupply());

pool.lpBdv = IBEANSTALK(BEANSTALK).bdv(wellAddress, WELL_DECIMALS);

}

}
18 changes: 17 additions & 1 deletion protocol/scripts/impersonate.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@ const {
ETH_USDC_UNISWAP_V3,
ETH_USDT_UNISWAP_V3,
USDT,
ETH_USD_CHAINLINK_AGGREGATOR
ETH_USD_CHAINLINK_AGGREGATOR,
BEAN_ETH_WELL
} = require('../test/utils/constants');
const { deployWell } = require('../utils/well.js');
const { impersonateSigner, mintEth } = require('../utils');

const { getSigner } = '../utils'
Expand Down Expand Up @@ -95,6 +97,8 @@ async function weth() {
WETH,
JSON.parse(tokenJson).deployedBytecode,
]);
const weth = await ethers.getContractAt("MockToken", WETH);
await weth.setDecimals(18);
}

async function router() {
Expand Down Expand Up @@ -268,6 +272,15 @@ async function ethUsdtUniswap() {
]);
}

async function beanEthWell() {
const well = await deployWell([BEAN, WETH]);
const bytecode = await ethers.provider.getCode(well.address)
await network.provider.send("hardhat_setCode", [
BEAN_ETH_WELL,
bytecode,
]);
}

async function ethUsdChainlinkAggregator() {
let chainlinkAggregatorJson = fs.readFileSync(`./artifacts/contracts/mocks/chainlink/MockChainlinkAggregator.sol/MockChainlinkAggregator.json`);

Expand All @@ -279,6 +292,8 @@ async function ethUsdChainlinkAggregator() {
await ethUsdChainlinkAggregator.setDecimals(6)
}



exports.impersonateRouter = router
exports.impersonateBean = bean
exports.impersonateCurve = curve
Expand All @@ -295,3 +310,4 @@ exports.impersonateEthUsdcUniswap = ethUsdcUniswap
exports.impersonateEthUsdtUniswap = ethUsdtUniswap
exports.impersonateBeanstalk = impersonateBeanstalk
exports.impersonateEthUsdChainlinkAggregator = ethUsdChainlinkAggregator
exports.impersonateBeanEthWell = beanEthWell
3 changes: 0 additions & 3 deletions protocol/test/LegacyClaim.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ const { upgradeWithNewFacets } = require("../scripts/diamond");

describe("Legacy Claim", async function () {
before(async function () {
console.log("startup stuff");

try {
await network.provider.request({
method: "hardhat_reset",
Expand Down Expand Up @@ -47,7 +45,6 @@ describe("Legacy Claim", async function () {


this.diamond = BEANSTALK;
console.log("this.diamond: ", this.diamond);

// this.season = await ethers.getContractAt("MockSeasonFacet", this.diamond);

Expand Down
Loading

0 comments on commit e1c74e9

Please sign in to comment.