Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bip38 UI Changes #656

Closed
wants to merge 27 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
6ed6287
ui: rename/replace unripe bean3crv with unripe beanweth
0xalecks Sep 24, 2023
c1f3713
ui: fix annoying bugs
0xalecks Sep 24, 2023
d71e89e
cli: add support for beanweth lp
0xalecks Sep 24, 2023
ba4df9f
cli: add mine() command
0xalecks Sep 24, 2023
41c8500
sdk/ui: use well for bean swaps
0xalecks Sep 25, 2023
e252e34
sdk: update swap and deposit workflows
0xalecks Sep 25, 2023
6c15885
ui: migrate Barn page to bip38
0xalecks Sep 26, 2023
8e301d3
cli: fix mine command
0xalecks Sep 26, 2023
b4ce91c
ui: fix minLPcalc for Fert
0xalecks Sep 28, 2023
57fe4be
ui: update silo balances and chop
0xalecks Sep 29, 2023
e33d0cc
ui: fix chop quote
0xalecks Sep 29, 2023
7b4d9da
ui: update silo balance fiat calculations
0xalecks Oct 2, 2023
e72c3d3
ui: set urBEANETH symbol name
0xalecks Oct 2, 2023
8918d81
fix import
0xalecks Oct 3, 2023
92542f3
fix race condition
0xalecks Oct 3, 2023
633e646
undo token rename
0xalecks Oct 3, 2023
064db00
rename tokens to beaneth
0xalecks Oct 3, 2023
76ef098
ui: fix tvd for urbeaneth
0xalecks Oct 4, 2023
31cf0bb
ui: barn copy update
0xalecks Oct 4, 2023
2202fda
ui: fix token comparison bug in dev
0xalecks Oct 4, 2023
5d6154f
ui: fix barn slippage
0xalecks Oct 5, 2023
c112f6e
ui: fix convert warning
0xalecks Oct 5, 2023
9ba312a
ui: update silo images
0xalecks Oct 6, 2023
e1a5906
ui: add slippage to barn purchase
0xalecks Oct 9, 2023
95b4178
fix balances page
0xalecks Oct 11, 2023
0d05d0a
ui: fix build
0xalecks Oct 11, 2023
d49e52e
update graphql schema
0xalecks Oct 11, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion projects/cli/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { setbalance } from "./commands/setbalance.js";
import { sunrise } from "./commands/sunrise.js";
import { setPrice } from "./commands/setprice.js";
import { help } from "./commands/help.js";
import { mineBlocks } from "./commands/mine.js";

