Skip to content

Commit

Permalink
Aave V3 supply and withdraw
Browse files Browse the repository at this point in the history
  • Loading branch information
pgbrandao committed Oct 31, 2023
1 parent 0bc860f commit 18987eb
Show file tree
Hide file tree
Showing 13 changed files with 393 additions and 29 deletions.
2 changes: 2 additions & 0 deletions core/src/abis/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Interface } from "ethers";

import IERC20ABI from "./IERC20.json";
import IPoolABI from "./Aave/IPool.json";
import IBeefyVaultV6ABI from "./Beefy/IBeefyVaultV6.json";
import IHypervisorABI from "./Gamma/IHypervisor.json";
import IHypervisorRouterABI from "./Gamma/IHypervisorRouter.json";
Expand All @@ -11,6 +12,7 @@ import RouterABI from "./Router.json";
import RouterSimulatorABI from "./RouterSimulator.json";

export const IERC20 = new Interface(IERC20ABI.abi);
export const IPool = new Interface(IPoolABI);
export const IBeefyVaultV6 = new Interface(IBeefyVaultV6ABI);
export const IHypervisor = new Interface(IHypervisorABI);
export const IHypervisorRouter = new Interface(IHypervisorRouterABI.abi);
Expand Down
238 changes: 238 additions & 0 deletions core/src/asset-strategies/AaveV3DepositStrategy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@
import { RequestTree } from "../transaction/get-prices-and-linked-assets";
import { StoreOpType } from "../transaction/types";
import {
fetchPriceData,
getPrice,
} from "../transaction/asset-type-strategies-helpers";
import { getMagicOffsets } from "core/src/utils/get-magic-offset";
import { IERC20, IPool } from "core/src/abis";
import {
FRACTION_MULTIPLIER,
MAGIC_REPLACER_0,
} from "core/src/utils/get-magic-offset";
import {
FetchPriceDataParams,
GetPriceParams,
GenerateStepParams,
} from "./InterfaceStrategy";
import { InterfaceStrategy } from "./InterfaceStrategy";

const poolAddress = "0x794a61358D6845594F94dc1DB02A252b5b4814aD";

