Skip to content

Commit

Permalink
Addings SavisDai integration (still untested)
Browse files Browse the repository at this point in the history
Also changes to assets
  • Loading branch information
pgbrandao committed Dec 8, 2023
1 parent 2aef49d commit 7da333f
Show file tree
Hide file tree
Showing 11 changed files with 800 additions and 2 deletions.
477 changes: 477 additions & 0 deletions core/src/abis/Maker/SavingsDai.json

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions core/src/abis/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import UniswapV2FactoryABI from "./UniswapV2/UniswapV2Factory.json";
import UniswapV2PairABI from "./UniswapV2/UniswapV2Pair.json";
import UniswapV2Router02ABI from "./UniswapV2/UniswapV2Router02.json";
import ZeroXERC20ABI from "./ZeroX/ZeroXERC20.json";
import SavingsDaiABI from "./Maker/SavingsDai.json";
import RouterABI from "./Router.json";
import RouterSimulatorABI from "./RouterSimulator.json";

Expand All @@ -37,5 +38,6 @@ export const UniswapV2Factory = new Interface(UniswapV2FactoryABI);
export const UniswapV2Pair = new Interface(UniswapV2PairABI);
export const UniswapV2Router02 = new Interface(UniswapV2Router02ABI);
export const ZeroXERC20 = new Interface(ZeroXERC20ABI.abi);
export const SavingsDai = new Interface(SavingsDaiABI);
export const Router = new Interface(RouterABI.abi);
export const RouterSimulator = new Interface(RouterSimulatorABI.abi);
202 changes: 202 additions & 0 deletions core/src/asset-strategies/SavingsDaiDepositStrategy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
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, SavingsDai } from "core/src/abis";
import {
FRACTION_MULTIPLIER,
MAGIC_REPLACERS,
} from "core/src/utils/get-magic-offset";
import {
FetchPriceDataParams,
GetPriceParams,
GenerateStepParams,
} from "./InterfaceStrategy";
import { InterfaceStrategy } from "./InterfaceStrategy";

export class SavingsDaiDepositStrategy 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,
chainId,
value,
currentAllocation,
routerOperation,
}: GenerateStepParams) {
const asset = assetStore.getAssetById(assetAllocation.assetId);
if (asset.linkedAssets.length != 1) {
throw new Error(
`SavingsDaiDepositStrategy: asset ${asset.id} should have exactly one linked asset`
);
}
const linkedAsset = assetStore.getAssetById(asset.linkedAssets[0].assetId);

const storeNumberSDai = routerOperation.stores.findOrInitializeStoreIdx({
assetId: asset.id,
});
const storeNumberDai = routerOperation.stores.findOrInitializeStoreIdx({
assetId: linkedAsset.id,
});

if (assetAllocation.fraction > 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", [
asset.address,
MAGIC_REPLACERS[0],
]),
magicReplacers: [MAGIC_REPLACERS[0]],
});

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

const { data: depositEncodedCall, offsets: depositFromOffsets } =
getMagicOffsets({
data: SavingsDai.encodeFunctionData("deposit", [
MAGIC_REPLACERS[0], // assets
walletAddress, // receiver
]),
magicReplacers: [MAGIC_REPLACERS[0]],
});

const { offsets: depositToOffsets } = getMagicOffsets({
data: SavingsDai.encodeFunctionResult("deposit", [
MAGIC_REPLACERS[0], // shares
]),
magicReplacers: [MAGIC_REPLACERS[0]],
});

routerOperation.steps.push({
stepAddress: asset.address,
stepEncodedCall: depositEncodedCall,
storeOperations: [
{
storeOpType: StoreOpType.RetrieveStoreAssignCallSubtract,
storeNumber: storeNumberDai,
secondaryStoreNumber: 0,
offset: depositFromOffsets[0],
fraction: Math.round(newFraction * FRACTION_MULTIPLIER),
},
{
storeOpType: StoreOpType.RetrieveResultAddStore,
storeNumber: storeNumberSDai,
secondaryStoreNumber: 0,
offset: depositToOffsets[0],
fraction: FRACTION_MULTIPLIER,
},
],
});
} else if (assetAllocation.fraction < 0) {
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: redeemEncodedCall, offsets: redeemFromOffsets } =
getMagicOffsets({
data: SavingsDai.encodeFunctionData("redeem", [
MAGIC_REPLACERS[0], // shares
walletAddress, // receiver
walletAddress, // owner
]),
magicReplacers: [MAGIC_REPLACERS[0]],
});

const { offsets: redeemToOffsets } = getMagicOffsets({
data: SavingsDai.encodeFunctionResult("redeem", [MAGIC_REPLACERS[0]]),
magicReplacers: [MAGIC_REPLACERS[0]],
});

routerOperation.steps.push({
stepAddress: asset.address,
stepEncodedCall: redeemEncodedCall,
storeOperations: [
{
storeOpType: StoreOpType.RetrieveStoreAssignCallSubtract,
storeNumber: storeNumberSDai,
secondaryStoreNumber: 0,
offset: redeemFromOffsets[0],
fraction: Math.round(newFraction * FRACTION_MULTIPLIER),
},
{
storeOpType: StoreOpType.RetrieveResultAddStore,
storeNumber: storeNumberDai,
secondaryStoreNumber: 0,
offset: redeemToOffsets[0],
fraction: FRACTION_MULTIPLIER,
},
],
});
}