main().catch((e) => {
console.log("FAILED:");
Expand All @@ -22,7 +23,7 @@ async function main() {
{ name: "amount", alias: "m", defaultValue: "50000" },
{ name: "rpcUrl", alias: "r", defaultValue: "http://127.0.0.1:8545" },
{ name: "no-imp", type: Boolean },
{ name: "force", alias: "f", type: Boolean}
{ name: "force", alias: "f", type: Boolean }
];
const args = commandLineArgs(commands, { partial: true });

Expand All @@ -41,6 +42,9 @@ async function main() {
case "setprice":
await setPrice(sdk, chain, { params: args._unknown });
break;
case "mine":
await mineBlocks(sdk, args.amount);
break;
case "help":
default:
await help();
Expand Down
17 changes: 14 additions & 3 deletions projects/cli/src/commands/balance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,20 @@ export const balance = async (sdk, { account, symbol }) => {
res.push(await getBal(sdk, symbol, account));
} else {
const bals = await Promise.all(
["ETH", "WETH", "BEAN", "USDT", "USDC", "DAI", "CRV3", "UNRIPE_BEAN", "UNRIPE_BEAN_CRV3", "BEAN_CRV3_LP", "ROOT"].map((s) =>
getBal(sdk, s, account)
)
[
"ETH",
"WETH",
"BEAN",
"USDT",
"USDC",
"DAI",
"CRV3",
"UNRIPE_BEAN",
"UNRIPE_BEAN_WETH",
"BEAN_CRV3_LP",
"BEAN_ETH_WELL_LP",
"ROOT"
].map((s) => getBal(sdk, s, account))
);
res.push(...bals);
}
Expand Down
18 changes: 18 additions & 0 deletions projects/cli/src/commands/mine.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { BeanstalkSDK } from "@beanstalk/sdk";
import chalk from "chalk";
import { table } from "table";

export const mineBlocks = async (sdk: BeanstalkSDK, amount) => {
const numBlocks = amount === "50000" ? 1 : amount;

async function mineBlocks(blockNumber) {
while (blockNumber > 0) {
blockNumber--;
await sdk.provider.send("evm_mine", []);
}
}

await mineBlocks(numBlocks);

console.log(`${chalk.bold.whiteBright("Mined ")} ${chalk.greenBright(numBlocks)} block(s)`);
};
5 changes: 3 additions & 2 deletions projects/cli/src/commands/setbalance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,17 @@ export const setbalance = async (sdk, chain, { account, symbol, amount }) => {
if (!symbol) {
await chain.setAllBalances(account, amount);
} else {
const symbols = ["ETH", "WETH", "BEAN", "USDT", "USDC", "DAI", "3CRV", "BEAN3CRV", "urBEAN", "urBEAN3CRV", "ROOT"];
const symbols = ["ETH", "WETH", "BEAN", "USDT", "USDC", "DAI", "3CRV", "BEAN3CRV", "BEANWETH", "urBEAN", "urBEANWETH", "ROOT"];
if (!symbols.includes(symbol)) {
console.log(`${chalk.bold.red("Error")} - ${chalk.bold.white(symbol)} is not a valid token. Valid options are: `);
console.log(symbols.map((s) => chalk.green(s)).join(", "));
process.exit(-1);
}
let t = sdk.tokens[symbol] as Token;
if (symbol === "urBEAN") t = sdk.tokens.UNRIPE_BEAN;
if (symbol === "urBEAN3CRV") t = sdk.tokens.UNRIPE_BEAN_CRV3;
if (symbol === "urBEANWETH") t = sdk.tokens.UNRIPE_BEAN_WETH;
if (symbol === "BEAN3CRV") t = sdk.tokens.BEAN_CRV3_LP;
if (symbol === "BEANWETH") t = sdk.tokens.BEAN_ETH_WELL_LP;
if (typeof chain[`set${symbol}Balance`] !== "function")
throw new Error(`${symbol} is not a valid token or the method ${chalk.bold.whiteBright("")}`);

Expand Down
4 changes: 2 additions & 2 deletions projects/sdk/src/classes/Workflow.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ethers } from "ethers";
import { CallOverrides, ethers } from "ethers";
import { Token } from "src/classes/Token";
import { BeanstalkSDK } from "src/lib/BeanstalkSDK";
import { TokenValue } from "src/TokenValue";
Expand Down Expand Up @@ -593,7 +593,7 @@ export abstract class Workflow<
* @param slippage A human readable percent value. Ex: 0.1 would mean 0.1% slippage
* @returns Promise of a Transaction
*/
abstract execute(amountIn: ethers.BigNumber | TokenValue, data: RunData): Promise<ethers.ContractTransaction>;
abstract execute(amountIn: ethers.BigNumber | TokenValue, data: RunData, overrides?: CallOverrides): Promise<ethers.ContractTransaction>;

/**
* CallStatic version of the execute method. Allows testing the execution of the workflow.
Expand Down
4 changes: 2 additions & 2 deletions projects/sdk/src/constants/addresses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ export const addresses = {
UNRIPE_BEAN:
// "Unripe Bean": Unripe vesting asset for the Bean token, Localhost
Address.make("0x1BEA0050E63e05FBb5D8BA2f10cf5800B6224449"),
UNRIPE_BEAN_CRV3:
// "Unripe BEAN:CRV3 LP": Unripe vesting asset for the BEAN:CRV3 LP token, Localhost
UNRIPE_BEAN_WETH:
// "Unripe BEAN:WETH LP": Unripe vesting asset for the BEAN:WETH LP token, Localhost
Address.make("0x1BEA3CcD22F4EBd3d37d731BA31Eeca95713716D"),

// ----------------------------------------
Expand Down
22 changes: 18 additions & 4 deletions projects/sdk/src/lib/farm/LibraryPresets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export class LibraryPresets {

public readonly weth2bean: ActionBuilder;
public readonly bean2weth: ActionBuilder;
public readonly weth2bean3crv: ActionBuilder;
public readonly wellWethBean;
public readonly wellAddLiquidity;

Expand All @@ -37,6 +38,7 @@ export class LibraryPresets {
public readonly dai2weth: ActionBuilder;
public readonly usdc2weth: ActionBuilder;

public readonly usdt23crv: ActionBuilder;
public readonly usdc2beaneth;
public readonly usdt2beaneth;
public readonly dai2beaneth;
Expand Down Expand Up @@ -176,6 +178,20 @@ export class LibraryPresets {
this.usdt2weth(FarmFromMode.INTERNAL, toMode) as StepGenerator
];

///////// WETH -> 3CRV ///////////
this.weth2bean3crv = (fromMode?: FarmFromMode, toMode?: FarmToMode) => [
this.weth2usdt(fromMode, FarmToMode.INTERNAL) as StepGenerator,
this.usdt23crv(fromMode, FarmToMode.INTERNAL) as StepGenerator
];

//////// USDT -> 3CRV ////////
this.usdt23crv = (fromMode?: FarmFromMode, toMode?: FarmToMode) => {
const pool = sdk.contracts.curve.pools.pool3.address;
const registry = sdk.contracts.curve.registries.poolRegistry.address;
// [0 ,0 , 1] is for USDT; [DAI, USDC, USDT]
return new sdk.farm.actions.AddLiquidity(pool, registry, [0, 0, 1], fromMode, toMode);
};

///////// DAI -> USDT ///////////
this.dai2usdt = (fromMode?: FarmFromMode, toMode?: FarmToMode) =>
new Exchange(
Expand All @@ -197,7 +213,7 @@ export class LibraryPresets {
fromMode,
toMode
);

///////// DAI -> WETH ///////////
this.dai2weth = (fromMode?: FarmFromMode, toMode?: FarmToMode) => [
this.dai2usdt(fromMode, FarmToMode.INTERNAL) as StepGenerator,
Expand All @@ -210,7 +226,6 @@ export class LibraryPresets {
this.usdt2weth(FarmFromMode.INTERNAL, toMode) as StepGenerator
];


///////// [ USDC, USDT, DAI ] -> BEANETH ///////////
this.usdc2beaneth = (well: BasinWell, account: string, fromMode?: FarmFromMode, toMode?: FarmToMode) => [
this.usdc2weth(fromMode, FarmToMode.INTERNAL) as StepGenerator,
Expand Down Expand Up @@ -275,7 +290,6 @@ export class LibraryPresets {
};

this.wellAddLiquidity = (well: BasinWell, tokenIn: ERC20Token, account: string, from?: FarmFromMode, to?: FarmToMode) => {

const result = [];
const advancedPipe = sdk.farm.createAdvancedPipe("pipelineDeposit");

Expand Down Expand Up @@ -304,13 +318,13 @@ export class LibraryPresets {
}
const transferToBeanstalk = new sdk.farm.actions.TransferToken(well.address, account, FarmFromMode.EXTERNAL, FarmToMode.INTERNAL, transferClipboard);


result.push(transfer);
advancedPipe.add(addLiquidity, { tag: "amountToDeposit" });
if (transferBack) {
advancedPipe.add(approveBack);
advancedPipe.add(transferToBeanstalk);
}

result.push(advancedPipe);

return result;
Expand Down
3 changes: 3 additions & 0 deletions projects/sdk/src/lib/farm/actions/WellShift.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import { Token } from "src/classes/Token";
import { RunContext, RunMode, Step, StepClass, Workflow } from "src/classes/Workflow";
import { AdvancedPipePreparedResult } from "src/lib/depot/pipe";

/**
* Swap tokens in a Well by using the shift() method
*/
export class WellShift extends StepClass<AdvancedPipePreparedResult> {
public name: string = "shift";

Expand Down
22 changes: 11 additions & 11 deletions projects/sdk/src/lib/farm/actions/WellSync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import { Token } from "src/classes/Token";
import { RunContext, RunMode, Step, StepClass } from "src/classes/Workflow";
import { AdvancedPipePreparedResult } from "src/lib/depot/pipe";

/**
* Add liqudity to a well using the Sync method, which transfers tokens directly to the well first
* which does not require an approval
*/
export class WellSync extends StepClass<AdvancedPipePreparedResult> {
public name: string = "wellSync";

Expand All @@ -31,7 +35,7 @@ export class WellSync extends StepClass<AdvancedPipePreparedResult> {
throw new Error("Reverse direction is not supported by wellSync");
}

let amounts: TokenValue[] = []
let amounts: TokenValue[] = [];
for (let i = 0; i < this._well.tokens.length; i++) {
if (i === tokenIndex) {
amounts[i] = this.tokenIn.fromBlockchain(_amountInStep);
Expand All @@ -47,23 +51,19 @@ export class WellSync extends StepClass<AdvancedPipePreparedResult> {
amountOut: quote.toBigNumber(),
value: ethers.BigNumber.from(0),
prepare: () => {

const minLP = quote.subSlippage(context.data.slippage || 0.1);

WellSync.sdk.debug(`>[${this.name}.prepare()]`, {
well: well.name,
recipient: this.recipient,
quoteAmountLessSlippage: minLP,
method: "sync",
context
well: well.name,
recipient: this.recipient,
quoteAmountLessSlippage: minLP,
method: "sync",
context
});

return {
target: well.address,
callData: well.contract.interface.encodeFunctionData("sync", [
this.recipient,
minLP.toBigNumber().toString(),
])
callData: well.contract.interface.encodeFunctionData("sync", [this.recipient, minLP.toBigNumber().toString()])
};
},
decode: (data: string) => well.contract.interface.decodeFunctionData("sync", data),
Expand Down
2 changes: 1 addition & 1 deletion projects/sdk/src/lib/silo/Convert.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ describe("Silo Convert", function () {
const BEAN = sdk.tokens.BEAN;
const BEANLP = sdk.tokens.BEAN_CRV3_LP;
const urBEAN = sdk.tokens.UNRIPE_BEAN;
const urBEANLP = sdk.tokens.UNRIPE_BEAN_CRV3;
const urBEANLP = sdk.tokens.UNRIPE_BEAN_WETH;
const whitelistedTokens = [BEAN, BEANLP, urBEAN, urBEANLP];

beforeAll(async () => {
Expand Down
16 changes: 8 additions & 8 deletions projects/sdk/src/lib/silo/Convert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,24 +21,24 @@ export class Convert {
BeanCrv3: Token;
BeanEth: Token;
urBean: Token;
urBeanCrv3: Token;
urBeanWeth: Token;
paths: Map<Token, Token>;

constructor(sdk: BeanstalkSDK) {
Convert.sdk = sdk;
this.Bean = Convert.sdk.tokens.BEAN;
this.BeanCrv3 = Convert.sdk.tokens.BEAN_CRV3_LP;
this.BeanCrv3 = Convert.sdk.tokens.BEAN_CRV3_LP;
this.BeanEth = Convert.sdk.tokens.BEAN_ETH_WELL_LP;
this.urBean = Convert.sdk.tokens.UNRIPE_BEAN;
this.urBeanCrv3 = Convert.sdk.tokens.UNRIPE_BEAN_CRV3;
this.urBeanWeth = Convert.sdk.tokens.UNRIPE_BEAN_WETH;

this.paths = new Map<Token, Token>();
this.paths.set(this.Bean, this.BeanCrv3);
this.paths.set(this.BeanCrv3, this.Bean);
this.paths.set(this.Bean, this.BeanEth);
this.paths.set(this.BeanEth, this.Bean);
this.paths.set(this.urBean, this.urBeanCrv3);
this.paths.set(this.urBeanCrv3, this.urBean);
this.paths.set(this.urBean, this.urBeanWeth);
this.paths.set(this.urBeanWeth, this.urBean);
}

async convert(fromToken: Token, toToken: Token, fromAmount: TokenValue, slippage: number = 0.1): Promise<ContractTransaction> {
Expand Down Expand Up @@ -117,12 +117,12 @@ export class Convert {
calculateEncoding(fromToken: Token, toToken: Token, amountIn: TokenValue, minAmountOut: TokenValue) {
let encoding;

if (fromToken.address === this.urBean.address && toToken.address === this.urBeanCrv3.address) {
if (fromToken.address === this.urBean.address && toToken.address === this.urBeanWeth.address) {
encoding = ConvertEncoder.unripeBeansToLP(
amountIn.toBlockchain(), // amountBeans
minAmountOut.toBlockchain() // minLP
);
} else if (fromToken.address === this.urBeanCrv3.address && toToken.address === this.urBean.address) {
} else if (fromToken.address === this.urBeanWeth.address && toToken.address === this.urBean.address) {
encoding = ConvertEncoder.unripeLPToBeans(
amountIn.toBlockchain(), // amountLP
minAmountOut.toBlockchain() // minBeans
Expand Down Expand Up @@ -178,7 +178,7 @@ export class Convert {
const deltaB = await Convert.sdk.bean.getDeltaB();

if (deltaB.gte(TokenValue.ZERO)) {
if (fromToken.equals(this.BeanCrv3) || fromToken.equals(this.urBeanCrv3) || fromToken.equals(this.BeanEth)) {
if (fromToken.equals(this.BeanCrv3) || fromToken.equals(this.urBeanWeth) || fromToken.equals(this.BeanEth)) {
throw new Error("Cannot convert this token when deltaB is >= 0");
}
} else if (deltaB.lt(TokenValue.ZERO)) {
Expand Down
47 changes: 47 additions & 0 deletions projects/sdk/src/lib/silo/Deposit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,41 @@ const { sdk, account, utils } = getTestUtils();

jest.setTimeout(30000);

const happyPaths: Record<string, string> = {
"ETH:BEAN": "ETH -> WETH -> BEAN -> BEAN:SILO",
"ETH:BEAN3CRV": "ETH -> WETH -> 3CRV -> BEAN3CRV -> BEAN3CRV:SILO",
"ETH:BEANWETH": "ETH -> WETH -> BEANWETH -> BEANWETH:SILO",

"WETH:BEAN": "WETH -> BEAN -> BEAN:SILO",
"WETH:BEAN3CRV": "WETH -> 3CRV -> BEAN3CRV -> BEAN3CRV:SILO",
"WETH:BEANWETH": "WETH -> BEANWETH -> BEANWETH:SILO",

"BEAN:BEAN": "BEAN -> BEAN:SILO",
"BEAN:BEAN3CRV": "BEAN -> BEAN3CRV -> BEAN3CRV:SILO",
"BEAN:BEANWETH": "BEAN -> BEANWETH -> BEANWETH:SILO",

"3CRV:BEAN": "3CRV -> USDC -> WETH -> BEAN -> BEAN:SILO", // TODO: Fix this path
"3CRV:BEAN3CRV": "3CRV -> BEAN3CRV -> BEAN3CRV:SILO",
"3CRV:BEANWETH": "3CRV -> USDC -> BEANWETH -> BEANWETH:SILO",

"DAI:BEAN": "DAI -> WETH -> BEAN -> BEAN:SILO",
"DAI:BEAN3CRV": "DAI -> 3CRV -> BEAN3CRV -> BEAN3CRV:SILO",
"DAI:BEANWETH": "DAI -> BEANWETH -> BEANWETH:SILO",

"USDC:BEAN": "USDC -> WETH -> BEAN -> BEAN:SILO",
"USDC:BEAN3CRV": "USDC -> 3CRV -> BEAN3CRV -> BEAN3CRV:SILO",
"USDC:BEANWETH": "USDC -> BEANWETH -> BEANWETH:SILO",

"USDT:BEAN": "USDT -> WETH -> BEAN -> BEAN:SILO",
"USDT:BEAN3CRV": "USDT -> 3CRV -> BEAN3CRV -> BEAN3CRV:SILO",
"USDT:BEANWETH": "USDT -> BEANWETH -> BEANWETH:SILO"
};

describe("Silo Deposit", function () {
const builder = new DepositBuilder(sdk);

const whiteListedTokens = Array.from(sdk.tokens.siloWhitelist);
const whiteListedTokensRipe = whiteListedTokens.filter((t) => !t.isUnripe);
const bean3CrvDepositable = [
sdk.tokens.ETH,
sdk.tokens.WETH,
Expand All @@ -29,6 +60,22 @@ describe("Silo Deposit", function () {
await utils.setAllBalances(account, "20000");
});

describe("Routes correctly", () => {
describe.each(bean3CrvDepositable)("Whitelist Token", (token: Token) => {
it.each(whiteListedTokensRipe.map((t) => [t.symbol, t]))(`Deposit ${token.symbol} into %s`, async (symbol: string, silo: Token) => {
const op = builder.buildDeposit(silo, account);
op.setInputToken(token);

// need to run an estimate first to generate the route
await op.estimate(token.amount(10));
const path = op.route.toString();

const goodPath = happyPaths[`${token.symbol}:${silo.symbol}`];
expect(path).toBe(goodPath);
});
});
});

it("Estimates", async () => {
const op = builder.buildDeposit(sdk.tokens.BEAN_CRV3_LP, account);
op.setInputToken(sdk.tokens.USDC);
Expand Down
Loading
Loading