export class AaveV3DepositStrategy extends InterfaceStrategy {
fetchPriceData({ provider, assetStore, asset }: FetchPriceDataParams) {
const linkedAsset = assetStore.getAssetById(asset.linkedAssets[0].assetId);

let requestTree: RequestTree = {};

requestTree[asset.address] = {};

const fetchedData = fetchPriceData({
provider,
assetStore,
asset: linkedAsset,
});
requestTree = {
...requestTree,
...fetchedData,
};
return requestTree;
}

getPrice({ assetStore, asset, requestTree }: GetPriceParams) {
const linkedAsset = assetStore.getAssetById(asset.linkedAssets[0].assetId);

return getPrice({ assetStore, asset: linkedAsset, requestTree });
}

async generateStep({
assetAllocation,
assetStore,
walletAddress,
value,
currentAllocation,
routerOperation,
}: GenerateStepParams) {
const asset = assetStore.getAssetById(assetAllocation.assetId);
if (asset.linkedAssets.length != 1) {
throw new Error(
`AaveV3DepositStrategy: asset ${asset.id} should have exactly one linked asset`
);
}
const linkedAsset = assetStore.getAssetById(asset.linkedAssets[0].assetId);

if (assetAllocation.fraction > 0) {
const storeNumberFrom = routerOperation.stores.findOrInitializeStoreIdx({
assetId: linkedAsset.id,
});
const storeNumberTo = routerOperation.stores.findOrInitializeStoreIdx({
assetId: asset.id,
});
const storeNumberTmp = routerOperation.stores.findOrInitializeStoreIdx({
tmpStoreName: `${asset.id} tmp store 0`,
});

const currentFraction = currentAllocation.getAssetById({
assetId: linkedAsset.id,
}).fraction;
const newFraction = asset.linkedAssets[0].fraction / currentFraction;
const variation = currentFraction * newFraction;

currentAllocation.updateFraction({
assetId: linkedAsset.id,
delta: -variation,
});
currentAllocation.updateFraction({
assetId: asset.id,
delta: variation,
});

const { data: approveEncodedCall, offsets: approveFromOffsets } =
getMagicOffsets({
data: IERC20.encodeFunctionData("approve", [
poolAddress,
MAGIC_REPLACER_0,
]),
magicReplacers: [MAGIC_REPLACER_0],
});

routerOperation.steps.push({
stepAddress: linkedAsset.address,
stepEncodedCall: approveEncodedCall,
storeOperations: [
{
storeOpType: StoreOpType.RetrieveStoreAssignCall,
storeNumber: storeNumberFrom,
offset: approveFromOffsets[0],
fraction: Math.round(FRACTION_MULTIPLIER * newFraction),
},
],
});

const { offsets: balanceOfToOffsets } = getMagicOffsets({
data: IERC20.encodeFunctionResult("balanceOf", [MAGIC_REPLACER_0]),
magicReplacers: [MAGIC_REPLACER_0],
});

routerOperation.steps.push({
stepAddress: asset.address,
stepEncodedCall: IERC20.encodeFunctionData("balanceOf", [
asset.address,
]),
storeOperations: [
{
storeOpType: StoreOpType.RetrieveResultAddStore,
storeNumber: storeNumberTmp,
offset: balanceOfToOffsets[0],
fraction: FRACTION_MULTIPLIER,
},
],
});

const { data: supplyEncodedCall, offsets: supplyFromOffsets } =
getMagicOffsets({
data: IPool.encodeFunctionData("supply", [
linkedAsset.address, // asset
MAGIC_REPLACER_0, // amount
walletAddress, // onBehalfOf
0, // referralCode
]),
magicReplacers: [MAGIC_REPLACER_0],
});

routerOperation.steps.push({
stepAddress: poolAddress,
stepEncodedCall: supplyEncodedCall,
storeOperations: [
{
storeOpType: StoreOpType.RetrieveStoreAssignCallSubtract,
storeNumber: storeNumberFrom,
offset: supplyFromOffsets[0],
fraction: newFraction * FRACTION_MULTIPLIER,
},
],
});

routerOperation.steps.push({
stepAddress: asset.address,
stepEncodedCall: IERC20.encodeFunctionData("balanceOf", [
asset.address,
]),
storeOperations: [
{
storeOpType: StoreOpType.RetrieveResultAddStore,
storeNumber: storeNumberTo,
offset: balanceOfToOffsets[0],
fraction: newFraction * FRACTION_MULTIPLIER,
},
{
storeOpType: StoreOpType.SubtractStoreFromStore,
storeNumber: storeNumberTmp,
offset: storeNumberTo,
fraction: FRACTION_MULTIPLIER,
},
],
});
} else if (assetAllocation.fraction < 0) {
const storeNumberFrom = routerOperation.stores.findOrInitializeStoreIdx({
assetId: asset.id,
});
const storeNumberTo = routerOperation.stores.findOrInitializeStoreIdx({
assetId: linkedAsset.id,
});

const currentFraction = currentAllocation.getAssetById({
assetId: asset.id,
}).fraction;
const newFraction = -assetAllocation.fraction / currentFraction;
const variation = newFraction * currentFraction;

asset.linkedAssets.map((la, i) => {
currentAllocation.updateFraction({
assetId: la.assetId,
delta: variation * la.fraction,
});
currentAllocation.updateFraction({
assetId: asset.id,
delta: -variation * la.fraction,
});
});

const { data: withdrawEncodedCall, offsets: withdrawFromOffsets } =
getMagicOffsets({
data: IPool.encodeFunctionData("withdraw", [
linkedAsset.address, // asset
MAGIC_REPLACER_0, // _shares
walletAddress, // to
]),
magicReplacers: [MAGIC_REPLACER_0],
});

const { offsets: withdrawToOffsets } = getMagicOffsets({
data: IPool.encodeFunctionResult("withdraw", [MAGIC_REPLACER_0]),
magicReplacers: [MAGIC_REPLACER_0],
});

routerOperation.steps.push({
stepAddress: poolAddress,
stepEncodedCall: withdrawEncodedCall,
storeOperations: [
{
storeOpType: StoreOpType.RetrieveStoreAssignCallSubtract,
storeNumber: storeNumberFrom,
offset: withdrawFromOffsets[0],
fraction: newFraction * FRACTION_MULTIPLIER,
},
{
storeOpType: StoreOpType.RetrieveResultAddStore,
storeNumber: storeNumberTo,
offset: withdrawToOffsets[0],
fraction: FRACTION_MULTIPLIER,
},
],
});
}

return routerOperation;
}
}
4 changes: 2 additions & 2 deletions core/src/asset-strategies/BeefyDepositStrategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ export class BeefyDepositStrategy extends InterfaceStrategy {
]),
storeOperations: [
{
storeOpType: StoreOpType.RetrieveResultAssignStore,
storeOpType: StoreOpType.RetrieveResultAddStore,
storeNumber: storeNumberTmp,
offset: balanceOfToOffsets[0],
fraction: FRACTION_MULTIPLIER,
Expand Down Expand Up @@ -227,7 +227,7 @@ export class BeefyDepositStrategy extends InterfaceStrategy {
]),
storeOperations: [
{
storeOpType: StoreOpType.RetrieveResultAssignStore,
storeOpType: StoreOpType.RetrieveResultAddStore,
storeNumber: storeNumberTmp,
offset: balanceOfToOffsets[0],
fraction: FRACTION_MULTIPLIER,
Expand Down
10 changes: 5 additions & 5 deletions core/src/asset-strategies/GammaDepositStrategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,13 +217,13 @@ export class GammaDepositStrategy extends InterfaceStrategy {
fraction: Math.round(linkedAssetFractions[1] * FRACTION_MULTIPLIER),
},
{
storeOpType: StoreOpType.RetrieveResultAssignStore,
storeOpType: StoreOpType.RetrieveResultAddStore,
storeNumber: storeNumberTmp[0],
offset: calculateRatiosToOffsets[0],
fraction: FRACTION_MULTIPLIER,
},
{
storeOpType: StoreOpType.RetrieveResultAssignStore,
storeOpType: StoreOpType.RetrieveResultAddStore,
storeNumber: storeNumberTmp[1],
offset: calculateRatiosToOffsets[1],
fraction: FRACTION_MULTIPLIER,
Expand Down Expand Up @@ -305,7 +305,7 @@ export class GammaDepositStrategy extends InterfaceStrategy {
fraction: FRACTION_MULTIPLIER,
},
{
storeOpType: StoreOpType.RetrieveResultAssignStore,
storeOpType: StoreOpType.RetrieveResultAddStore,
storeNumber: storeNumberTo,
offset: depositToOffsets[0],
fraction: FRACTION_MULTIPLIER,
Expand Down Expand Up @@ -372,13 +372,13 @@ export class GammaDepositStrategy extends InterfaceStrategy {
fraction: newFraction * FRACTION_MULTIPLIER,
},
{
storeOpType: StoreOpType.RetrieveResultAssignStore,
storeOpType: StoreOpType.RetrieveResultAddStore,
storeNumber: storeNumberTo0,
offset: withdrawToOffsets[0],
fraction: FRACTION_MULTIPLIER,
},
{
storeOpType: StoreOpType.RetrieveResultAssignStore,
storeOpType: StoreOpType.RetrieveResultAddStore,
storeNumber: storeNumberTo1,
offset: withdrawToOffsets[1],
fraction: FRACTION_MULTIPLIER,
Expand Down
12 changes: 1 addition & 11 deletions core/src/asset-strategies/InterfaceStrategy.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,13 @@
import { Provider } from "ethers";
import {
RequestTree,
RequestTree,
} from "../transaction/get-prices-and-linked-assets";
import { RequestTree } from "../transaction/get-prices-and-linked-assets";
import {
RouterOperation,
LinkedAsset,
Asset,
AssetStore,
CurrentAllocation,
FractionAllocationItem,
RouterOperation,
} from "../transaction/types";
import {
GenerateStepParams,
FetchPriceDataParams,
GetPriceParams,
GetLinkedAssetsParams,
} from "./InterfaceStrategy";

export abstract class InterfaceStrategy {
abstract generateStep({
Expand Down
2 changes: 2 additions & 0 deletions core/src/asset-strategies/asset-type-strategies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { NetworkTokenStrategy } from "./NetworkTokenStrategy";
import { TokenStrategy } from "./TokenStrategy";
import { GammaDepositStrategy } from "./GammaDepositStrategy";
import { BeefyDepositStrategy } from "./BeefyDepositStrategy";
import { AaveV3DepositStrategy } from "./AaveV3DepositStrategy";
import { InterfaceStrategy } from "./InterfaceStrategy";

export const assetTypeStrategies: {
Expand All @@ -15,5 +16,6 @@ export const assetTypeStrategies: {
networkToken: new NetworkTokenStrategy(),
beefyDeposit: new BeefyDepositStrategy(),
gammaDeposit: new GammaDepositStrategy(),
aaveV3Deposit: new AaveV3DepositStrategy(),
},
};
4 changes: 2 additions & 2 deletions core/src/config/config.default.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
export default {
networks: {
137: {
routerAddress: "0x9cD5c60284654b99540Bc5839Ab0edBFDaa6cA20",
routerSimulatorAddress: "0xa33C0B0Be63BaDf55054Feaa1f3B5B382E19A52D",
routerAddress: "0x5F5Ef893d65b91c5A060119fcBe8F0EB964dB5a8",
routerSimulatorAddress: "0xf12093D00E70D0AF5a3d16950d515cbC8232d46F",
gammaRatiosCalculator: "0x0F306e004258dc4c9Ecc0373b6E3dC59A3f0dB58",
},
},
Expand Down
4 changes: 2 additions & 2 deletions core/src/path/exchanges.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ export class Paraswap extends Exchange {
fraction: Math.round(path.fraction * FRACTION_MULTIPLIER),
},
{
storeOpType: StoreOpType.RetrieveResultAssignStore,
storeOpType: StoreOpType.RetrieveResultAddStore,
storeNumber: storeNumberTo,
offset: swapToOffset,
fraction: 0,
Expand Down Expand Up @@ -292,7 +292,7 @@ export class ZeroX extends Exchange {
fraction: Math.round(path.fraction * FRACTION_MULTIPLIER),
},
{
storeOpType: StoreOpType.RetrieveResultAssignStore,
storeOpType: StoreOpType.RetrieveResultAddStore,
storeNumber: storeNumberTo,
offset: swapToOffsets[0],
fraction: 0,
Expand Down
5 changes: 3 additions & 2 deletions core/src/transaction/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -269,12 +269,13 @@ export type AssetType =
| "token"
| "networkToken"
| "gammaDeposit"
| "beefyDeposit";
| "beefyDeposit"
| "aaveV3Deposit";

export enum StoreOpType {
RetrieveStoreAssignValue, // 0
RetrieveStoreAssignCall, // 1
RetrieveResultAssignStore, // 2
RetrieveResultAddStore, // 2
RetrieveResultSubtractStore, // 3
RetrieveStoreAssignValueSubtract, // 4
RetrieveStoreAssignCallSubtract, // 5
Expand Down
Loading

0 comments on commit 18987eb

Please sign in to comment.