return routerOperation;
}
}
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 @@ -8,6 +8,7 @@ import { AaveV2DepositStrategy } from "./AaveV2DepositStrategy";
import { AaveV3DepositStrategy } from "./AaveV3DepositStrategy";
import { InterfaceStrategy } from "./InterfaceStrategy";
import { BalancerDepositStrategy } from "./BalancerDepositStrategy";
import { SavingsDaiDepositStrategy } from "./SavingsDaiDepositStrategy";

export const assetTypeStrategies: {
[chainId: number]: {
Expand All @@ -23,5 +24,6 @@ export const assetTypeStrategies: {
gammaDeposit: new GammaDepositStrategy(),
aaveV2Deposit: new AaveV2DepositStrategy(),
aaveV3Deposit: new AaveV3DepositStrategy(),
savingsDaiDeposit: new SavingsDaiDepositStrategy(),
},
};
1 change: 1 addition & 0 deletions core/src/transaction/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ export type AssetType =
| "beefyDeposit"
| "aaveV2Deposit"
| "aaveV3Deposit"
| "savingsDaiDeposit"
| "balancerDeposit"
| "uniswapV2Liquidity";

Expand Down
32 changes: 32 additions & 0 deletions core/tests/protocols/savingsDai.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { test } from "vitest";
import { simulateRouterOperationHelper } from "./utils";

test.skip("generateTransaction: USDC to SDAI (savingsDai)", async () => {
await simulateRouterOperationHelper({
chainId: 1,
inputAllocation: [
{
assetId: "ed46f991-d225-491d-b2b2-91f89da016d2",
amountStr: "1000000000",
},
],
outputAllocation: [
{ assetId: "8bd1bd78-4938-4204-a945-fa63f57c642b", fraction: 1.0 },
],
});
});

test.skip("generateTransaction: SDAI (savingsDai) to USDC", async () => {
await simulateRouterOperationHelper({
chainId: 1,
inputAllocation: [
{
assetId: "8bd1bd78-4938-4204-a945-fa63f57c642b",
amountStr: "1000000000000000000000",
},
],
outputAllocation: [
{ assetId: "ed46f991-d225-491d-b2b2-91f89da016d2", fraction: 1.0 },
],
});
});
14 changes: 14 additions & 0 deletions data/assets/1/networkToken.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[
{
"id": "98887ce0-466f-481d-a0a0-3d5bf5ea6d83",
"name": "Ether",
"chainId": 1,
"active": true,
"address": "0x0000000000000000000000000000000000001010",
"color": "#818181",
"decimals": 18,
"symbol": "ETH",
"type": "networkToken",
"visible": true
}
]
23 changes: 23 additions & 0 deletions data/assets/1/savingsDaiDeposit.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[
{
"id": "8bd1bd78-4938-4204-a945-fa63f57c642b",
"name": "Savings Dai",
"chainId": 1,
"active": true,
"address": "0x83F20F44975D03b1b09e64809B757c47f942BEeA",
"color": "#79A63A",
"decimals": 18,
"symbol": "sDAI",
"type": "savingsDaiDeposit",
"visible": true,
"maxSize": 64,
"allowSlot": 2,
"balanceSlot": 1,
"linkedAssets": [
{
"assetId": "389d84c3-9095-4b00-b01a-18948b9ada39",
"fraction": 1
}
]
}
]
31 changes: 31 additions & 0 deletions data/assets/1/token.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
[
{
"id": "ed46f991-d225-491d-b2b2-91f89da016d2",
"active": true,
"address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"color": "#2775ca",
"decimals": 6,
"name": "USD Coin",
"chainId": 1,
"symbol": "USDC",
"type": "token",
"visible": true,
"allowSlot": 10,
"balanceSlot": 9
},
{
"id": "a80c67f9-5ba9-4c05-b5b1-511836b38454",
"name": "DAI",
"chainId": 1,
"active": true,
"address": "0x6B175474E89094C44Da98b954EedeAC495271d0F",
"color": "#fcb934",
"decimals": 18,
"symbol": "DAI",
"type": "token",
"visible": true,
"allowSlot": 3,
"balanceSlot": 2,
"maxSize": 64
}
]
4 changes: 2 additions & 2 deletions data/assets/137/balancerDeposit.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@
"linkedAssets": [
{
"assetId": "8634b650-20fe-4f9e-8310-6672b38ea0ce",
"fraction": 0
"fraction": 0.7951
},
{
"assetId": "d604439e-d464-4df5-bed1-66815b348cab",
"fraction": 1
"fraction": 0.2049
}
],
"name": "maticX/WMATIC",
Expand Down
14 changes: 14 additions & 0 deletions data/assets/137/networkToken.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[
{
"id": "48f0325c-e5cc-4dac-9873-793f6c12fe08",
"name": "Matic",
"chainId": 137,
"active": true,
"address": "0x0000000000000000000000000000000000001010",
"color": "#468af0",
"decimals": 18,
"symbol": "MATIC",
"type": "networkToken",
"visible": true
}
]

0 comments on commit 7da333f

Please sign in to comment.