Skip to content

Commit

Permalink
Add clipboard support
Browse files Browse the repository at this point in the history
  • Loading branch information
uncoolzero committed Sep 9, 2023
1 parent 8d486de commit c56d4d3
Show file tree
Hide file tree
Showing 10 changed files with 81 additions and 26 deletions.
4 changes: 3 additions & 1 deletion projects/sdk/src/classes/Workflow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -289,8 +289,10 @@ export abstract class Workflow<
if (input instanceof StepClass) {
input.setSDK(Workflow.sdk);
}
const depositOptions = { tag: "depositAmount" }
const validInput = input.name === "pipelineDeposit";
this._generators.push(input);
this._options.push(options || null); // null = no options set
this._options.push(validInput ? depositOptions : options || null); // null = no options set
}
return this; // allow chaining
}
Expand Down
20 changes: 15 additions & 5 deletions projects/sdk/src/lib/farm/LibraryPresets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ export class LibraryPresets {
this.wellAddLiquidity = (well: BasinWell, tokenIn: ERC20Token, account: string, from?: FarmFromMode, to?: FarmToMode) => {

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

const transferBack = to === FarmToMode.INTERNAL;
const recipient = transferBack ? sdk.contracts.pipeline.address : account;
Expand All @@ -289,19 +289,29 @@ export class LibraryPresets {
const addLiquidity = new sdk.farm.actions.WellSync(well, tokenIn, recipient);

// This approves the transferToBeanstalk operation.
const approveBack = new sdk.farm.actions.ApproveERC20(well.lpToken, sdk.contracts.beanstalk.address);
const approveBack = new sdk.farm.actions.ApproveERC20(well.lpToken, sdk.contracts.beanstalk.address, true);

// Transfers the output token back to Beanstalk, from PIPELINE.
const transferToBeanstalk = new sdk.farm.actions.TransferToken(well.address, account, FarmFromMode.EXTERNAL, FarmToMode.INTERNAL);
const transferToBeanstalk = new sdk.farm.actions.TransferToken(well.address, account, FarmFromMode.EXTERNAL, FarmToMode.INTERNAL, true);


result.push(transfer);
advancedPipe.add(addLiquidity, { tag: "wellSync" });
advancedPipe.add(addLiquidity);
advancedPipe.add(
async function getBalance() {
return {
target: well.lpToken.address,
callData: well.lpToken.getContract().interface.encodeFunctionData("balanceOf", [
sdk.contracts.pipeline.address
])
};
},
{ tag: "amountToDeposit" }
);
if (transferBack) {
advancedPipe.add(approveBack);
advancedPipe.add(transferToBeanstalk);
}

result.push(advancedPipe);

return result;
Expand Down
14 changes: 12 additions & 2 deletions projects/sdk/src/lib/farm/actions/ApproveERC20.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
import { ethers } from "ethers";
import { ERC20Token } from "src/classes/Token";
import { RunContext, Step, StepClass } from "src/classes/Workflow";
import { Clipboard } from "src/lib/depot";
import { AdvancedPipePreparedResult } from "src/lib/depot/pipe";

export class ApproveERC20 extends StepClass<AdvancedPipePreparedResult> {
public name: string = "approve";
public token: ERC20Token;
public spender: string;
public useClipboard?: boolean;

constructor(token: ERC20Token, spender: string) {
constructor(token: ERC20Token, spender: string, useClipboard?: boolean) {
super();
if (!token) throw new Error("ApproveERC20 action requires a token");
if (!spender) throw new Error("ApproveERC20 action requires a spender");

this.token = token;
this.spender = spender;
this.useClipboard = useClipboard;
}

async run(_amountInStep: ethers.BigNumber, context: RunContext): Promise<Step<AdvancedPipePreparedResult>> {
Expand All @@ -23,9 +26,16 @@ export class ApproveERC20 extends StepClass<AdvancedPipePreparedResult> {
amountOut: _amountInStep,
value: ethers.BigNumber.from(0),
prepare: () => {
ApproveERC20.sdk.debug(`[${this.name}.encode()]`, {
token: this.token,
spender: this.spender,
amountInStep: _amountInStep,
useClipboard: this.useClipboard
});
return {
target: this.token.address,
callData: this.token.getContract().interface.encodeFunctionData("approve", [this.spender, _amountInStep])
callData: this.token.getContract().interface.encodeFunctionData("approve", [this.spender, _amountInStep]),
clipboard: this.useClipboard ? Clipboard.encodeSlot(context.step.findTag("amountToDeposit"), 0, 1) : undefined
};
},
decode: (data: string) => this.token.getContract().interface.decodeFunctionData("approve", data),
Expand Down
9 changes: 6 additions & 3 deletions projects/sdk/src/lib/farm/actions/Deposit.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { BasicPreparedResult, RunContext, Step, StepClass } from "src/classes/Workflow";
import { BasicPreparedResult, RunContext, StepClass } from "src/classes/Workflow";
import { ethers } from "ethers";
import { FarmFromMode, FarmToMode } from "../types";
import { Token } from "src/classes/Token";
import { Clipboard } from "src/lib/depot";

export class Deposit extends StepClass<BasicPreparedResult> {
public name: string = "deposit";
Expand All @@ -22,15 +23,17 @@ export class Deposit extends StepClass<BasicPreparedResult> {
context
});
if (!_amountInStep) throw new Error("Deposit: Missing _amountInStep");
const wellDeposit = this.token.symbol === "BEANETH";
return {
target: Deposit.sdk.contracts.beanstalk.address,
callData: Deposit.sdk.contracts.beanstalk.interface.encodeFunctionData("deposit", [
this.token.address,
_amountInStep,
this.fromMode
])
]),
clipboard: wellDeposit ? Clipboard.encodeSlot(context.step.findTag("depositAmount"), 9, 1) : undefined
};
},
},
decode: (data: string) => Deposit.sdk.contracts.beanstalk.interface.decodeFunctionData("deposit", data),
decodeResult: (result: string) => Deposit.sdk.contracts.beanstalk.interface.decodeFunctionResult("deposit", result)
};
Expand Down
12 changes: 9 additions & 3 deletions projects/sdk/src/lib/farm/actions/TransferToken.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
import { ethers } from "ethers";
import { BasicPreparedResult, RunContext, Step, StepClass } from "src/classes/Workflow";
import { FarmFromMode, FarmToMode } from "../types";
import { Clipboard } from "src/lib/depot";

export class TransferToken extends StepClass<BasicPreparedResult> {
public name: string = "transferToken";
public useClipboard?: boolean;

constructor(
public readonly _tokenIn: string,
public readonly _recipient: string,
public readonly _fromMode: FarmFromMode = FarmFromMode.INTERNAL_TOLERANT,
public readonly _toMode: FarmToMode = FarmToMode.INTERNAL
public readonly _toMode: FarmToMode = FarmToMode.INTERNAL,
useClipboard?: boolean
) {
super();
this.useClipboard = useClipboard;
}

async run(_amountInStep: ethers.BigNumber, context: RunContext) {
Expand All @@ -24,7 +28,8 @@ export class TransferToken extends StepClass<BasicPreparedResult> {
recipient: this._recipient,
amountInStep: _amountInStep,
fromMode: this._fromMode,
toMode: this._toMode
toMode: this._toMode,
useClipboard: this.useClipboard
});
return {
target: TransferToken.sdk.contracts.beanstalk.address,
Expand All @@ -34,7 +39,8 @@ export class TransferToken extends StepClass<BasicPreparedResult> {
_amountInStep, // ignore minAmountOut since there is no slippage on transfer
this._fromMode, //
this._toMode //
])
]),
clipboard: this.useClipboard ? Clipboard.encodeSlot(context.step.findTag("amountToDeposit"), 0, 2) : undefined
};
},
decode: (data: string) => TransferToken.sdk.contracts.beanstalk.interface.decodeFunctionData("transferToken", data),
Expand Down
23 changes: 18 additions & 5 deletions projects/sdk/src/lib/farm/farm.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { BeanstalkSDK } from "../BeanstalkSDK";
import * as ActionLibrary from "./actions";
import { LibraryPresets } from "./LibraryPresets";
import { BasicPreparedResult, RunMode, Step, Workflow } from "src/classes/Workflow";
import { RunMode, Workflow } from "src/classes/Workflow";
import { Beanstalk, Depot } from "src/constants/generated";
import { TokenValue } from "src/TokenValue";
import { CallOverrides, ethers } from "ethers";
Expand Down Expand Up @@ -94,7 +94,7 @@ export class AdvancedFarmWorkflow<RunData extends { slippage: number } = { slipp
public readonly FUNCTION_NAME = "advancedFarm";
private contract: Beanstalk;

constructor(protected sdk: BeanstalkSDK, public name: string = "Farm") {
constructor(protected sdk: BeanstalkSDK, public name: string = "AdvancedFarm") {
super(sdk, name);
this.contract = Workflow.sdk.contracts.beanstalk; // ?
}
Expand All @@ -113,7 +113,10 @@ export class AdvancedFarmWorkflow<RunData extends { slippage: number } = { slipp
}

encodeWorkflow() {
return this.contract.interface.encodeFunctionData(this.FUNCTION_NAME, [this.encodeSteps()]);
const steps = this.encodeSteps();
const encodedWorkflow = this.contract.interface.encodeFunctionData("advancedFarm", [steps]);
Workflow.sdk.debug(`[Workflow][${this.name}][encodeWorkflow]`, encodedWorkflow);
return encodedWorkflow;
}

encodeStep(p: AdvancedFarmPreparedResult): AdvancedFarmCallStruct {
Expand All @@ -125,9 +128,15 @@ export class AdvancedFarmWorkflow<RunData extends { slippage: number } = { slipp

////////// Parent Behavior //////////

async execute(amountIn: ethers.BigNumber | TokenValue, data: RunData): Promise<ethers.ContractTransaction> {
async execute(amountIn: ethers.BigNumber | TokenValue, data: RunData, overrides?: CallOverrides): Promise<ethers.ContractTransaction> {
const encoded = await this.estimateAndEncodeSteps(amountIn, RunMode.Execute, data);
return this.contract.advancedFarm(encoded, { value: this.value });
if (overrides) {
overrides.value = this.value;
} else {
overrides = { value: this.value };
}
Workflow.sdk.debug(`[Workflow][${this.name}][execute]`, encoded, overrides);
return this.contract.advancedFarm(encoded, overrides);
}

async callStatic(amountIn: ethers.BigNumber | TokenValue, data: RunData): Promise<string[]> {
Expand Down Expand Up @@ -165,4 +174,8 @@ export class Farm {
createAdvancedPipe(name?: string) {
return new AdvancedPipeWorkflow(Farm.sdk, name);
}

createAdvancedFarm(name?: string) {
return new AdvancedFarmWorkflow(Farm.sdk, name);
}
}
2 changes: 1 addition & 1 deletion projects/sdk/src/lib/farm/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export { Farm, FarmWorkflow } from "./farm";
export { Farm, FarmWorkflow, AdvancedFarmWorkflow } from "./farm";
export { FarmFromMode, FarmToMode } from "./types";
10 changes: 7 additions & 3 deletions projects/sdk/src/lib/silo/DepositOperation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Token } from "src/classes/Token";
import { ActionType } from "src/constants/actions";
import { TokenValue } from "src/TokenValue";
import { BeanstalkSDK } from "../BeanstalkSDK";
import { FarmFromMode, FarmToMode, FarmWorkflow } from "../farm";
import { AdvancedFarmWorkflow, FarmFromMode, FarmToMode, FarmWorkflow } from "../farm";

export class DepositOperation {
static sdk: BeanstalkSDK;
Expand All @@ -14,7 +14,7 @@ export class DepositOperation {
inputToken: Token;
inputAmount: TokenValue;
readonly router: Router;
workflow: FarmWorkflow<{ slippage: number } & Record<string, any>>;
workflow: AdvancedFarmWorkflow|FarmWorkflow<{ slippage: number } & Record<string, any>>;
lastAmountIn: TokenValue;

constructor(sdk: BeanstalkSDK, router: Router, targetToken: Token, account: string) {
Expand All @@ -37,7 +37,11 @@ export class DepositOperation {
buildWorkflow() {
const route = this.router.getRoute(this.inputToken.symbol, `${this.targetToken.symbol}:SILO`);

this.workflow = DepositOperation.sdk.farm.create(`Deposit`);
if (this.targetToken.symbol === "BEANETH") {
this.workflow = DepositOperation.sdk.farm.createAdvancedFarm(`Deposit`);
} else {
this.workflow = DepositOperation.sdk.farm.create(`Deposit`);
}

for (let i = 0; i < route.length; i++) {
let from, to;
Expand Down
3 changes: 2 additions & 1 deletion projects/ui/src/components/Silo/Actions/Deposit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,8 @@ const DepositPropProvider: FC<{
depositTxn,
amountIn,
values.settings.slippage,
target.equals(BEAN_ETH_WELL_LP) ? 1.2 : undefined
target.equals(BEAN_ETH_WELL_LP) ? 1.2 : undefined,
target.equals(BEAN_ETH_WELL_LP)
);

const txn = await execute();
Expand Down
10 changes: 8 additions & 2 deletions projects/ui/src/lib/Txn/FormTxn/FormTxnBundler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,15 @@ export class FormTxnBundler {
operation: FarmStep,
amountIn: TokenValue,
slippage: number,
gasMultiplier?: number
gasMultiplier?: number,
advancedFarm?: boolean
) {
const farm = this._sdk.farm.create();
let farm: any;
if (advancedFarm) {
farm = this._sdk.farm.createAdvancedFarm();
} else {
farm = this._sdk.farm.create();
}

Object.entries(this.before).forEach(([step, farmStep]) => {
const farmInput = farmStep.getFarmInput();
Expand Down

0 comments on commit c56d4d3

Please sign in to comment.