├── .eslintignore ├── .eslintrc.json ├── .github └── workflows │ ├── lint.yaml │ └── test.yaml ├── .gitignore ├── .prettierignore ├── .prettierrc ├── LICENSE ├── README.md ├── dist ├── examples │ ├── contractAddresses.d.ts │ ├── contractAddresses.js │ ├── mint.d.ts │ ├── mint.js │ ├── poolDetails.d.ts │ ├── poolDetails.js │ ├── poolId.d.ts │ ├── poolId.js │ ├── swap.d.ts │ ├── swap.js │ ├── tvl.d.ts │ └── tvl.js ├── hardhat.config.d.ts ├── hardhat.config.js └── src │ ├── constants │ ├── time.d.ts │ └── time.js │ ├── exitPool.d.ts │ ├── exitPool.js │ ├── helpers │ ├── calcFixedAPR.d.ts │ ├── calcFixedAPR.js │ ├── calcPoolSwap.d.ts │ ├── calcPoolSwap.js │ ├── calcSpotPrice.d.ts │ ├── calcSpotPrice.js │ ├── calcTotalValueLocked.d.ts │ ├── calcTotalValueLocked.js │ ├── calcTvl.d.ts │ ├── calcTvl.js │ ├── getElementAddresses.d.ts │ ├── getElementAddresses.js │ ├── getLatestBlockTimestamp.d.ts │ ├── getLatestBlockTimestamp.js │ ├── getOpenTerms.d.ts │ ├── getOpenTerms.js │ ├── getPoolId.d.ts │ ├── getPoolId.js │ ├── getReserves.d.ts │ ├── getReserves.js │ ├── getSecondsUntilExpiration.d.ts │ ├── getSecondsUntilExpiration.js │ ├── getTermByTokenSymbol.d.ts │ ├── getTermByTokenSymbol.js │ ├── getTermTokenSymbols.d.ts │ ├── getTermTokenSymbols.js │ ├── getTerms.d.ts │ ├── getTerms.js │ ├── getTimeUntilExpiration.d.ts │ ├── getTimeUntilExpiration.js │ ├── getTokenInfo.d.ts │ ├── getTokenInfo.js │ ├── getTokenPrice.d.ts │ ├── getTokenPrice.js │ ├── getTotalSupply.d.ts │ ├── getTotalSupply.js │ ├── getUnderlyingContractsByAddress.d.ts │ ├── getUnderlyingContractsByAddress.js │ ├── getUnitSeconds.d.ts │ └── getUnitSeconds.js │ ├── index.d.ts │ ├── index.js │ ├── joinPool.d.ts │ ├── joinPool.js │ ├── mint.d.ts │ ├── mint.js │ ├── prices │ ├── coingecko │ │ ├── coins.json │ │ ├── index.d.ts │ │ └── index.js │ ├── curve │ │ ├── pools.d.ts │ │ ├── pools.js │ │ ├── stablePools.d.ts │ │ └── stablePools.js │ ├── getTokenPrice.d.ts │ └── getTokenPrice.js │ ├── swap.d.ts │ └── swap.js ├── elf.default.env ├── examples ├── contractAddresses.ts ├── interestPerToken.ts ├── mint.ts ├── poolDetails.ts ├── poolId.ts ├── swap.ts └── tvl.ts ├── hardhat.config.test.ts ├── hardhat.config.ts ├── package-lock.json ├── package.json ├── scripts ├── build.sh └── generate-interfaces.ts ├── src ├── constants │ └── time.ts ├── exitPool.ts ├── helpers │ ├── calcFixedAPR.ts │ ├── calcPoolSwap.ts │ ├── calcSpotPrice.ts │ ├── calcTotalValueLocked.ts │ ├── getElementAddresses.ts │ ├── getInterestPerToken.ts │ ├── getLatestBlockTimestamp.ts │ ├── getOpenTerms.ts │ ├── getPoolId.ts │ ├── getReserves.ts │ ├── getSecondsUntilExpiration.ts │ ├── getTermByTokenSymbol.ts │ ├── getTermTokenSymbols.ts │ ├── getTerms.ts │ ├── getTokenInfo.ts │ ├── getTotalSupply.ts │ ├── getUnderlyingContractsByAddress.ts │ └── getUnitSeconds.ts ├── index.ts ├── joinPool.ts ├── mint.ts ├── prices │ ├── coingecko │ │ ├── coins.json │ │ └── index.ts │ ├── curve │ │ ├── pools.ts │ │ └── stablePools.ts │ └── getTokenPrice.ts └── swap.ts ├── test ├── calcFixedAprTest.ts ├── calcSpotPriceTest.ts └── getSecondsUntilExpirationTest.ts └── tsconfig.json /.eslintignore: -------------------------------------------------------------------------------- 1 | compiled/ 2 | dist/ 3 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "es2021": true, 5 | "node": true 6 | }, 7 | "extends": [ 8 | "eslint:recommended", 9 | "plugin:@typescript-eslint/recommended" 10 | ], 11 | "parser": "@typescript-eslint/parser", 12 | "parserOptions": { 13 | "ecmaVersion": 12, 14 | "sourceType": "module" 15 | }, 16 | "plugins": [ 17 | "@typescript-eslint" 18 | ], 19 | "rules": { 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /.github/workflows/lint.yaml: -------------------------------------------------------------------------------- 1 | name: Lint 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | branches: 9 | - main 10 | 11 | jobs: 12 | 13 | lint: 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - name: check out github repository 18 | uses: actions/checkout@v2 19 | with: 20 | fetch-depth: 1 21 | 22 | - name: setup ssh-agent 23 | uses: webfactory/ssh-agent@v0.5.3 24 | with: 25 | ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }} 26 | 27 | - name: init 28 | run: npm ci 29 | 30 | - name: Style Check 31 | run: npm run style-check 32 | 33 | - name: Lint Check 34 | run: npm run lint-check 35 | -------------------------------------------------------------------------------- /.github/workflows/test.yaml: -------------------------------------------------------------------------------- 1 | name: Tests 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | branches: 9 | - main 10 | 11 | jobs: 12 | unit: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@v2 16 | - name: setup ssh-agent 17 | uses: webfactory/ssh-agent@v0.5.3 18 | with: 19 | ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }} 20 | - name: Install dependencies 21 | run: npm ci 22 | - name: test 23 | run: npm run test 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | contracts 4 | artifacts 5 | cache 6 | typechain 7 | elf.env 8 | compiled -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | *.json 2 | *.js 3 | *.md 4 | *.yaml 5 | contracts/ 6 | typechain/ 7 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "bracketSpacing": true 3 | } 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ELF SDK 2 | [![Build Status](https://github.com/element-fi/elf-sdk/workflows/Tests/badge.svg)](https://github.com/element-fi/elf-sdk/actions) 3 | [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/element-fi/elf-sdk/blob/master/LICENSE) 4 | 5 | **⚠️ This is a work in progress! ⚠️** 6 | 7 | This repo provides an SDK for developers to use when interacting with and building on Element smart contracts. 8 | 9 | ## Install 10 | 11 | ```bash 12 | npm install git+https://github.com/element-fi/elf-sdk.git 13 | npm run generate-interfaces 14 | ``` 15 | 16 | Since this repo is not an npm package, it can be helpful to include this simple script to upgrade your project to the latest commit: 17 | 18 | ``` 19 | "scripts": { 20 | "update-elf-sdk": "npm install git+https://github.com/element-fi/elf-sdk.git" 21 | }, 22 | ``` 23 | 24 | ## Build 25 | 26 | ```bash 27 | npm run build 28 | ``` 29 | 30 | ## Configure 31 | 32 | To use the Element SDK you need to configure some env variables. For linux and mac run the following: 33 | 34 | 1) Copy `elf.default.env` 35 | 36 | ```bash 37 | cp elf.default.env elf.env 38 | ``` 39 | 40 | 2) Update elf.env with your private key and alchemy api key 41 | 42 | ```bash 43 | export MAINNET_PROVIDER_URL=[MAINNET_PROVIDER_URL_HERE] 44 | export GOERLI_PROVIDER_URL=[GOERLI_PROVIDER_URL_HERE] 45 | export PRIVATE_KEY=[PRIVATE_KEY_HERE] 46 | ``` 47 | 48 | 3) Source the env file 49 | 50 | ```bash 51 | source elf.env 52 | ``` 53 | 54 | ## Run Example Script: 55 | 56 | ```bash 57 | npx hardhat run examples/poolDetails.ts --network goerli 58 | ``` 59 | -------------------------------------------------------------------------------- /dist/examples/contractAddresses.d.ts: -------------------------------------------------------------------------------- 1 | export {}; 2 | -------------------------------------------------------------------------------- /dist/examples/mint.d.ts: -------------------------------------------------------------------------------- 1 | export {}; 2 | -------------------------------------------------------------------------------- /dist/examples/poolDetails.d.ts: -------------------------------------------------------------------------------- 1 | export {}; 2 | -------------------------------------------------------------------------------- /dist/examples/poolId.d.ts: -------------------------------------------------------------------------------- 1 | export {}; 2 | -------------------------------------------------------------------------------- /dist/examples/poolId.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | /* 3 | * Copyright 2021 Element Finance, Inc 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 18 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 19 | return new (P || (P = Promise))(function (resolve, reject) { 20 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 21 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 22 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 23 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 24 | }); 25 | }; 26 | var __generator = (this && this.__generator) || function (thisArg, body) { 27 | var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; 28 | return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; 29 | function verb(n) { return function (v) { return step([n, v]); }; } 30 | function step(op) { 31 | if (f) throw new TypeError("Generator is already executing."); 32 | while (_) try { 33 | if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; 34 | if (y = 0, t) op = [op[0] & 2, t.value]; 35 | switch (op[0]) { 36 | case 0: case 1: t = op; break; 37 | case 4: _.label++; return { value: op[1], done: false }; 38 | case 5: _.label++; y = op[1]; op = [0]; continue; 39 | case 7: op = _.ops.pop(); _.trys.pop(); continue; 40 | default: 41 | if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } 42 | if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } 43 | if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } 44 | if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } 45 | if (t[2]) _.ops.pop(); 46 | _.trys.pop(); continue; 47 | } 48 | op = body.call(thisArg, _); 49 | } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } 50 | if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; 51 | } 52 | }; 53 | Object.defineProperty(exports, "__esModule", { value: true }); 54 | var hardhat_1 = require("hardhat"); 55 | var getPoolId_1 = require("../src/helpers/getPoolId"); 56 | function main() { 57 | return __awaiter(this, void 0, void 0, function () { 58 | var signer, poolID; 59 | return __generator(this, function (_a) { 60 | switch (_a.label) { 61 | case 0: return [4 /*yield*/, hardhat_1.ethers.getSigners()]; 62 | case 1: 63 | signer = (_a.sent())[0]; 64 | return [4 /*yield*/, (0, getPoolId_1.getPoolId)("0x9eB7F54C0eCc4d0D2dfF28a1276e36d598F2B0D1", signer)]; 65 | case 2: 66 | poolID = _a.sent(); 67 | console.log("Pool ID: " + poolID); 68 | return [4 /*yield*/, (0, getPoolId_1.getPoolId)("0xD75bfF2444FF738d443066ff4688691e6852b217", signer)]; 69 | case 3: 70 | poolID = _a.sent(); 71 | console.log("Pool ID: " + poolID); 72 | return [4 /*yield*/, (0, getPoolId_1.getPoolId)("0x5941DB4d6C500C4FFa57c359eE0C55c6b41D0b61", signer)]; 73 | case 4: 74 | poolID = _a.sent(); 75 | console.log("Pool ID: " + poolID); 76 | return [4 /*yield*/, (0, getPoolId_1.getPoolId)("0xcF6894C48c2AF3ddD433CC1EDfEfC74e654cC9B4", signer)]; 77 | case 5: 78 | poolID = _a.sent(); 79 | console.log("Pool ID: " + poolID); 80 | return [2 /*return*/]; 81 | } 82 | }); 83 | }); 84 | } 85 | main(); 86 | -------------------------------------------------------------------------------- /dist/examples/swap.d.ts: -------------------------------------------------------------------------------- 1 | export {}; 2 | -------------------------------------------------------------------------------- /dist/examples/tvl.d.ts: -------------------------------------------------------------------------------- 1 | export {}; 2 | -------------------------------------------------------------------------------- /dist/hardhat.config.d.ts: -------------------------------------------------------------------------------- 1 | import "@nomiclabs/hardhat-waffle"; 2 | import "hardhat-typechain"; 3 | import "hardhat-gas-reporter"; 4 | import { HardhatUserConfig } from "hardhat/config"; 5 | declare const config: HardhatUserConfig; 6 | export default config; 7 | -------------------------------------------------------------------------------- /dist/hardhat.config.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | require("@nomiclabs/hardhat-waffle"); 4 | require("hardhat-typechain"); 5 | require("hardhat-gas-reporter"); 6 | var MAINNET_PROVIDER_URL = process.env.MAINNET_PROVIDER_URL || ""; 7 | var GOERLI_PROVIDER_URL = process.env.GOERLI_PROVIDER_URL || ""; 8 | var PRIVATE_KEY = process.env.PRIVATE_KEY || 9 | "0000000000000000000000000000000000000000000000000000000000000000"; 10 | var config = { 11 | defaultNetwork: "hardhat", 12 | solidity: { 13 | compilers: [ 14 | { 15 | version: "0.7.1", 16 | settings: { 17 | optimizer: { 18 | enabled: true, 19 | runs: 10000, 20 | }, 21 | }, 22 | }, 23 | { 24 | version: "0.8.0", 25 | settings: { 26 | optimizer: { 27 | enabled: true, 28 | runs: 7500, 29 | }, 30 | }, 31 | }, 32 | ], 33 | overrides: { 34 | "contracts/balancer-core-v2/vault/Vault.sol": { 35 | version: "0.7.1", 36 | settings: { 37 | optimizer: { 38 | enabled: true, 39 | runs: 400, 40 | }, 41 | }, 42 | }, 43 | "contracts/balancer-core-v2/pools/weighted/WeightedPoolFactory.sol": { 44 | version: "0.7.1", 45 | settings: { 46 | optimizer: { 47 | enabled: true, 48 | runs: 800, 49 | }, 50 | }, 51 | }, 52 | }, 53 | }, 54 | mocha: { timeout: 0 }, 55 | networks: { 56 | goerli: { 57 | url: "" + GOERLI_PROVIDER_URL, 58 | accounts: ["0x" + PRIVATE_KEY], 59 | }, 60 | mainnet: { 61 | url: "" + MAINNET_PROVIDER_URL, 62 | accounts: ["0x" + PRIVATE_KEY], 63 | }, 64 | hardhat: { 65 | forking: { 66 | url: "https://eth-mainnet.alchemyapi.io/v2/kwjMP-X-Vajdk1ItCfU-56Uaq1wwhamK", 67 | blockNumber: 13475006, 68 | }, 69 | }, 70 | }, 71 | }; 72 | exports.default = config; 73 | -------------------------------------------------------------------------------- /dist/src/constants/time.d.ts: -------------------------------------------------------------------------------- 1 | export declare const ONE_MINUTE_IN_SECONDS = 60; 2 | export declare const ONE_HOUR_IN_SECONDS: number; 3 | export declare const ONE_DAY_IN_SECONDS: number; 4 | export declare const ONE_WEEK_IN_SECONDS: number; 5 | export declare const THIRTY_DAYS_IN_SECONDS: number; 6 | export declare const SIX_MONTHS_IN_SECONDS: number; 7 | export declare const ONE_YEAR_IN_SECONDS: number; 8 | export declare const ONE_MINUTE_IN_MILLISECONDS: number; 9 | export declare const ONE_HOUR_IN_MILLISECONDS: number; 10 | export declare const ONE_DAY_IN_MILLISECONDS: number; 11 | export declare const ONE_WEEK_IN_MILLISECONDS: number; 12 | export declare const ONE_YEAR_IN_MILLISECONDS: number; 13 | export declare const THIRTY_DAYS_IN_MILLISECONDS: number; 14 | -------------------------------------------------------------------------------- /dist/src/constants/time.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | /* 3 | * Copyright 2021 Element Finance, Inc 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | Object.defineProperty(exports, "__esModule", { value: true }); 18 | exports.THIRTY_DAYS_IN_MILLISECONDS = exports.ONE_YEAR_IN_MILLISECONDS = exports.ONE_WEEK_IN_MILLISECONDS = exports.ONE_DAY_IN_MILLISECONDS = exports.ONE_HOUR_IN_MILLISECONDS = exports.ONE_MINUTE_IN_MILLISECONDS = exports.ONE_YEAR_IN_SECONDS = exports.SIX_MONTHS_IN_SECONDS = exports.THIRTY_DAYS_IN_SECONDS = exports.ONE_WEEK_IN_SECONDS = exports.ONE_DAY_IN_SECONDS = exports.ONE_HOUR_IN_SECONDS = exports.ONE_MINUTE_IN_SECONDS = void 0; 19 | exports.ONE_MINUTE_IN_SECONDS = 60; 20 | exports.ONE_HOUR_IN_SECONDS = 60 * exports.ONE_MINUTE_IN_SECONDS; 21 | exports.ONE_DAY_IN_SECONDS = 24 * exports.ONE_HOUR_IN_SECONDS; 22 | exports.ONE_WEEK_IN_SECONDS = 7 * exports.ONE_DAY_IN_SECONDS; 23 | exports.THIRTY_DAYS_IN_SECONDS = 30 * exports.ONE_DAY_IN_SECONDS; 24 | exports.SIX_MONTHS_IN_SECONDS = 26 * exports.ONE_WEEK_IN_SECONDS; 25 | exports.ONE_YEAR_IN_SECONDS = 365 * exports.ONE_DAY_IN_SECONDS; 26 | exports.ONE_MINUTE_IN_MILLISECONDS = 1000 * exports.ONE_MINUTE_IN_SECONDS; 27 | exports.ONE_HOUR_IN_MILLISECONDS = 60 * exports.ONE_MINUTE_IN_MILLISECONDS; 28 | exports.ONE_DAY_IN_MILLISECONDS = 24 * exports.ONE_HOUR_IN_MILLISECONDS; 29 | exports.ONE_WEEK_IN_MILLISECONDS = 7 * exports.ONE_DAY_IN_MILLISECONDS; 30 | exports.ONE_YEAR_IN_MILLISECONDS = 365 * exports.ONE_DAY_IN_MILLISECONDS; 31 | exports.THIRTY_DAYS_IN_MILLISECONDS = 30 * exports.ONE_DAY_IN_MILLISECONDS; 32 | -------------------------------------------------------------------------------- /dist/src/exitPool.d.ts: -------------------------------------------------------------------------------- 1 | import { BigNumber, ContractTransaction, Signer } from "ethers"; 2 | /** 3 | * Remove liquidity from a ConvergentCurvePool. 4 | * @param signer Who is authorizing the transaction 5 | * @param poolId Balancer V2 PoolId 6 | * @param senderAddress who is returning LP token to the pool 7 | * @param receipientAddress who is receiving assets from the pool 8 | * @param vaultAddress Balancer V2 Vault address 9 | * @param tokens tokens to withdraw, note: sorted alphanumerically. ETH must be sorted as though it 10 | * were WETH. 11 | * @param minAmountsOut minimum amounts to withdraw, same order as tokens. The minimum amounts can 12 | * be set to ensure slippage tolerance. 13 | * @param fromInternalBalance Use the sender's Balancer V2 internal balance first, if available. 14 | * @returns returns the contract transaction. 15 | */ 16 | export declare function exitConvergentPool( 17 | signer: Signer, 18 | poolId: string, 19 | senderAddress: string, 20 | receipientAddress: string, 21 | vaultAddress: string, 22 | tokens: string[], 23 | minAmountsOut: BigNumber[], 24 | toInternalBalance?: boolean 25 | ): Promise; 26 | export declare enum WeightedPoolExitKind { 27 | EXACT_BPT_IN_FOR_ONE_TOKEN_OUT = 0, 28 | EXACT_BPT_IN_FOR_TOKENS_OUT = 1, 29 | BPT_IN_FOR_EXACT_TOKENS_OUT = 2, 30 | } 31 | /** 32 | * Remove liquidity from a WeightedPool. 33 | * @param signer Who is authorizing the transaction 34 | * @param poolId Balancer V2 PoolId 35 | * @param senderAddress who is returning LP token to the pool 36 | * @param receipientAddress who is receiving assets from the pool 37 | * @param vaultAddress Balancer V2 Vault address 38 | * @param tokens tokens to withdraw, note: sorted alphanumerically. ETH must be sorted as though it 39 | * were WETH. 40 | * @param minAmountsOut minimum amounts to withdraw, same order as tokens. The minimum amounts can 41 | * be set to ensure slippage tolerance. 42 | * @param fromInternalBalance Use the sender's Balancer V2 internal balance first, if available. 43 | * @param exitKind The exit operation 44 | * @param maxBPTIn The amount, or max amount of Balancer Pool Token in, depending on the exitKind. 45 | * @param tokenIndex If withdrawing a single token, the index of the token in tokens 46 | * @returns returns the contract transaction. 47 | */ 48 | export declare function exitWeightedPool( 49 | signer: Signer, 50 | poolId: string, 51 | senderAddress: string, 52 | receipientAddress: string, 53 | vaultAddress: string, 54 | tokens: string[], 55 | minAmountsOut: BigNumber[], 56 | toInternalBalance: boolean | undefined, 57 | exitKind: WeightedPoolExitKind | undefined, 58 | maxBPTIn: BigNumber, 59 | tokenIndex?: number 60 | ): Promise; 61 | -------------------------------------------------------------------------------- /dist/src/helpers/calcFixedAPR.d.ts: -------------------------------------------------------------------------------- 1 | export declare function calcFixedAPR( 2 | spotPrice: number, 3 | secondsUntilMaturity: number 4 | ): number; 5 | -------------------------------------------------------------------------------- /dist/src/helpers/calcFixedAPR.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | /* 3 | * Copyright 2021 Element Finance, Inc 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | Object.defineProperty(exports, "__esModule", { value: true }); 18 | exports.calcFixedAPR = void 0; 19 | var time_1 = require("../../src/constants/time"); 20 | function calcFixedAPR(spotPrice, secondsUntilMaturity) { 21 | if (secondsUntilMaturity > 0) { 22 | var timeRemaining = secondsUntilMaturity / time_1.ONE_YEAR_IN_SECONDS; 23 | return ((1 - spotPrice) / timeRemaining) * 100; 24 | } 25 | else { 26 | return 0; 27 | } 28 | } 29 | exports.calcFixedAPR = calcFixedAPR; 30 | -------------------------------------------------------------------------------- /dist/src/helpers/calcPoolSwap.d.ts: -------------------------------------------------------------------------------- 1 | export declare function calcSwapOutGivenInCCPoolUnsafe( 2 | xAmount: string, 3 | xReserves: string, 4 | yReserves: string, 5 | totalSupply: string, 6 | timeRemainingSeconds: number, 7 | tParamSeconds: number, 8 | baseAssetIn: boolean 9 | ): number; 10 | export declare function calcSwapInGivenOutCCPoolUnsafe( 11 | xAmount: string, 12 | xReserves: string, 13 | yReserves: string, 14 | totalSupply: string, 15 | timeRemainingSeconds: number, 16 | tParamSeconds: number, 17 | baseAssetIn: boolean 18 | ): number; 19 | /********************************************************************************************** 20 | // outGivenIn // 21 | // aO = amountOut // 22 | // bO = balanceOut // 23 | // bI = balanceIn / / bI \ (wI / wO) \ // 24 | // aI = amountIn aO = bO * | 1 - | -------------------------- | ^ | // 25 | // wI = weightIn \ \ ( bI + aI ) / / // 26 | // wO = weightOut // 27 | **********************************************************************************************/ 28 | export declare function calcSwapOutGivenInWeightedPoolUnsafe( 29 | amountIn: string, 30 | balanceOut: string, 31 | balanceIn: string 32 | ): number; 33 | /********************************************************************************************** 34 | // inGivenOut // 35 | // aO = amountOut // 36 | // bO = balanceOut // 37 | // bI = balanceIn / / bO \ (wO / wI) \ // 38 | // aI = amountIn aI = bI * | | -------------------------- | ^ - 1 | // 39 | // wI = weightIn \ \ ( bO - aO ) / / // 40 | // wO = weightOut // 41 | **********************************************************************************************/ 42 | export declare function calcSwapInGivenOutWeightedPoolUnsafe( 43 | amountOut: string, 44 | balanceOut: string, 45 | balanceIn: string 46 | ): number; 47 | -------------------------------------------------------------------------------- /dist/src/helpers/calcPoolSwap.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | /* 3 | * Copyright 2021 Element Finance, Inc 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | Object.defineProperty(exports, "__esModule", { value: true }); 18 | exports.calcSwapInGivenOutWeightedPoolUnsafe = exports.calcSwapOutGivenInWeightedPoolUnsafe = exports.calcSwapInGivenOutCCPoolUnsafe = exports.calcSwapOutGivenInCCPoolUnsafe = void 0; 19 | function calcSwapOutGivenInCCPoolUnsafe(xAmount, xReserves, yReserves, totalSupply, timeRemainingSeconds, tParamSeconds, baseAssetIn) { 20 | var tS = +totalSupply; 21 | var amountX = +xAmount; 22 | var xR = +xReserves + tS; 23 | var yR = +yReserves; 24 | if (baseAssetIn) { 25 | xR = +xReserves; 26 | yR = +yReserves + tS; 27 | } 28 | var t = timeRemainingSeconds / tParamSeconds; 29 | var xBefore = Math.pow(xR, (1 - t)); 30 | var yBefore = Math.pow(yR, (1 - t)); 31 | var xAfter = Math.pow((xR + amountX), (1 - t)); 32 | // this is the real equation, make ascii art for it 33 | var yAfter = Math.pow((xBefore + yBefore - xAfter), (1 / (1 - t))); 34 | var amountY = yR - yAfter; 35 | return amountY; 36 | } 37 | exports.calcSwapOutGivenInCCPoolUnsafe = calcSwapOutGivenInCCPoolUnsafe; 38 | function calcSwapInGivenOutCCPoolUnsafe(xAmount, xReserves, yReserves, totalSupply, timeRemainingSeconds, tParamSeconds, baseAssetIn) { 39 | var tS = +totalSupply; 40 | var amountX = +xAmount; 41 | var xR = +xReserves + tS; 42 | var yR = +yReserves; 43 | if (baseAssetIn) { 44 | xR = +xReserves; 45 | yR = +yReserves + tS; 46 | } 47 | var t = timeRemainingSeconds / tParamSeconds; 48 | var xBefore = Math.pow(xR, (1 - t)); 49 | var yBefore = Math.pow(yR, (1 - t)); 50 | var xAfter = Math.pow((xR - amountX), (1 - t)); 51 | // this is the real equation, make ascii art for it 52 | var yAfter = Math.pow((xBefore + yBefore - xAfter), (1 / (1 - t))); 53 | var amountY = yAfter - yR; 54 | return amountY; 55 | } 56 | exports.calcSwapInGivenOutCCPoolUnsafe = calcSwapInGivenOutCCPoolUnsafe; 57 | // Computes how many tokens can be taken out of a pool if `amountIn` are sent, given the current 58 | // balances and weights. In our case the weights are the same so we don't need to add them to our 59 | // calcs 60 | /********************************************************************************************** 61 | // outGivenIn // 62 | // aO = amountOut // 63 | // bO = balanceOut // 64 | // bI = balanceIn / / bI \ (wI / wO) \ // 65 | // aI = amountIn aO = bO * | 1 - | -------------------------- | ^ | // 66 | // wI = weightIn \ \ ( bI + aI ) / / // 67 | // wO = weightOut // 68 | **********************************************************************************************/ 69 | function calcSwapOutGivenInWeightedPoolUnsafe(amountIn, balanceOut, balanceIn) { 70 | var aI = +amountIn; 71 | var bO = +balanceOut; 72 | var bI = +balanceIn; 73 | var amountOut = bO * (1 - bI / (bI + aI)); 74 | return amountOut; 75 | } 76 | exports.calcSwapOutGivenInWeightedPoolUnsafe = calcSwapOutGivenInWeightedPoolUnsafe; 77 | // Computes how many tokens must be sent to a pool in order to take `amountOut`, given the current 78 | // balances and weights. In our case the weights are the same so we don't need to add them to our 79 | // calcs. 80 | /********************************************************************************************** 81 | // inGivenOut // 82 | // aO = amountOut // 83 | // bO = balanceOut // 84 | // bI = balanceIn / / bO \ (wO / wI) \ // 85 | // aI = amountIn aI = bI * | | -------------------------- | ^ - 1 | // 86 | // wI = weightIn \ \ ( bO - aO ) / / // 87 | // wO = weightOut // 88 | **********************************************************************************************/ 89 | function calcSwapInGivenOutWeightedPoolUnsafe(amountOut, balanceOut, balanceIn) { 90 | var aO = +amountOut; 91 | var bO = +balanceOut; 92 | var bI = +balanceIn; 93 | var amountIn = bI * (bO / (bO - aO) - 1); 94 | return amountIn; 95 | } 96 | exports.calcSwapInGivenOutWeightedPoolUnsafe = calcSwapInGivenOutWeightedPoolUnsafe; 97 | -------------------------------------------------------------------------------- /dist/src/helpers/calcSpotPrice.d.ts: -------------------------------------------------------------------------------- 1 | export declare function calcSpotPricePt( 2 | baseReserves: string, 3 | ptReserves: string, 4 | totalSupply: string, 5 | timeRemainingSeconds: number, 6 | tParamSeconds: number, 7 | decimals: number 8 | ): number; 9 | export declare function calcSpotPriceYt( 10 | baseReserves: string, 11 | ytReserves: string 12 | ): number; 13 | -------------------------------------------------------------------------------- /dist/src/helpers/calcSpotPrice.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | /* 3 | * Copyright 2021 Element Finance, Inc 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | Object.defineProperty(exports, "__esModule", { value: true }); 18 | exports.calcSpotPriceYt = exports.calcSpotPricePt = void 0; 19 | function calcSpotPricePt(baseReserves, ptReserves, totalSupply, timeRemainingSeconds, tParamSeconds, decimals) { 20 | // normalize decimal places of precision to 18 21 | if (decimals < 0 || decimals > 18) { 22 | // return 0 if decimals fall outside the range between 0 and 18 23 | return 0; 24 | } 25 | var diff = 18 - decimals; 26 | var normalizedBaseReserves = +baseReserves * Math.pow(10, diff); 27 | var normalizedPtReserves = +ptReserves * Math.pow(10, diff); 28 | var t = timeRemainingSeconds / tParamSeconds; 29 | return Math.pow((normalizedBaseReserves / (normalizedPtReserves + +totalSupply)), t); 30 | } 31 | exports.calcSpotPricePt = calcSpotPricePt; 32 | function calcSpotPriceYt(baseReserves, ytReserves) { 33 | return +baseReserves / +ytReserves; 34 | } 35 | exports.calcSpotPriceYt = calcSpotPriceYt; 36 | -------------------------------------------------------------------------------- /dist/src/helpers/calcTotalValueLocked.d.ts: -------------------------------------------------------------------------------- 1 | import { Money } from "ts-money"; 2 | import { TokenInfo } from "@uniswap/token-lists"; 3 | import { Signer, BigNumber } from "ethers"; 4 | import { Provider } from "@ethersproject/providers"; 5 | import { 6 | ERC20, 7 | ERC20Permit, 8 | WETH, 9 | DAI, 10 | } from "elf-contracts-typechain/dist/types"; 11 | import { 12 | PrincipalTokenInfo, 13 | YieldPoolTokenInfo, 14 | PrincipalPoolTokenInfo, 15 | AssetProxyTokenInfo, 16 | AnyTokenListInfo, 17 | } from "elf-tokenlist"; 18 | /** 19 | * Calculate the TVL 20 | * @param chainName 21 | * @param signerOrProvider 22 | * @returns TVL 23 | */ 24 | export declare function calcTotalValueLocked( 25 | chainName: string, 26 | signerOrProvider: Signer | Provider 27 | ): Promise; 28 | /** 29 | * Calculate the TVL for a term 30 | * @param trancheInfo 31 | * @param balancerVaultAddress 32 | * @param underlyingContractsByAddress 33 | * @param assetProxyTokenInfos 34 | * @param tokenInfos 35 | * @param tokenInfoByAddress 36 | * @param baseAssetPrice 37 | * @param signerOrProvider 38 | * @returns TVL for term 39 | */ 40 | export declare function calcTotalValueLockedForTerm( 41 | trancheInfo: PrincipalTokenInfo, 42 | balancerVaultAddress: string, 43 | underlyingContractsByAddress: Record< 44 | string, 45 | ERC20 | WETH | DAI | ERC20Permit 46 | >, 47 | assetProxyTokenInfos: AssetProxyTokenInfo[], 48 | tokenInfos: TokenInfo[], 49 | tokenInfoByAddress: Record, 50 | baseAssetPrice: Money, 51 | signerOrProvider: Signer | Provider 52 | ): Promise; 53 | /** 54 | * Return the accumulated interest for a term 55 | * @param poolInfo 56 | * @param assetProxyTokenInfos 57 | * @param tokenInfos 58 | * @param signerOrProvider 59 | * @returns accumulated interest 60 | */ 61 | export declare function getAccumulatedInterestForTranche( 62 | poolInfo: YieldPoolTokenInfo | PrincipalPoolTokenInfo, 63 | assetProxyTokenInfos: AssetProxyTokenInfo[], 64 | tokenInfos: TokenInfo[], 65 | signerOrProvider: Signer | Provider 66 | ): Promise; 67 | /** 68 | * Return the base asset reserves in a pool 69 | * @param poolInfo 70 | * @param balancerVaultAddress 71 | * @param tokenInfoByAddress 72 | * @param underlyingContractsByAddress 73 | * @param signerOrProvider 74 | * @returns number representing the base assets 75 | */ 76 | export declare function getBaseAssetReservesInPool( 77 | poolInfo: YieldPoolTokenInfo | PrincipalPoolTokenInfo, 78 | balancerVaultAddress: string, 79 | tokenInfoByAddress: Record, 80 | underlyingContractsByAddress: Record< 81 | string, 82 | ERC20 | WETH | DAI | ERC20Permit 83 | >, 84 | signerOrProvider: Signer | Provider 85 | ): Promise; 86 | interface PoolTokens { 87 | baseAssetInfo: TokenInfo; 88 | termAssetInfo: TokenInfo; 89 | baseAssetContract: ERC20; 90 | termAssetContract: ERC20; 91 | baseAssetIndex: number; 92 | termAssetIndex: number; 93 | sortedAddresses: [string, string]; 94 | } 95 | /** 96 | * Get the tokens in the pool corresponding to ther poolInfo 97 | * @param poolInfo 98 | * @param tokenInfoByAddress 99 | * @param underlyingContractsByAddress 100 | * @param signerOrProvider 101 | * @returns PoolTokens 102 | */ 103 | export declare function getPoolTokens( 104 | poolInfo: YieldPoolTokenInfo | PrincipalPoolTokenInfo, 105 | tokenInfoByAddress: Record, 106 | underlyingContractsByAddress: Record< 107 | string, 108 | ERC20 | WETH | DAI | ERC20Permit 109 | >, 110 | signerOrProvider: Signer | Provider 111 | ): PoolTokens; 112 | export {}; 113 | -------------------------------------------------------------------------------- /dist/src/helpers/calcTvl.d.ts: -------------------------------------------------------------------------------- 1 | import { Money } from "ts-money"; 2 | import { TokenInfo } from "@uniswap/token-lists"; 3 | import { Signer, BigNumber } from "ethers"; 4 | import { Provider } from "@ethersproject/providers"; 5 | import { WeightedPool } from "elf-contracts-typechain/dist/types/WeightedPool"; 6 | import { 7 | ERC20, 8 | ERC20Permit, 9 | WETH, 10 | DAI, 11 | } from "elf-contracts-typechain/dist/types"; 12 | import { 13 | PrincipalTokenInfo, 14 | YieldPoolTokenInfo, 15 | PrincipalPoolTokenInfo, 16 | AssetProxyTokenInfo, 17 | AnyTokenListInfo, 18 | } from "elf-tokenlist"; 19 | export declare function getPoolForYieldToken( 20 | yieldTokenAddress: string, 21 | YieldPoolTokenInfos: YieldPoolTokenInfo[], 22 | signerOrProvider: Signer | Provider 23 | ): WeightedPool; 24 | export declare function useTotalValueLockedForPlatform( 25 | chainName: string, 26 | signerOrProvider: Signer | Provider 27 | ): Promise; 28 | export declare function fetchTotalValueLockedForTerm( 29 | trancheInfo: PrincipalTokenInfo, 30 | balancerVaultAddress: string, 31 | underlyingContractsByAddress: Record< 32 | string, 33 | ERC20 | WETH | DAI | ERC20Permit 34 | >, 35 | assetProxyTokenInfos: AssetProxyTokenInfo[], 36 | tokenInfos: TokenInfo[], 37 | tokenInfoByAddress: Record, 38 | baseAssetPrice: Money, 39 | signerOrProvider: Signer | Provider 40 | ): Promise; 41 | export declare function fetchAccumulatedInterestForTranche( 42 | poolInfo: YieldPoolTokenInfo | PrincipalPoolTokenInfo, 43 | assetProxyTokenInfos: AssetProxyTokenInfo[], 44 | tokenInfos: TokenInfo[], 45 | signerOrProvider: Signer | Provider 46 | ): Promise; 47 | export declare function fetchBaseAssetReservesInPool( 48 | poolInfo: YieldPoolTokenInfo | PrincipalPoolTokenInfo, 49 | balancerVaultAddress: string, 50 | tokenInfoByAddress: Record, 51 | underlyingContractsByAddress: Record< 52 | string, 53 | ERC20 | WETH | DAI | ERC20Permit 54 | >, 55 | signerOrProvider: Signer | Provider 56 | ): Promise; 57 | interface PoolTokens { 58 | baseAssetInfo: TokenInfo; 59 | termAssetInfo: TokenInfo; 60 | baseAssetContract: ERC20; 61 | termAssetContract: ERC20; 62 | baseAssetIndex: number; 63 | termAssetIndex: number; 64 | sortedAddresses: [string, string]; 65 | } 66 | export declare function getPoolTokens( 67 | poolInfo: YieldPoolTokenInfo | PrincipalPoolTokenInfo, 68 | tokenInfoByAddress: Record, 69 | underlyingContractsByAddress: Record< 70 | string, 71 | ERC20 | WETH | DAI | ERC20Permit 72 | >, 73 | signerOrProvider: Signer | Provider 74 | ): PoolTokens; 75 | export {}; 76 | -------------------------------------------------------------------------------- /dist/src/helpers/getElementAddresses.d.ts: -------------------------------------------------------------------------------- 1 | import { DeploymentAddresses } from "typechain/DeploymentAddresses"; 2 | export declare enum PoolType { 3 | PT = 0, 4 | YT = 1, 5 | } 6 | /** 7 | * Get the contract addresses deployed by Element 8 | * @param url The url of the json changelog file 9 | * @returns A Promise for the DeploymentAddresses object 10 | */ 11 | export declare function getElementDeploymentAddresses( 12 | url: string 13 | ): Promise; 14 | /** 15 | * Get TermFactory addresses associated with each term 16 | * @param deploymentAddresses The DeploymentAddresses object 17 | * @returns the TermFactory used to deploy each individual term 18 | */ 19 | export declare function getElementTermFactoryAddresses( 20 | deploymentAddresses: DeploymentAddresses 21 | ): string[]; 22 | /** 23 | * Get Element Term addresses 24 | * @param deploymentAddresses The DeploymentAddresses object 25 | * @returns An array of Term addresses 26 | */ 27 | export declare function getElementTermAddresses( 28 | deploymentAddresses: DeploymentAddresses 29 | ): string[]; 30 | /** 31 | * Get PtPool addresses associated with each term 32 | * @param deploymentAddresses The DeploymentAddresses object 33 | * @returns An array of PT Pool addresses 34 | */ 35 | export declare function getElementPtPoolAddresses( 36 | deploymentAddresses: DeploymentAddresses 37 | ): string[]; 38 | /** 39 | * Get PtPool addresses associated with each term 40 | * @param deploymentAddresses The DeploymentAddresses object 41 | * @returns An array of YT Pool addresses 42 | */ 43 | export declare function getElementYtPoolAddresses( 44 | deploymentAddresses: DeploymentAddresses 45 | ): string[]; 46 | /** 47 | * Returns the PoolId from the DeploymentAddresses that matches a termAddress 48 | * @param termAddress termAddress to filter on 49 | * @param deploymentAddresses The DeploymentAddresses object 50 | * @param PoolType Either PT or YT 51 | * @returns a promise for a poolId 52 | */ 53 | export declare function getPoolIdByTermAddress( 54 | termAddress: string, 55 | deploymentAddresses: DeploymentAddresses, 56 | poolType: PoolType 57 | ): Promise; 58 | /** 59 | * Get base address for a given token 60 | * @param deploymentAddresses The Deployment Addresses object 61 | * @param tokenKey 62 | * @returns The base address 63 | */ 64 | export declare function getBaseTokenAddress( 65 | deploymentAddresses: DeploymentAddresses, 66 | tokenKey: string 67 | ): string; 68 | -------------------------------------------------------------------------------- /dist/src/helpers/getLatestBlockTimestamp.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Get timestamp of the latest block 3 | * @returns the timestamp of the latest block 4 | */ 5 | export declare function getLatestBlockTimestamp(): Promise; 6 | -------------------------------------------------------------------------------- /dist/src/helpers/getLatestBlockTimestamp.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | /* 3 | * Copyright 2021 Element Finance, Inc 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 18 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 19 | return new (P || (P = Promise))(function (resolve, reject) { 20 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 21 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 22 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 23 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 24 | }); 25 | }; 26 | var __generator = (this && this.__generator) || function (thisArg, body) { 27 | var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; 28 | return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; 29 | function verb(n) { return function (v) { return step([n, v]); }; } 30 | function step(op) { 31 | if (f) throw new TypeError("Generator is already executing."); 32 | while (_) try { 33 | if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; 34 | if (y = 0, t) op = [op[0] & 2, t.value]; 35 | switch (op[0]) { 36 | case 0: case 1: t = op; break; 37 | case 4: _.label++; return { value: op[1], done: false }; 38 | case 5: _.label++; y = op[1]; op = [0]; continue; 39 | case 7: op = _.ops.pop(); _.trys.pop(); continue; 40 | default: 41 | if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } 42 | if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } 43 | if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } 44 | if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } 45 | if (t[2]) _.ops.pop(); 46 | _.trys.pop(); continue; 47 | } 48 | op = body.call(thisArg, _); 49 | } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } 50 | if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; 51 | } 52 | }; 53 | Object.defineProperty(exports, "__esModule", { value: true }); 54 | exports.getLatestBlockTimestamp = void 0; 55 | var ethers_1 = require("ethers"); 56 | /** 57 | * Get timestamp of the latest block 58 | * @returns the timestamp of the latest block 59 | */ 60 | function getLatestBlockTimestamp() { 61 | return __awaiter(this, void 0, void 0, function () { 62 | var provider, blockNumber, block; 63 | return __generator(this, function (_a) { 64 | switch (_a.label) { 65 | case 0: 66 | provider = ethers_1.providers.getDefaultProvider(); 67 | return [4 /*yield*/, provider.getBlockNumber()]; 68 | case 1: 69 | blockNumber = _a.sent(); 70 | return [4 /*yield*/, provider.getBlock(blockNumber)]; 71 | case 2: 72 | block = _a.sent(); 73 | return [2 /*return*/, block.timestamp]; 74 | } 75 | }); 76 | }); 77 | } 78 | exports.getLatestBlockTimestamp = getLatestBlockTimestamp; 79 | -------------------------------------------------------------------------------- /dist/src/helpers/getOpenTerms.d.ts: -------------------------------------------------------------------------------- 1 | import { Provider } from "@ethersproject/providers"; 2 | import { Signer } from "ethers"; 3 | /** 4 | * Returns an array of not expired tranche addresses. 5 | * 6 | * @param trancheFactoryAddress The TrancheFactory that deployed the tranches 7 | * @returns a promise of an array of tranche addresses 8 | */ 9 | export declare function getOpenTerms( 10 | trancheFactoryAddress: string, 11 | signerOrProvider: Signer | Provider 12 | ): Promise; 13 | -------------------------------------------------------------------------------- /dist/src/helpers/getOpenTerms.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 3 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 4 | return new (P || (P = Promise))(function (resolve, reject) { 5 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 6 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 7 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 8 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 9 | }); 10 | }; 11 | var __generator = (this && this.__generator) || function (thisArg, body) { 12 | var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; 13 | return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; 14 | function verb(n) { return function (v) { return step([n, v]); }; } 15 | function step(op) { 16 | if (f) throw new TypeError("Generator is already executing."); 17 | while (_) try { 18 | if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; 19 | if (y = 0, t) op = [op[0] & 2, t.value]; 20 | switch (op[0]) { 21 | case 0: case 1: t = op; break; 22 | case 4: _.label++; return { value: op[1], done: false }; 23 | case 5: _.label++; y = op[1]; op = [0]; continue; 24 | case 7: op = _.ops.pop(); _.trys.pop(); continue; 25 | default: 26 | if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } 27 | if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } 28 | if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } 29 | if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } 30 | if (t[2]) _.ops.pop(); 31 | _.trys.pop(); continue; 32 | } 33 | op = body.call(thisArg, _); 34 | } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } 35 | if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; 36 | } 37 | }; 38 | Object.defineProperty(exports, "__esModule", { value: true }); 39 | exports.getOpenTerms = void 0; 40 | var elf_contracts_typechain_1 = require("elf-contracts-typechain"); 41 | var getLatestBlockTimestamp_1 = require("./getLatestBlockTimestamp"); 42 | /** 43 | * Returns an array of not expired tranche addresses. 44 | * 45 | * @param trancheFactoryAddress The TrancheFactory that deployed the tranches 46 | * @returns a promise of an array of tranche addresses 47 | */ 48 | function getOpenTerms(trancheFactoryAddress, signerOrProvider) { 49 | return __awaiter(this, void 0, void 0, function () { 50 | var trancheFactoryContract, queryFilter, trancheEvents, timestamp, notExpiredTranches; 51 | return __generator(this, function (_a) { 52 | switch (_a.label) { 53 | case 0: 54 | trancheFactoryContract = elf_contracts_typechain_1.TrancheFactory__factory.connect(trancheFactoryAddress, signerOrProvider); 55 | queryFilter = trancheFactoryContract.filters.TrancheCreated(null, null, null); 56 | return [4 /*yield*/, trancheFactoryContract.queryFilter(queryFilter)]; 57 | case 1: 58 | trancheEvents = _a.sent(); 59 | return [4 /*yield*/, (0, getLatestBlockTimestamp_1.getLatestBlockTimestamp)()]; 60 | case 2: 61 | timestamp = _a.sent(); 62 | notExpiredTranches = trancheEvents 63 | .filter(function (event) { var _a; return ((_a = event.args) === null || _a === void 0 ? void 0 : _a.expiration.toNumber()) > timestamp; }) 64 | .map(function (event) { var _a; return (_a = event.args) === null || _a === void 0 ? void 0 : _a.trancheAddress; }); 65 | return [2 /*return*/, notExpiredTranches]; 66 | } 67 | }); 68 | }); 69 | } 70 | exports.getOpenTerms = getOpenTerms; 71 | -------------------------------------------------------------------------------- /dist/src/helpers/getPoolId.d.ts: -------------------------------------------------------------------------------- 1 | import { Signer } from "ethers"; 2 | import { Provider } from "@ethersproject/providers"; 3 | /** 4 | * Returns the PoolId for a given pool. 5 | * @param poolAddress any pool with a getPoolId method 6 | * @param signerOrProvider 7 | * @returns a promise for a poolId 8 | */ 9 | export declare function getPoolId( 10 | poolAddress: string, 11 | signerOrProvider: Signer | Provider 12 | ): Promise; 13 | -------------------------------------------------------------------------------- /dist/src/helpers/getPoolId.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | /* 3 | * Copyright 2021 Element Finance, Inc 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 18 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 19 | return new (P || (P = Promise))(function (resolve, reject) { 20 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 21 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 22 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 23 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 24 | }); 25 | }; 26 | var __generator = (this && this.__generator) || function (thisArg, body) { 27 | var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; 28 | return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; 29 | function verb(n) { return function (v) { return step([n, v]); }; } 30 | function step(op) { 31 | if (f) throw new TypeError("Generator is already executing."); 32 | while (_) try { 33 | if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; 34 | if (y = 0, t) op = [op[0] & 2, t.value]; 35 | switch (op[0]) { 36 | case 0: case 1: t = op; break; 37 | case 4: _.label++; return { value: op[1], done: false }; 38 | case 5: _.label++; y = op[1]; op = [0]; continue; 39 | case 7: op = _.ops.pop(); _.trys.pop(); continue; 40 | default: 41 | if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } 42 | if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } 43 | if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } 44 | if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } 45 | if (t[2]) _.ops.pop(); 46 | _.trys.pop(); continue; 47 | } 48 | op = body.call(thisArg, _); 49 | } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } 50 | if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; 51 | } 52 | }; 53 | Object.defineProperty(exports, "__esModule", { value: true }); 54 | exports.getPoolId = void 0; 55 | var elf_contracts_typechain_1 = require("elf-contracts-typechain"); 56 | /** 57 | * Returns the PoolId for a given pool. 58 | * @param poolAddress any pool with a getPoolId method 59 | * @param signerOrProvider 60 | * @returns a promise for a poolId 61 | */ 62 | function getPoolId(poolAddress, signerOrProvider) { 63 | return __awaiter(this, void 0, void 0, function () { 64 | var poolContract; 65 | return __generator(this, function (_a) { 66 | poolContract = elf_contracts_typechain_1.BasePool__factory.connect(poolAddress, signerOrProvider); 67 | return [2 /*return*/, poolContract.getPoolId()]; 68 | }); 69 | }); 70 | } 71 | exports.getPoolId = getPoolId; 72 | -------------------------------------------------------------------------------- /dist/src/helpers/getReserves.d.ts: -------------------------------------------------------------------------------- 1 | import { Provider } from "@ethersproject/providers"; 2 | import { BigNumber, Signer } from "ethers"; 3 | export interface ReservesResult { 4 | /** 5 | * addresses of tokens 6 | */ 7 | tokens: string[]; 8 | /** 9 | * balances of tokens in same order as tokens 10 | */ 11 | balances: BigNumber[]; 12 | /** 13 | * decimals of tokens in same order as tokens 14 | */ 15 | decimals: number[]; 16 | } 17 | /** 18 | * Returns the reserves for a given pool. 19 | * @param poolAddress any pool with a getPoolId method 20 | * @param balancerVaultAddress the address of the balancer v2 vault 21 | * @param signerOrProvider 22 | */ 23 | export declare function getReserves( 24 | poolAddress: string, 25 | balancerVaultAddress: string, 26 | signerOrProvider: Signer | Provider 27 | ): Promise; 28 | -------------------------------------------------------------------------------- /dist/src/helpers/getSecondsUntilExpiration.d.ts: -------------------------------------------------------------------------------- 1 | import { Provider } from "@ethersproject/providers"; 2 | import { Signer } from "ethers"; 3 | import { PrincipalPoolTokenInfo, YieldPoolTokenInfo } from "elf-tokenlist"; 4 | /** 5 | * Get the seconds until expiration for a given pool 6 | * @param poolAddress any pool with a getPoolId method 7 | * @param signerOrProvider 8 | * @param timestamp timestamp of the latest block 9 | * @returns the seconds until expiration 10 | */ 11 | export declare function getSecondsUntilExpiration( 12 | poolAddress: string, 13 | signerOrProvider: Signer | Provider, 14 | timestamp: number 15 | ): Promise; 16 | /** 17 | * Get the seconds until expiration for a given pool using tokenlist. 18 | * @param poolTokenInfo PoolTokenInfo with extension property expiration 19 | * @param timestamp timestamp of the latest block 20 | * @returns the seconds until expiration 21 | */ 22 | export declare function getSecondsUntilExpirationByTokenInfo( 23 | poolTokenInfo: PrincipalPoolTokenInfo | YieldPoolTokenInfo, 24 | timestamp: number 25 | ): number; 26 | -------------------------------------------------------------------------------- /dist/src/helpers/getSecondsUntilExpiration.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | /* 3 | * Copyright 2021 Element Finance, Inc 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 18 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 19 | return new (P || (P = Promise))(function (resolve, reject) { 20 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 21 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 22 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 23 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 24 | }); 25 | }; 26 | var __generator = (this && this.__generator) || function (thisArg, body) { 27 | var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; 28 | return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; 29 | function verb(n) { return function (v) { return step([n, v]); }; } 30 | function step(op) { 31 | if (f) throw new TypeError("Generator is already executing."); 32 | while (_) try { 33 | if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; 34 | if (y = 0, t) op = [op[0] & 2, t.value]; 35 | switch (op[0]) { 36 | case 0: case 1: t = op; break; 37 | case 4: _.label++; return { value: op[1], done: false }; 38 | case 5: _.label++; y = op[1]; op = [0]; continue; 39 | case 7: op = _.ops.pop(); _.trys.pop(); continue; 40 | default: 41 | if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } 42 | if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } 43 | if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } 44 | if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } 45 | if (t[2]) _.ops.pop(); 46 | _.trys.pop(); continue; 47 | } 48 | op = body.call(thisArg, _); 49 | } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } 50 | if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; 51 | } 52 | }; 53 | Object.defineProperty(exports, "__esModule", { value: true }); 54 | exports.getSecondsUntilExpirationByTokenInfo = exports.getSecondsUntilExpiration = void 0; 55 | var ethers_1 = require("ethers"); 56 | var elf_contracts_typechain_1 = require("elf-contracts-typechain"); 57 | /** 58 | * Get the seconds until expiration for a given pool 59 | * @param poolAddress any pool with a getPoolId method 60 | * @param signerOrProvider 61 | * @param timestamp timestamp of the latest block 62 | * @returns the seconds until expiration 63 | */ 64 | function getSecondsUntilExpiration(poolAddress, signerOrProvider, timestamp) { 65 | return __awaiter(this, void 0, void 0, function () { 66 | var poolContract, expiration, timeUntilExpiration; 67 | return __generator(this, function (_a) { 68 | switch (_a.label) { 69 | case 0: 70 | poolContract = elf_contracts_typechain_1.ConvergentCurvePool__factory.connect(poolAddress, signerOrProvider); 71 | return [4 /*yield*/, poolContract.expiration()]; 72 | case 1: 73 | expiration = _a.sent(); 74 | timeUntilExpiration = ethers_1.BigNumber.from(timestamp) < expiration 75 | ? expiration.sub(ethers_1.BigNumber.from(timestamp)) 76 | : ethers_1.BigNumber.from(0); 77 | return [2 /*return*/, timeUntilExpiration.toNumber()]; 78 | } 79 | }); 80 | }); 81 | } 82 | exports.getSecondsUntilExpiration = getSecondsUntilExpiration; 83 | /** 84 | * Get the seconds until expiration for a given pool using tokenlist. 85 | * @param poolTokenInfo PoolTokenInfo with extension property expiration 86 | * @param timestamp timestamp of the latest block 87 | * @returns the seconds until expiration 88 | */ 89 | function getSecondsUntilExpirationByTokenInfo(poolTokenInfo, timestamp) { 90 | var expiration = poolTokenInfo.extensions.expiration; 91 | var timeUntilExpiration = timestamp < expiration ? expiration - timestamp : 0; 92 | return timeUntilExpiration; 93 | } 94 | exports.getSecondsUntilExpirationByTokenInfo = getSecondsUntilExpirationByTokenInfo; 95 | -------------------------------------------------------------------------------- /dist/src/helpers/getTermByTokenSymbol.d.ts: -------------------------------------------------------------------------------- 1 | import { Provider } from "@ethersproject/providers"; 2 | import { Signer } from "ethers"; 3 | /** 4 | * returns the term matching a token symbol 5 | * @param termAddresses array of terms addresses 6 | * @param tokenSymbol the token symbol to filter on 7 | * @param signerOrProvider 8 | * @returns a promise for a term address 9 | */ 10 | export declare function getTermByTokenSymbol( 11 | termAddresses: string[], 12 | tokenSymbol: string, 13 | signerOrProvider: Signer | Provider 14 | ): Promise; 15 | -------------------------------------------------------------------------------- /dist/src/helpers/getTermByTokenSymbol.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 3 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 4 | return new (P || (P = Promise))(function (resolve, reject) { 5 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 6 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 7 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 8 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 9 | }); 10 | }; 11 | var __generator = (this && this.__generator) || function (thisArg, body) { 12 | var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; 13 | return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; 14 | function verb(n) { return function (v) { return step([n, v]); }; } 15 | function step(op) { 16 | if (f) throw new TypeError("Generator is already executing."); 17 | while (_) try { 18 | if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; 19 | if (y = 0, t) op = [op[0] & 2, t.value]; 20 | switch (op[0]) { 21 | case 0: case 1: t = op; break; 22 | case 4: _.label++; return { value: op[1], done: false }; 23 | case 5: _.label++; y = op[1]; op = [0]; continue; 24 | case 7: op = _.ops.pop(); _.trys.pop(); continue; 25 | default: 26 | if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } 27 | if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } 28 | if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } 29 | if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } 30 | if (t[2]) _.ops.pop(); 31 | _.trys.pop(); continue; 32 | } 33 | op = body.call(thisArg, _); 34 | } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } 35 | if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; 36 | } 37 | }; 38 | Object.defineProperty(exports, "__esModule", { value: true }); 39 | exports.getTermByTokenSymbol = void 0; 40 | var getTermTokenSymbols_1 = require("./getTermTokenSymbols"); 41 | /** 42 | * returns the term matching a token symbol 43 | * @param termAddresses array of terms addresses 44 | * @param tokenSymbol the token symbol to filter on 45 | * @param signerOrProvider 46 | * @returns a promise for a term address 47 | */ 48 | function getTermByTokenSymbol(termAddresses, tokenSymbol, signerOrProvider) { 49 | return __awaiter(this, void 0, void 0, function () { 50 | var symbolsList; 51 | var _this = this; 52 | return __generator(this, function (_a) { 53 | switch (_a.label) { 54 | case 0: return [4 /*yield*/, Promise.all(termAddresses.map(function (termAddress) { return __awaiter(_this, void 0, void 0, function () { 55 | var _a, principalTokenSymbol, yieldTokenSymbol; 56 | return __generator(this, function (_b) { 57 | switch (_b.label) { 58 | case 0: return [4 /*yield*/, (0, getTermTokenSymbols_1.getTermTokenSymbols)(termAddress, signerOrProvider)]; 59 | case 1: 60 | _a = _b.sent(), principalTokenSymbol = _a.principalTokenSymbol, yieldTokenSymbol = _a.yieldTokenSymbol; 61 | return [2 /*return*/, { 62 | termAddress: termAddress, 63 | principalTokenSymbol: principalTokenSymbol, 64 | yieldTokenSymbol: yieldTokenSymbol, 65 | }]; 66 | } 67 | }); 68 | }); }))]; 69 | case 1: 70 | symbolsList = _a.sent(); 71 | return [2 /*return*/, termAddresses.find(function (t) { 72 | // get the symbols of a particular term address 73 | var term = symbolsList.find(function (_a) { 74 | var termAddress = _a.termAddress; 75 | return termAddress == t; 76 | }); 77 | return ((term === null || term === void 0 ? void 0 : term.principalTokenSymbol) == tokenSymbol || 78 | (term === null || term === void 0 ? void 0 : term.yieldTokenSymbol) == tokenSymbol); 79 | })]; 80 | } 81 | }); 82 | }); 83 | } 84 | exports.getTermByTokenSymbol = getTermByTokenSymbol; 85 | -------------------------------------------------------------------------------- /dist/src/helpers/getTermTokenSymbols.d.ts: -------------------------------------------------------------------------------- 1 | import { Provider } from "@ethersproject/providers"; 2 | import { Signer } from "ethers"; 3 | export interface TermTokenSymbolsResult { 4 | /** 5 | * name of the Principal Token 6 | */ 7 | principalTokenSymbol: string; 8 | /** 9 | * name of the Yield Token 10 | */ 11 | yieldTokenSymbol: string; 12 | } 13 | /** 14 | * returns the token symbols for a given term 15 | * @param termAddress the address of the term 16 | * @param signerOrProvider 17 | * @returns a promise for a TermTokenSymbolsResult 18 | */ 19 | export declare function getTermTokenSymbols( 20 | termAddress: string, 21 | signerOrProvider: Signer | Provider 22 | ): Promise; 23 | -------------------------------------------------------------------------------- /dist/src/helpers/getTermTokenSymbols.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | /* 3 | * Copyright 2021 Element Finance, Inc 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 18 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 19 | return new (P || (P = Promise))(function (resolve, reject) { 20 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 21 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 22 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 23 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 24 | }); 25 | }; 26 | var __generator = (this && this.__generator) || function (thisArg, body) { 27 | var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; 28 | return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; 29 | function verb(n) { return function (v) { return step([n, v]); }; } 30 | function step(op) { 31 | if (f) throw new TypeError("Generator is already executing."); 32 | while (_) try { 33 | if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; 34 | if (y = 0, t) op = [op[0] & 2, t.value]; 35 | switch (op[0]) { 36 | case 0: case 1: t = op; break; 37 | case 4: _.label++; return { value: op[1], done: false }; 38 | case 5: _.label++; y = op[1]; op = [0]; continue; 39 | case 7: op = _.ops.pop(); _.trys.pop(); continue; 40 | default: 41 | if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } 42 | if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } 43 | if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } 44 | if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } 45 | if (t[2]) _.ops.pop(); 46 | _.trys.pop(); continue; 47 | } 48 | op = body.call(thisArg, _); 49 | } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } 50 | if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; 51 | } 52 | }; 53 | Object.defineProperty(exports, "__esModule", { value: true }); 54 | exports.getTermTokenSymbols = void 0; 55 | var elf_contracts_typechain_1 = require("elf-contracts-typechain"); 56 | /** 57 | * returns the token symbols for a given term 58 | * @param termAddress the address of the term 59 | * @param signerOrProvider 60 | * @returns a promise for a TermTokenSymbolsResult 61 | */ 62 | function getTermTokenSymbols(termAddress, signerOrProvider) { 63 | return __awaiter(this, void 0, void 0, function () { 64 | var trancheContract, termSymbol, interestTokenAddress, interestTokenContract, yieldTokenSymbol; 65 | return __generator(this, function (_a) { 66 | switch (_a.label) { 67 | case 0: 68 | trancheContract = elf_contracts_typechain_1.Tranche__factory.connect(termAddress, signerOrProvider); 69 | return [4 /*yield*/, trancheContract.symbol()]; 70 | case 1: 71 | termSymbol = _a.sent(); 72 | return [4 /*yield*/, trancheContract.interestToken()]; 73 | case 2: 74 | interestTokenAddress = _a.sent(); 75 | interestTokenContract = elf_contracts_typechain_1.InterestToken__factory.connect(interestTokenAddress, signerOrProvider); 76 | return [4 /*yield*/, interestTokenContract.symbol()]; 77 | case 3: 78 | yieldTokenSymbol = _a.sent(); 79 | return [2 /*return*/, { 80 | principalTokenSymbol: termSymbol, 81 | yieldTokenSymbol: yieldTokenSymbol, 82 | }]; 83 | } 84 | }); 85 | }); 86 | } 87 | exports.getTermTokenSymbols = getTermTokenSymbols; 88 | -------------------------------------------------------------------------------- /dist/src/helpers/getTerms.d.ts: -------------------------------------------------------------------------------- 1 | import { Provider } from "@ethersproject/providers"; 2 | import { Signer } from "ethers"; 3 | /** 4 | * Returns an array of tranche addresses for a given tranche factory. filterable by wrapped position. 5 | * 6 | * @param trancheFactoryAddress The TrancheFactory that deployed the tranches 7 | * @param wrappedPositionAddress The wrapped position to filter by 8 | * @returns a promise of an array of tranche addresses 9 | */ 10 | export declare function getTerms( 11 | trancheFactoryAddress: string, 12 | wrappedPositionAddress: string | null, 13 | signerOrProvider: Signer | Provider 14 | ): Promise; 15 | -------------------------------------------------------------------------------- /dist/src/helpers/getTerms.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | /* 3 | * Copyright 2021 Element Finance, Inc 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 18 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 19 | return new (P || (P = Promise))(function (resolve, reject) { 20 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 21 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 22 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 23 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 24 | }); 25 | }; 26 | var __generator = (this && this.__generator) || function (thisArg, body) { 27 | var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; 28 | return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; 29 | function verb(n) { return function (v) { return step([n, v]); }; } 30 | function step(op) { 31 | if (f) throw new TypeError("Generator is already executing."); 32 | while (_) try { 33 | if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; 34 | if (y = 0, t) op = [op[0] & 2, t.value]; 35 | switch (op[0]) { 36 | case 0: case 1: t = op; break; 37 | case 4: _.label++; return { value: op[1], done: false }; 38 | case 5: _.label++; y = op[1]; op = [0]; continue; 39 | case 7: op = _.ops.pop(); _.trys.pop(); continue; 40 | default: 41 | if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } 42 | if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } 43 | if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } 44 | if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } 45 | if (t[2]) _.ops.pop(); 46 | _.trys.pop(); continue; 47 | } 48 | op = body.call(thisArg, _); 49 | } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } 50 | if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; 51 | } 52 | }; 53 | Object.defineProperty(exports, "__esModule", { value: true }); 54 | exports.getTerms = void 0; 55 | var elf_contracts_typechain_1 = require("elf-contracts-typechain"); 56 | /** 57 | * Returns an array of tranche addresses for a given tranche factory. filterable by wrapped position. 58 | * 59 | * @param trancheFactoryAddress The TrancheFactory that deployed the tranches 60 | * @param wrappedPositionAddress The wrapped position to filter by 61 | * @returns a promise of an array of tranche addresses 62 | */ 63 | function getTerms(trancheFactoryAddress, wrappedPositionAddress, signerOrProvider) { 64 | return __awaiter(this, void 0, void 0, function () { 65 | var trancheFactoryContract, queryFilter, trancheEvents, trancheAddresses; 66 | return __generator(this, function (_a) { 67 | switch (_a.label) { 68 | case 0: 69 | trancheFactoryContract = elf_contracts_typechain_1.TrancheFactory__factory.connect(trancheFactoryAddress, signerOrProvider); 70 | queryFilter = trancheFactoryContract.filters.TrancheCreated(null, wrappedPositionAddress, null); 71 | return [4 /*yield*/, trancheFactoryContract.queryFilter(queryFilter)]; 72 | case 1: 73 | trancheEvents = _a.sent(); 74 | trancheAddresses = trancheEvents.map(function (event) { var _a; return (_a = event.args) === null || _a === void 0 ? void 0 : _a.trancheAddress; }); 75 | return [2 /*return*/, trancheAddresses]; 76 | } 77 | }); 78 | }); 79 | } 80 | exports.getTerms = getTerms; 81 | -------------------------------------------------------------------------------- /dist/src/helpers/getTimeUntilExpiration.d.ts: -------------------------------------------------------------------------------- 1 | import { Provider } from "@ethersproject/providers"; 2 | import { Signer } from "ethers"; 3 | /** 4 | * Get the time until expiration for a given pool 5 | * @param poolAddress any pool with a getPoolId method 6 | * @param signerOrProvider 7 | * @param timestamp timestamp of the latest block 8 | * @returns the time until expiration 9 | */ 10 | export declare function getTimeUntilExpiration( 11 | poolAddress: string, 12 | signerOrProvider: Signer | Provider, 13 | timestamp: number 14 | ): Promise; 15 | -------------------------------------------------------------------------------- /dist/src/helpers/getTimeUntilExpiration.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | /* 3 | * Copyright 2021 Element Finance, Inc 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 18 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 19 | return new (P || (P = Promise))(function (resolve, reject) { 20 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 21 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 22 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 23 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 24 | }); 25 | }; 26 | var __generator = (this && this.__generator) || function (thisArg, body) { 27 | var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; 28 | return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; 29 | function verb(n) { return function (v) { return step([n, v]); }; } 30 | function step(op) { 31 | if (f) throw new TypeError("Generator is already executing."); 32 | while (_) try { 33 | if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; 34 | if (y = 0, t) op = [op[0] & 2, t.value]; 35 | switch (op[0]) { 36 | case 0: case 1: t = op; break; 37 | case 4: _.label++; return { value: op[1], done: false }; 38 | case 5: _.label++; y = op[1]; op = [0]; continue; 39 | case 7: op = _.ops.pop(); _.trys.pop(); continue; 40 | default: 41 | if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } 42 | if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } 43 | if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } 44 | if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } 45 | if (t[2]) _.ops.pop(); 46 | _.trys.pop(); continue; 47 | } 48 | op = body.call(thisArg, _); 49 | } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } 50 | if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; 51 | } 52 | }; 53 | Object.defineProperty(exports, "__esModule", { value: true }); 54 | exports.getTimeUntilExpiration = void 0; 55 | var elf_contracts_typechain_1 = require("elf-contracts-typechain"); 56 | var ethers_1 = require("ethers"); 57 | /** 58 | * Get the time until expiration for a given pool 59 | * @param poolAddress any pool with a getPoolId method 60 | * @param signerOrProvider 61 | * @param timestamp timestamp of the latest block 62 | * @returns the time until expiration 63 | */ 64 | function getTimeUntilExpiration(poolAddress, signerOrProvider, timestamp) { 65 | return __awaiter(this, void 0, void 0, function () { 66 | var poolContract, expiration, timeUntilExpiration; 67 | return __generator(this, function (_a) { 68 | switch (_a.label) { 69 | case 0: 70 | poolContract = elf_contracts_typechain_1.ConvergentCurvePool__factory.connect(poolAddress, signerOrProvider); 71 | return [4 /*yield*/, poolContract.expiration()]; 72 | case 1: 73 | expiration = _a.sent(); 74 | timeUntilExpiration = ethers_1.BigNumber.from(timestamp) < expiration 75 | ? expiration.sub(ethers_1.BigNumber.from(timestamp)) 76 | : ethers_1.BigNumber.from(0); 77 | return [2 /*return*/, timeUntilExpiration.toNumber()]; 78 | } 79 | }); 80 | }); 81 | } 82 | exports.getTimeUntilExpiration = getTimeUntilExpiration; 83 | -------------------------------------------------------------------------------- /dist/src/helpers/getTokenInfo.d.ts: -------------------------------------------------------------------------------- 1 | import { TokenInfo, TokenList } from "@uniswap/token-lists"; 2 | import { 3 | PrincipalTokenInfo, 4 | YieldPoolTokenInfo, 5 | PrincipalPoolTokenInfo, 6 | AssetProxyTokenInfo, 7 | AnyTokenListInfo, 8 | } from "elf-tokenlist"; 9 | import { AddressesJsonFile } from "elf-tokenlist/dist/AddressesJsonFile"; 10 | interface InitTokenListResult { 11 | tokenList: TokenList; 12 | addressesJson: AddressesJsonFile; 13 | tokenInfoByAddress: Record; 14 | } 15 | /** 16 | * Init the tokenlist for given chain 17 | * @param chainName name of the chain that the tokenlist represents 18 | * @returns InitTokenListResult 19 | */ 20 | export declare function initTokenList(chainName: string): InitTokenListResult; 21 | /** 22 | * Helper function for looking up a tokenlist info 23 | * @param address address of the token 24 | * @param tokenInfoByAddress mapping of TokenInfos by address 25 | * @returns TokenInfo associated with the address param 26 | */ 27 | export declare function getTokenInfo( 28 | address: string, 29 | tokenInfoByAddress: Record 30 | ): T; 31 | /** 32 | * Finds tokenInfos for AssetProxies. 33 | * @param tokenInfos 34 | * @returns list of AssetProxyTokenInfo 35 | */ 36 | export declare function getAssetProxyTokenInfos( 37 | tokenInfos: TokenInfo[] 38 | ): AssetProxyTokenInfo[]; 39 | /** 40 | * Finds tokenInfos for Principal Tokens 41 | * @param tokenInfos 42 | * @returns list of PrincipalTokenInfo 43 | */ 44 | export declare function getPrincipalTokenInfos( 45 | tokenInfos: TokenInfo[] 46 | ): PrincipalTokenInfo[]; 47 | /** 48 | * Returns a PrincipalTokenInfo given a TokenInfo for a pool 49 | * @param poolInfo 50 | * @param tokenInfos 51 | * @returns PrincipalTokenInfo 52 | */ 53 | export declare function getPrincipalTokenInfoForPool( 54 | poolInfo: YieldPoolTokenInfo | PrincipalPoolTokenInfo, 55 | tokenInfos: TokenInfo[] 56 | ): PrincipalTokenInfo; 57 | /** 58 | * Returns the TokenInfo of the pool corresponding to a Principal Token 59 | * @param principalTokenAddress 60 | * @param tokenInfos 61 | * @returns PrincipalPoolTokenInfo 62 | */ 63 | export declare function getPoolInfoForPrincipalToken( 64 | principalTokenAddress: string, 65 | tokenInfos: TokenInfo[] 66 | ): PrincipalPoolTokenInfo; 67 | /** 68 | * Returns the TokenInfos for the Yield Pools 69 | * @param tokenInfos 70 | * @returns a list of YieldPoolTokenInfo 71 | */ 72 | export declare function getYieldPoolTokenInfos( 73 | tokenInfos: TokenInfo[] 74 | ): YieldPoolTokenInfo[]; 75 | export {}; 76 | -------------------------------------------------------------------------------- /dist/src/helpers/getTokenInfo.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | /* 3 | * Copyright 2021 Element Finance, Inc 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | var __importDefault = (this && this.__importDefault) || function (mod) { 18 | return (mod && mod.__esModule) ? mod : { "default": mod }; 19 | }; 20 | Object.defineProperty(exports, "__esModule", { value: true }); 21 | exports.getYieldPoolTokenInfos = exports.getPoolInfoForPrincipalToken = exports.getPrincipalTokenInfoForPool = exports.getPrincipalTokenInfos = exports.getAssetProxyTokenInfos = exports.getTokenInfo = exports.initTokenList = void 0; 22 | var lodash_keyby_1 = __importDefault(require("lodash.keyby")); 23 | var elf_tokenlist_1 = require("elf-tokenlist"); 24 | /** 25 | * Init the tokenlist for given chain 26 | * @param chainName name of the chain that the tokenlist represents 27 | * @returns InitTokenListResult 28 | */ 29 | function initTokenList(chainName) { 30 | // eslint-disable-next-line @typescript-eslint/no-var-requires 31 | var tokenList = require("elf-tokenlist/dist/" + chainName + ".tokenlist.json"); 32 | // eslint-disable-next-line @typescript-eslint/no-var-requires 33 | var addressesJson = require("elf-tokenlist/dist/" + chainName + ".addresses.json"); 34 | var tokenInfos = tokenList.tokens; 35 | var tokenInfoByAddress = (0, lodash_keyby_1.default)(tokenInfos, "address"); 36 | return { tokenList: tokenList, addressesJson: addressesJson, tokenInfoByAddress: tokenInfoByAddress }; 37 | } 38 | exports.initTokenList = initTokenList; 39 | /** 40 | * Helper function for looking up a tokenlist info 41 | * @param address address of the token 42 | * @param tokenInfoByAddress mapping of TokenInfos by address 43 | * @returns TokenInfo associated with the address param 44 | */ 45 | function getTokenInfo(address, tokenInfoByAddress) { 46 | return tokenInfoByAddress[address]; 47 | } 48 | exports.getTokenInfo = getTokenInfo; 49 | function isAssetProxy(tokenInfo) { 50 | var _a; 51 | return !!((_a = tokenInfo.tags) === null || _a === void 0 ? void 0 : _a.includes(elf_tokenlist_1.TokenTag.ASSET_PROXY)); 52 | } 53 | /** 54 | * Finds tokenInfos for AssetProxies. 55 | * @param tokenInfos 56 | * @returns list of AssetProxyTokenInfo 57 | */ 58 | function getAssetProxyTokenInfos(tokenInfos) { 59 | return tokenInfos.filter(function (tokenInfo) { 60 | return isAssetProxy(tokenInfo); 61 | }); 62 | } 63 | exports.getAssetProxyTokenInfos = getAssetProxyTokenInfos; 64 | function isPrincipalToken(tokenInfo) { 65 | var _a; 66 | return !!((_a = tokenInfo === null || tokenInfo === void 0 ? void 0 : tokenInfo.tags) === null || _a === void 0 ? void 0 : _a.includes(elf_tokenlist_1.TokenTag.PRINCIPAL)); 67 | } 68 | /** 69 | * Finds tokenInfos for Principal Tokens 70 | * @param tokenInfos 71 | * @returns list of PrincipalTokenInfo 72 | */ 73 | function getPrincipalTokenInfos(tokenInfos) { 74 | return tokenInfos.filter(function (tokenInfo) { 75 | return isPrincipalToken(tokenInfo); 76 | }); 77 | } 78 | exports.getPrincipalTokenInfos = getPrincipalTokenInfos; 79 | function isPrincipalPool(tokenInfo) { 80 | var _a; 81 | return !!((_a = tokenInfo.tags) === null || _a === void 0 ? void 0 : _a.includes(elf_tokenlist_1.TokenTag.CCPOOL)); 82 | } 83 | /** 84 | * Returns a PrincipalTokenInfo given a TokenInfo for a pool 85 | * @param poolInfo 86 | * @param tokenInfos 87 | * @returns PrincipalTokenInfo 88 | */ 89 | function getPrincipalTokenInfoForPool(poolInfo, tokenInfos) { 90 | var principalTokenInfos = getPrincipalTokenInfos(tokenInfos); 91 | if (isPrincipalPool(poolInfo)) { 92 | var trancheAddress_1 = poolInfo.extensions.bond; 93 | var trancheInfo_1 = principalTokenInfos.find(function (info) { return info.address === trancheAddress_1; }); 94 | return trancheInfo_1; 95 | } 96 | var interestTokenAddress = poolInfo.extensions.interestToken; 97 | var trancheInfo = principalTokenInfos.find(function (info) { return info.extensions.interestToken === interestTokenAddress; }); 98 | return trancheInfo; 99 | } 100 | exports.getPrincipalTokenInfoForPool = getPrincipalTokenInfoForPool; 101 | /** 102 | * Returns the TokenInfo of the pool corresponding to a Principal Token 103 | * @param principalTokenAddress 104 | * @param tokenInfos 105 | * @returns PrincipalPoolTokenInfo 106 | */ 107 | function getPoolInfoForPrincipalToken(principalTokenAddress, tokenInfos) { 108 | var principalPools = tokenInfos.filter(function (tokenInfo) { 109 | return isPrincipalPool(tokenInfo); 110 | }); 111 | return principalPools.find(function (_a) { 112 | var bond = _a.extensions.bond; 113 | return bond === principalTokenAddress; 114 | }); 115 | } 116 | exports.getPoolInfoForPrincipalToken = getPoolInfoForPrincipalToken; 117 | function isYieldPool(tokenInfo) { 118 | var _a; 119 | return !!((_a = tokenInfo.tags) === null || _a === void 0 ? void 0 : _a.includes(elf_tokenlist_1.TokenTag.WPOOL)); 120 | } 121 | /** 122 | * Returns the TokenInfos for the Yield Pools 123 | * @param tokenInfos 124 | * @returns a list of YieldPoolTokenInfo 125 | */ 126 | function getYieldPoolTokenInfos(tokenInfos) { 127 | return tokenInfos.filter(function (tokenInfo) { 128 | return isYieldPool(tokenInfo); 129 | }); 130 | } 131 | exports.getYieldPoolTokenInfos = getYieldPoolTokenInfos; 132 | -------------------------------------------------------------------------------- /dist/src/helpers/getTokenPrice.d.ts: -------------------------------------------------------------------------------- 1 | import { Currency, Money } from "ts-money"; 2 | import { ERC20 } from "elf-contracts-typechain/dist/types/ERC20"; 3 | export declare function getTokenPrice( 4 | contract: TContract, 5 | currency: Currency 6 | ): Promise; 7 | -------------------------------------------------------------------------------- /dist/src/helpers/getTokenPrice.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.getTokenPrice = void 0; 4 | var ts_money_1 = require("ts-money"); 5 | function getTokenPrice(contract, currency) { 6 | return new Promise(function (resolve) { 7 | return resolve(ts_money_1.Money.fromDecimal(0.01, currency, Math.round)); 8 | }); 9 | } 10 | exports.getTokenPrice = getTokenPrice; 11 | -------------------------------------------------------------------------------- /dist/src/helpers/getTotalSupply.d.ts: -------------------------------------------------------------------------------- 1 | import { Provider } from "@ethersproject/providers"; 2 | import { BigNumber, Signer } from "ethers"; 3 | /** 4 | * Returns the total supply for a pool. All balancer v2 pools use an 18 decimal Balancer Pool Token 5 | * (BPT) to track the total supply. 6 | * @param poolAddress any pool with a totalSupply method 7 | * @param signerOrProvider 8 | */ 9 | export declare function getTotalSupply( 10 | poolAddress: string, 11 | signerOrProvider: Signer | Provider 12 | ): Promise; 13 | -------------------------------------------------------------------------------- /dist/src/helpers/getTotalSupply.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | /* 3 | * Copyright 2021 Element Finance, Inc 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 18 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 19 | return new (P || (P = Promise))(function (resolve, reject) { 20 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 21 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 22 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 23 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 24 | }); 25 | }; 26 | var __generator = (this && this.__generator) || function (thisArg, body) { 27 | var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; 28 | return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; 29 | function verb(n) { return function (v) { return step([n, v]); }; } 30 | function step(op) { 31 | if (f) throw new TypeError("Generator is already executing."); 32 | while (_) try { 33 | if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; 34 | if (y = 0, t) op = [op[0] & 2, t.value]; 35 | switch (op[0]) { 36 | case 0: case 1: t = op; break; 37 | case 4: _.label++; return { value: op[1], done: false }; 38 | case 5: _.label++; y = op[1]; op = [0]; continue; 39 | case 7: op = _.ops.pop(); _.trys.pop(); continue; 40 | default: 41 | if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } 42 | if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } 43 | if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } 44 | if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } 45 | if (t[2]) _.ops.pop(); 46 | _.trys.pop(); continue; 47 | } 48 | op = body.call(thisArg, _); 49 | } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } 50 | if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; 51 | } 52 | }; 53 | Object.defineProperty(exports, "__esModule", { value: true }); 54 | exports.getTotalSupply = void 0; 55 | var elf_contracts_typechain_1 = require("elf-contracts-typechain"); 56 | /** 57 | * Returns the total supply for a pool. All balancer v2 pools use an 18 decimal Balancer Pool Token 58 | * (BPT) to track the total supply. 59 | * @param poolAddress any pool with a totalSupply method 60 | * @param signerOrProvider 61 | */ 62 | function getTotalSupply(poolAddress, signerOrProvider) { 63 | return __awaiter(this, void 0, void 0, function () { 64 | var poolContract, totalSupply; 65 | return __generator(this, function (_a) { 66 | switch (_a.label) { 67 | case 0: 68 | poolContract = elf_contracts_typechain_1.BasePool__factory.connect(poolAddress, signerOrProvider); 69 | return [4 /*yield*/, poolContract.totalSupply()]; 70 | case 1: 71 | totalSupply = _a.sent(); 72 | return [2 /*return*/, totalSupply]; 73 | } 74 | }); 75 | }); 76 | } 77 | exports.getTotalSupply = getTotalSupply; 78 | -------------------------------------------------------------------------------- /dist/src/helpers/getUnderlyingContractsByAddress.d.ts: -------------------------------------------------------------------------------- 1 | import { Provider } from "@ethersproject/providers"; 2 | import { Signer } from "ethers"; 3 | import { 4 | ERC20, 5 | ERC20Permit, 6 | WETH, 7 | DAI, 8 | } from "elf-contracts-typechain/dist/types"; 9 | /** 10 | * This method creates a token to contract mapping 11 | * @param addressesJsonId mainnet or goerli 12 | * @param signerOrProvider 13 | * @returns a mapping of token addresses to corresponding pool contracts 14 | */ 15 | export declare function getUnderlyingContractsByAddress( 16 | addressesJsonId: string, 17 | signerOrProvider: Signer | Provider 18 | ): Record; 19 | -------------------------------------------------------------------------------- /dist/src/helpers/getUnderlyingContractsByAddress.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | /* 3 | * Copyright 2021 Element Finance, Inc 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | Object.defineProperty(exports, "__esModule", { value: true }); 18 | exports.getUnderlyingContractsByAddress = void 0; 19 | var types_1 = require("elf-contracts-typechain/dist/types"); 20 | var WETH__factory_1 = require("elf-contracts-typechain/dist/types/factories/WETH__factory"); 21 | /** 22 | * This method creates a token to contract mapping 23 | * @param addressesJsonId mainnet or goerli 24 | * @param signerOrProvider 25 | * @returns a mapping of token addresses to corresponding pool contracts 26 | */ 27 | function getUnderlyingContractsByAddress(addressesJsonId, signerOrProvider) { 28 | var _a; 29 | // eslint-disable-next-line @typescript-eslint/no-var-requires 30 | var AddressesJson = require("elf-tokenlist/dist/" + addressesJsonId + ".addresses.json"); 31 | var _b = AddressesJson.addresses, wethAddress = _b.wethAddress, wbtcAddress = _b.wbtcAddress, usdcAddress = _b.usdcAddress, daiAddress = _b.daiAddress, crvalusdAddress = _b["alusd3crv-fAddress"], crvmimAddress = _b["mim-3lp3crv-fAddress"], crvlusdAddress = _b["lusd3crv-fAddress"], crv3cryptoAddress = _b.crv3cryptoAddress, crvtricryptoAddress = _b.crvtricryptoAddress, stecrvAddress = _b.stecrvAddress, eurscrvAddress = _b.eurscrvAddress; 32 | var wethContract = WETH__factory_1.WETH__factory.connect(wethAddress, signerOrProvider); 33 | var wbtcContract = types_1.ERC20__factory.connect(wbtcAddress, signerOrProvider); 34 | var usdcContract = types_1.ERC20Permit__factory.connect(usdcAddress, signerOrProvider); 35 | var daiContract = types_1.DAI__factory.connect(daiAddress, signerOrProvider); 36 | var crvlusdContract = types_1.ERC20__factory.connect(crvlusdAddress, signerOrProvider); 37 | var crvalusdContract = types_1.ERC20__factory.connect(crvalusdAddress, signerOrProvider); 38 | var crvmimContract = types_1.ERC20__factory.connect(crvmimAddress, signerOrProvider); 39 | var crvTricryptoContract = types_1.ERC20__factory.connect(crvtricryptoAddress, signerOrProvider); 40 | var crv3CryptoContract = types_1.ERC20__factory.connect(crv3cryptoAddress, signerOrProvider); 41 | var steCrvContract = types_1.ERC20__factory.connect(stecrvAddress, signerOrProvider); 42 | var eursCrvContract = types_1.ERC20__factory.connect(eurscrvAddress, signerOrProvider); 43 | var underlyingContractsByAddress = Object.freeze((_a = {}, 44 | _a[wethAddress] = wethContract, 45 | _a[wbtcAddress] = wbtcContract, 46 | _a[usdcAddress] = usdcContract, 47 | _a[daiAddress] = daiContract, 48 | _a[crvlusdAddress] = crvlusdContract, 49 | _a[crvalusdAddress] = crvalusdContract, 50 | _a[crvtricryptoAddress] = crvTricryptoContract, 51 | _a[crv3cryptoAddress] = crv3CryptoContract, 52 | _a[crvmimAddress] = crvmimContract, 53 | _a[stecrvAddress] = steCrvContract, 54 | _a[eurscrvAddress] = eursCrvContract, 55 | _a)); 56 | return underlyingContractsByAddress; 57 | } 58 | exports.getUnderlyingContractsByAddress = getUnderlyingContractsByAddress; 59 | -------------------------------------------------------------------------------- /dist/src/helpers/getUnitSeconds.d.ts: -------------------------------------------------------------------------------- 1 | import { Provider } from "@ethersproject/providers"; 2 | import { Signer } from "ethers"; 3 | /** 4 | * Get the unit seconds for a given pool 5 | * @param poolAddress any pool with a getPoolId method 6 | * @param signerOrProvider 7 | * @returns the unit seconds 8 | */ 9 | export declare function getUnitSeconds( 10 | poolAddress: string, 11 | signerOrProvider: Signer | Provider 12 | ): Promise; 13 | -------------------------------------------------------------------------------- /dist/src/helpers/getUnitSeconds.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | /* 3 | * Copyright 2021 Element Finance, Inc 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 18 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 19 | return new (P || (P = Promise))(function (resolve, reject) { 20 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 21 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 22 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 23 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 24 | }); 25 | }; 26 | var __generator = (this && this.__generator) || function (thisArg, body) { 27 | var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; 28 | return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; 29 | function verb(n) { return function (v) { return step([n, v]); }; } 30 | function step(op) { 31 | if (f) throw new TypeError("Generator is already executing."); 32 | while (_) try { 33 | if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; 34 | if (y = 0, t) op = [op[0] & 2, t.value]; 35 | switch (op[0]) { 36 | case 0: case 1: t = op; break; 37 | case 4: _.label++; return { value: op[1], done: false }; 38 | case 5: _.label++; y = op[1]; op = [0]; continue; 39 | case 7: op = _.ops.pop(); _.trys.pop(); continue; 40 | default: 41 | if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } 42 | if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } 43 | if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } 44 | if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } 45 | if (t[2]) _.ops.pop(); 46 | _.trys.pop(); continue; 47 | } 48 | op = body.call(thisArg, _); 49 | } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } 50 | if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; 51 | } 52 | }; 53 | Object.defineProperty(exports, "__esModule", { value: true }); 54 | exports.getUnitSeconds = void 0; 55 | var elf_contracts_typechain_1 = require("elf-contracts-typechain"); 56 | /** 57 | * Get the unit seconds for a given pool 58 | * @param poolAddress any pool with a getPoolId method 59 | * @param signerOrProvider 60 | * @returns the unit seconds 61 | */ 62 | function getUnitSeconds(poolAddress, signerOrProvider) { 63 | return __awaiter(this, void 0, void 0, function () { 64 | var poolContract, unitSeconds; 65 | return __generator(this, function (_a) { 66 | switch (_a.label) { 67 | case 0: 68 | poolContract = elf_contracts_typechain_1.ConvergentCurvePool__factory.connect(poolAddress, signerOrProvider); 69 | return [4 /*yield*/, poolContract.unitSeconds()]; 70 | case 1: 71 | unitSeconds = _a.sent(); 72 | return [2 /*return*/, unitSeconds.toNumber()]; 73 | } 74 | }); 75 | }); 76 | } 77 | exports.getUnitSeconds = getUnitSeconds; 78 | -------------------------------------------------------------------------------- /dist/src/index.d.ts: -------------------------------------------------------------------------------- 1 | export { mintWithUserProxy } from "./mint"; 2 | export { getTermExpiration } from "./mint"; 3 | export { getTermPosition } from "./mint"; 4 | export { SingleSwap } from "./swap"; 5 | export { swap } from "./swap"; 6 | export { joinConvergentPool } from "./joinPool"; 7 | export { joinWeightedPool } from "./joinPool"; 8 | export { exitConvergentPool } from "./exitPool"; 9 | export { WeightedPoolExitKind } from "./exitPool"; 10 | export { exitWeightedPool } from "./exitPool"; 11 | export { calcFixedAPR } from "./helpers/calcFixedAPR"; 12 | export { calcSwapOutGivenInCCPoolUnsafe } from "./helpers/calcPoolSwap"; 13 | export { calcSwapInGivenOutCCPoolUnsafe } from "./helpers/calcPoolSwap"; 14 | export { calcSwapOutGivenInWeightedPoolUnsafe } from "./helpers/calcPoolSwap"; 15 | export { calcSwapInGivenOutWeightedPoolUnsafe } from "./helpers/calcPoolSwap"; 16 | export { calcSpotPricePt } from "./helpers/calcSpotPrice"; 17 | export { calcSpotPriceYt } from "./helpers/calcSpotPrice"; 18 | export { PoolType } from "./helpers/getElementAddresses"; 19 | export { getElementDeploymentAddresses } from "./helpers/getElementAddresses"; 20 | export { getElementTermFactoryAddresses } from "./helpers/getElementAddresses"; 21 | export { getElementTermAddresses } from "./helpers/getElementAddresses"; 22 | export { getElementPtPoolAddresses } from "./helpers/getElementAddresses"; 23 | export { getElementYtPoolAddresses } from "./helpers/getElementAddresses"; 24 | export { getPoolIdByTermAddress } from "./helpers/getElementAddresses"; 25 | export { getBaseTokenAddress } from "./helpers/getElementAddresses"; 26 | export { getLatestBlockTimestamp } from "./helpers/getLatestBlockTimestamp"; 27 | export { getPoolId } from "./helpers/getPoolId"; 28 | export { ReservesResult } from "./helpers/getReserves"; 29 | export { getReserves } from "./helpers/getReserves"; 30 | export { TermTokenSymbolsResult } from "./helpers/getTermTokenSymbols"; 31 | export { getTermByTokenSymbol } from "./helpers/getTermByTokenSymbol"; 32 | export { getTerms } from "./helpers/getTerms"; 33 | export { getTermTokenSymbols } from "./helpers/getTermTokenSymbols"; 34 | export { getSecondsUntilExpiration } from "./helpers/getSecondsUntilExpiration"; 35 | export { getTotalSupply } from "./helpers/getTotalSupply"; 36 | export { getUnitSeconds } from "./helpers/getUnitSeconds"; 37 | export { ONE_MINUTE_IN_SECONDS } from "./constants/time"; 38 | export { ONE_HOUR_IN_SECONDS } from "./constants/time"; 39 | export { ONE_DAY_IN_SECONDS } from "./constants/time"; 40 | export { ONE_WEEK_IN_SECONDS } from "./constants/time"; 41 | export { THIRTY_DAYS_IN_SECONDS } from "./constants/time"; 42 | export { SIX_MONTHS_IN_SECONDS } from "./constants/time"; 43 | export { ONE_YEAR_IN_SECONDS } from "./constants/time"; 44 | export { ONE_MINUTE_IN_MILLISECONDS } from "./constants/time"; 45 | export { ONE_HOUR_IN_MILLISECONDS } from "./constants/time"; 46 | export { ONE_DAY_IN_MILLISECONDS } from "./constants/time"; 47 | export { ONE_WEEK_IN_MILLISECONDS } from "./constants/time"; 48 | export { ONE_YEAR_IN_MILLISECONDS } from "./constants/time"; 49 | export { THIRTY_DAYS_IN_MILLISECONDS } from "./constants/time"; 50 | -------------------------------------------------------------------------------- /dist/src/joinPool.d.ts: -------------------------------------------------------------------------------- 1 | import { BigNumber, ContractTransaction, Signer } from "ethers"; 2 | /** 3 | * Add liquidity to a ConvergentCurvePool. 4 | * @param signer Who is authorizing the transaction 5 | * @param poolId Balancer V2 PoolId 6 | * @param senderAddress who is depositing the money into the pool 7 | * @param receipientAddress who is receiving the LP token 8 | * @param vaultAddress Balancer V2 Vault address 9 | * @param tokens tokens to deposit, note: sorted alphanumerically. ETH must be sorted as though it 10 | * were WETH. 11 | * @param maxAmountsIn maximum amounts to deposit, same order as tokens. 12 | * @param fromInternalBalance Use the sender's Balancer V2 internal balance first, if available. 13 | * @returns returns the contract transaction. 14 | */ 15 | export declare function joinConvergentPool( 16 | signer: Signer, 17 | poolId: string, 18 | senderAddress: string, 19 | receipientAddress: string, 20 | vaultAddress: string, 21 | tokens: string[], 22 | maxAmountsIn: BigNumber[], 23 | fromInternalBalance?: boolean 24 | ): Promise; 25 | declare enum WeightedPoolJoinKind { 26 | INIT = 0, 27 | EXACT_TOKENS_IN_FOR_BPT_OUT = 1, 28 | TOKEN_IN_FOR_EXACT_BPT_OUT = 2, 29 | } 30 | /** 31 | * Add liquidity to a WeightedPool. 32 | * @param signer who is authorizing the transaction. 33 | * @param poolId Balancer V2 PoolId. 34 | * @param senderAddress who is depositing the money into the pool. 35 | * @param receipientAddress who is receiving the LP token. 36 | * @param vaultAddress Balancer V2 Vault address. 37 | * @param tokens tokens to deposit, note: sorted alphanumerically. ETH must be sorted as though it 38 | * were WETH. 39 | * @param maxAmountsIn maximum amounts to deposit, same order as tokens. 40 | * @param minBPTOut minimun amount of LP out, setting this creates a slippage tolerangs. 41 | * @param fromInternalBalance use the sender's Balancer V2 internal balance first, if available. 42 | * @param joinKind 43 | * @returns returns the contract transaction. 44 | */ 45 | export declare function joinWeightedPool( 46 | signer: Signer, 47 | poolId: string, 48 | senderAddress: string, 49 | receipientAddress: string, 50 | vaultAddress: string, 51 | tokens: string[], 52 | maxAmountsIn: BigNumber[], 53 | minBPTOut?: BigNumber, 54 | fromInternalBalance?: boolean, 55 | joinKind?: WeightedPoolJoinKind 56 | ): Promise; 57 | export {}; 58 | -------------------------------------------------------------------------------- /dist/src/mint.d.ts: -------------------------------------------------------------------------------- 1 | import { Provider } from "@ethersproject/providers"; 2 | import { 3 | BigNumber, 4 | ContractTransaction, 5 | PayableOverrides, 6 | Signer, 7 | } from "ethers"; 8 | export declare const ETH_SENTINEL_ADDRESS = 9 | "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; 10 | /** 11 | * Mints new principal and yield tokens for a given amount of base asset. The base asset must match 12 | * the term's underlying. For terms that accept WETH, ETH can also be used by supplying the ETH_SENTINEL_ADDRESS. 13 | * @param userProxyContractAddress address of Element's UserProxy 14 | * @param termExpiration the exiration date of the term in unix seconds 15 | * @param termPosition the address of the term's wrapped position 16 | * @param baseAssetAmount the amount of base asset to deposit, i.e. "3.14" Ether 17 | * @param baseAssetAddress the address of the token to deposit. Use 18 | * ETH_SENTINEL_ADDRESS to mint with Ether. 19 | * @param baseAssetDecimals the decimal precision of the asset, i.e. 18 for Ether 20 | * @param signerOrProvider 21 | */ 22 | export declare function mintWithUserProxy( 23 | userProxyContractAddress: string, 24 | termExpiration: number, 25 | termPosition: string, 26 | baseAssetAmount: string, 27 | baseAssetAddress: string, 28 | baseAssetDecimals: number, 29 | signerOrProvider: Signer | Provider, 30 | overrides?: PayableOverrides 31 | ): Promise; 32 | /** 33 | * get the expiration time in unix seconds for a term. returns a BigNumber that can be converted 34 | * to a number with BigNumber.toNumber() 35 | * @param termAddress the address of the term 36 | * @param signerOrProvider 37 | * @returns 38 | */ 39 | export declare function getTermExpiration( 40 | termAddress: string, 41 | signerOrProvider: Signer | Provider 42 | ): Promise; 43 | /** 44 | * returns the wrapped position address for a given term 45 | * @param termAddress the address of the term 46 | * @param signerOrProvider 47 | * @returns 48 | */ 49 | export declare function getTermPosition( 50 | termAddress: string, 51 | signerOrProvider: Signer | Provider 52 | ): Promise; 53 | -------------------------------------------------------------------------------- /dist/src/prices/coingecko/index.d.ts: -------------------------------------------------------------------------------- 1 | import { Currency, Money } from "ts-money"; 2 | export declare function getCoinGeckoId( 3 | symbol: string | undefined 4 | ): string | undefined; 5 | export declare function fetchCoinGeckoPrice( 6 | coinGeckoId: string, 7 | currency: Currency 8 | ): Promise; 9 | export declare function fetchCoinGeckoHistoricalPrice( 10 | coinGeckoId: string, 11 | currency: Currency, 12 | daysAgo?: number 13 | ): Promise; 14 | -------------------------------------------------------------------------------- /dist/src/prices/curve/pools.d.ts: -------------------------------------------------------------------------------- 1 | import { Provider } from "@ethersproject/providers"; 2 | import { Signer } from "ethers"; 3 | import { 4 | CurveStethPool, 5 | CurveContract, 6 | } from "elf-contracts-typechain/dist/types"; 7 | export declare function getCrvTriCryptoPoolContract( 8 | signerOrProvider: Signer | Provider 9 | ): CurveContract; 10 | export declare function getCrv3CryptoPoolContract( 11 | signerOrProvider: Signer | Provider 12 | ): CurveContract; 13 | export declare function getSteCrvPoolContract( 14 | signerOrProvider: Signer | Provider 15 | ): CurveStethPool; 16 | -------------------------------------------------------------------------------- /dist/src/prices/curve/pools.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.getSteCrvPoolContract = exports.getCrv3CryptoPoolContract = exports.getCrvTriCryptoPoolContract = void 0; 4 | var CurveContract__factory_1 = require("elf-contracts-typechain/dist/types/factories/CurveContract__factory"); 5 | var CurveStethPool__factory_1 = require("elf-contracts-typechain/dist/types/factories/CurveStethPool__factory"); 6 | /* 7 | * Curve pools that aren't strictly stablecoins are architected such that the LP 8 | * token (like what is used for minting in Element) is separate from the pool 9 | * contract that deals with trading and pricing. 10 | * 11 | * To price one of these assets, use the `withdraw_one_coin` method to price one 12 | * of the assets in the pool against an external price sensor, ie: coingecko. 13 | * 14 | * NOTE: You can find the pool addresses on curve's website at the bottom of a 15 | * pool page. 16 | */ 17 | function getCrvTriCryptoPoolContract(signerOrProvider) { 18 | var CRVTriCrytoPoolAddress = "0x80466c64868e1ab14a1ddf27a676c3fcbe638fe5"; 19 | var crvTriCryptoPoolContract = CurveContract__factory_1.CurveContract__factory.connect(CRVTriCrytoPoolAddress, signerOrProvider); 20 | return crvTriCryptoPoolContract; 21 | } 22 | exports.getCrvTriCryptoPoolContract = getCrvTriCryptoPoolContract; 23 | function getCrv3CryptoPoolContract(signerOrProvider) { 24 | var CRV3CrytoPoolAddress = "0xD51a44d3FaE010294C616388b506AcdA1bfAAE46"; 25 | var crv3CryptoPoolContract = CurveContract__factory_1.CurveContract__factory.connect(CRV3CrytoPoolAddress, signerOrProvider); 26 | return crv3CryptoPoolContract; 27 | } 28 | exports.getCrv3CryptoPoolContract = getCrv3CryptoPoolContract; 29 | function getSteCrvPoolContract(signerOrProvider) { 30 | var steCRVPoolAddress = "0xDC24316b9AE028F1497c275EB9192a3Ea0f67022"; 31 | var steCrvPoolContract = CurveStethPool__factory_1.CurveStethPool__factory.connect(steCRVPoolAddress, signerOrProvider); 32 | return steCrvPoolContract; 33 | } 34 | exports.getSteCrvPoolContract = getSteCrvPoolContract; 35 | -------------------------------------------------------------------------------- /dist/src/prices/curve/stablePools.d.ts: -------------------------------------------------------------------------------- 1 | import { Provider } from "@ethersproject/providers"; 2 | import { Signer } from "ethers"; 3 | import { CRVLUSD } from "elf-contracts-typechain/dist/types/CRVLUSD"; 4 | export declare function getCurveStablePoolContractsByAddress( 5 | chainName: string, 6 | signerOrProvider: Signer | Provider 7 | ): Record; 8 | export declare function isCurveStablePool( 9 | chainName: string, 10 | address: string 11 | ): boolean; 12 | -------------------------------------------------------------------------------- /dist/src/prices/curve/stablePools.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.isCurveStablePool = exports.getCurveStablePoolContractsByAddress = void 0; 4 | var CRVLUSD__factory_1 = require("elf-contracts-typechain/dist/types/factories/CRVLUSD__factory"); 5 | function getCurveStablePoolContractsByAddress(chainName, signerOrProvider) { 6 | var _a; 7 | // eslint-disable-next-line @typescript-eslint/no-var-requires 8 | var AddressesJson = require("elf-tokenlist/dist/" + chainName + ".addresses.json"); 9 | /** 10 | * Curve stable pools provide a `get_virtual_price` method for getting the price. 11 | */ 12 | var _b = AddressesJson.addresses, eurscrvAddress = _b.eurscrvAddress, crvalusdAddress = _b["alusd3crv-fAddress"], crvlusdAddress = _b["lusd3crv-fAddress"], crvmimAddress = _b["mim-3lp3crv-fAddress"]; 13 | var crvalusdContract = CRVLUSD__factory_1.CRVLUSD__factory.connect( 14 | // Note: the CRVLUSD_factory is the same, so it can handle both alusd and lusd pools. 15 | crvalusdAddress, signerOrProvider); 16 | var crvlusdContract = CRVLUSD__factory_1.CRVLUSD__factory.connect(crvlusdAddress, signerOrProvider); 17 | var crvMimContract = CRVLUSD__factory_1.CRVLUSD__factory.connect(crvmimAddress, signerOrProvider); 18 | var CRVEursPoolAddress = "0x0Ce6a5fF5217e38315f87032CF90686C96627CAA"; 19 | var crvEursPoolContract = CRVLUSD__factory_1.CRVLUSD__factory.connect(CRVEursPoolAddress, signerOrProvider); 20 | var curveVirtualPriceContractsByAddress = Object.freeze((_a = {}, 21 | _a[eurscrvAddress] = crvEursPoolContract, 22 | _a[crvalusdAddress] = crvalusdContract, 23 | _a[crvlusdAddress] = crvlusdContract, 24 | _a[crvmimAddress] = crvMimContract, 25 | _a)); 26 | return curveVirtualPriceContractsByAddress; 27 | } 28 | exports.getCurveStablePoolContractsByAddress = getCurveStablePoolContractsByAddress; 29 | function isCurveStablePool(chainName, address) { 30 | // eslint-disable-next-line @typescript-eslint/no-var-requires 31 | var AddressesJson = require("elf-tokenlist/dist/" + chainName + ".addresses.json"); 32 | /** 33 | * Curve stable pools provide a `get_virtual_price` method for getting the price. 34 | */ 35 | var _a = AddressesJson.addresses, eurscrvAddress = _a.eurscrvAddress, crvalusdAddress = _a["alusd3crv-fAddress"], crvlusdAddress = _a["lusd3crv-fAddress"], crvmimAddress = _a["mim-3lp3crv-fAddress"]; 36 | return [ 37 | eurscrvAddress, 38 | crvalusdAddress, 39 | crvlusdAddress, 40 | crvmimAddress, 41 | ].includes(address); 42 | } 43 | exports.isCurveStablePool = isCurveStablePool; 44 | -------------------------------------------------------------------------------- /dist/src/prices/getTokenPrice.d.ts: -------------------------------------------------------------------------------- 1 | import { Currency, Money } from "ts-money"; 2 | import { Provider } from "@ethersproject/providers"; 3 | import { Signer, BigNumber } from "ethers"; 4 | import { ERC20 } from "elf-contracts-typechain/dist/types/ERC20"; 5 | export declare const NUM_ETH_DECIMALS = 18; 6 | export declare const ONE_ETHER: BigNumber; 7 | export declare function getTokenPrice( 8 | chainName: string, 9 | contract: TContract, 10 | currency: Currency, 11 | signerOrProvider: Signer | Provider 12 | ): Promise; 13 | interface FormatBalanceOptions { 14 | /** 15 | * Whether or not to include commas when formatting, default is true. 16 | * Example: "1,000,000" 17 | */ 18 | formatCommas: boolean; 19 | } 20 | export declare function formatBalance( 21 | balance: BigNumber | undefined, 22 | decimals: number | undefined, 23 | options?: FormatBalanceOptions 24 | ): string; 25 | export {}; 26 | -------------------------------------------------------------------------------- /dist/src/swap.d.ts: -------------------------------------------------------------------------------- 1 | import { 2 | BigNumber, 3 | ContractTransaction, 4 | PayableOverrides, 5 | Signer, 6 | } from "ethers"; 7 | export declare const BALANCER_ETH_SENTINEL = 8 | "0x0000000000000000000000000000000000000000"; 9 | export declare enum SwapKind { 10 | GIVEN_IN = 0, 11 | GIVEN_OUT = 1, 12 | } 13 | export interface SingleSwap { 14 | poolId: string; 15 | kind: SwapKind; 16 | assetIn: string; 17 | assetOut: string; 18 | amount: BigNumber; 19 | userData: string; 20 | } 21 | /** 22 | * 23 | * @param signer 24 | * @param sender 25 | * @param recipient 26 | * @param poolId 27 | * @param tokenInAddress 28 | * @param tokenOutAddress 29 | * @param balancerVaultAddress 30 | * @param amount 31 | * @param kind 32 | * @param limit 33 | * @param expirationInSeconds 34 | * @param useETH 35 | * @param wethAddress 36 | * @param fromInternalBalance 37 | * @param toInternalBalance 38 | */ 39 | export declare function swap( 40 | signer: Signer, 41 | sender: string, 42 | recipient: string, 43 | poolId: string, 44 | tokenInAddress: string, 45 | tokenOutAddress: string, 46 | balancerVaultAddress: string, 47 | amount: BigNumber, 48 | kind: SwapKind, 49 | limit: BigNumber, 50 | overrides?: PayableOverrides, 51 | expirationInSeconds?: number, 52 | useETH?: boolean, 53 | wethAddress?: string, 54 | fromInternalBalance?: boolean, 55 | toInternalBalance?: boolean 56 | ): Promise; 57 | -------------------------------------------------------------------------------- /elf.default.env: -------------------------------------------------------------------------------- 1 | export MAINNET_PROVIDER_URL= 2 | export GOERLI_PROVIDER_URL= 3 | export PRIVATE_KEY= 4 | -------------------------------------------------------------------------------- /examples/contractAddresses.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Element Finance, Inc 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { ethers } from "hardhat"; 18 | import { 19 | getElementDeploymentAddresses, 20 | getElementTermFactoryAddresses, 21 | getElementTermAddresses, 22 | getElementPtPoolAddresses, 23 | } from "../src/helpers/getElementAddresses"; 24 | import { getTerms } from "../src/helpers/getTerms"; 25 | import { 26 | getTermTokenSymbols, 27 | TermTokenSymbolsResult, 28 | } from "../src/helpers/getTermTokenSymbols"; 29 | import { DeploymentAddresses } from "../typechain/DeploymentAddresses"; 30 | 31 | async function main() { 32 | const [signer] = await ethers.getSigners(); 33 | 34 | // get the official list of Element deployed addresses. 35 | const deploymentAddresses: DeploymentAddresses = ( 36 | await getElementDeploymentAddresses( 37 | "https://raw.githubusercontent.com/element-fi/elf-deploy/main/addresses/goerli.json" 38 | ) 39 | ); 40 | console.log(deploymentAddresses); 41 | 42 | // get the factories used to deploy each term 43 | // Note: because not every term is necessarily deployed from the same TermFactory (e.g. if the sc code was upgraded) 44 | // it is better to use this method to iterate through all terms and collect the associated factories. 45 | const elementTermFactoryAddresses = 46 | getElementTermFactoryAddresses(deploymentAddresses); 47 | console.log("Element TermFactories: " + elementTermFactoryAddresses); 48 | 49 | // get all official element term addresses 50 | const elementTermAddresses = getElementTermAddresses(deploymentAddresses); 51 | console.log("\nElement Terms: " + elementTermAddresses); 52 | 53 | // get all terms emitted by all officially deployed Element TermFactories 54 | // Note: this will include terms that were not "officially" deployed by 55 | // Element so they could be misconfigured 56 | const termAddresses: string[][] = []; 57 | await Promise.all( 58 | elementTermFactoryAddresses.map(async (termFactoryAddress) => { 59 | termAddresses.push(await getTerms(termFactoryAddress, null, signer)); 60 | }) 61 | ); 62 | console.log("\nAll Terms: " + termAddresses); 63 | 64 | // get all official element PTPool addresses 65 | const elementPtPoolAddresses = getElementPtPoolAddresses(deploymentAddresses); 66 | console.log("\nElement PT Pools: " + elementPtPoolAddresses); 67 | 68 | // get all official element YTPool addresses 69 | const elementYtPoolAddresses = getElementPtPoolAddresses(deploymentAddresses); 70 | console.log("\nElement YT Pools: " + elementYtPoolAddresses); 71 | 72 | // get the symbols of a particular term address 73 | const termTokenSymbols: TermTokenSymbolsResult = await getTermTokenSymbols( 74 | elementTermAddresses[0], 75 | signer 76 | ); 77 | console.log( 78 | "\nPrincipal Token Symbol: " + termTokenSymbols.principalTokenSymbol 79 | ); 80 | console.log("Yield Token Symbol: " + termTokenSymbols.yieldTokenSymbol); 81 | } 82 | 83 | main(); 84 | -------------------------------------------------------------------------------- /examples/interestPerToken.ts: -------------------------------------------------------------------------------- 1 | import { ethers } from "hardhat"; 2 | import { getInterestPerToken } from "../src/helpers/getInterestPerToken"; 3 | import { mainnetTokenList, TokenTag } from "elf-tokenlist"; 4 | import { Tranche__factory } from "elf-contracts-typechain"; 5 | 6 | async function main() { 7 | const [signer] = await ethers.getSigners(); 8 | 9 | const trancheAddresses = mainnetTokenList.tokens 10 | .filter((tokenInfo) => 11 | tokenInfo.tags?.some((tag) => tag === TokenTag.PRINCIPAL) 12 | ) 13 | .map((tokenInfo) => tokenInfo.address); 14 | 15 | const interestPerTokenList = await Promise.all( 16 | trancheAddresses.map((trancheAddress) => 17 | getInterestPerToken(trancheAddress, signer) 18 | ) 19 | ); 20 | 21 | const trancheSymbols = await Promise.all( 22 | trancheAddresses.map(async (trancheAddress) => { 23 | const tranche = Tranche__factory.connect(trancheAddress, signer); 24 | return await tranche.symbol(); 25 | }) 26 | ); 27 | 28 | interestPerTokenList.forEach((amount, idx) => { 29 | console.log(`${ethers.utils.formatEther(amount)} - ${trancheSymbols[idx]}`); 30 | }); 31 | } 32 | 33 | main() 34 | .then(() => process.exit(0)) 35 | .catch((error) => { 36 | console.error(error); 37 | process.exit(1); 38 | }); 39 | -------------------------------------------------------------------------------- /examples/mint.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Element Finance, Inc 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { ethers } from "hardhat"; 18 | import { 19 | getElementDeploymentAddresses, 20 | getElementTermAddresses, 21 | } from "../src/helpers/getElementAddresses"; 22 | import { 23 | mintWithUserProxy, 24 | getTermExpiration, 25 | getTermPosition, 26 | ETH_SENTINEL_ADDRESS, 27 | } from "../src/mint"; 28 | import { getTermByTokenSymbol } from "../src/helpers/getTermByTokenSymbol"; 29 | import { DeploymentAddresses } from "../typechain/DeploymentAddresses"; 30 | import { BigNumber } from "ethers"; 31 | import { ERC20Permit__factory } from "elf-contracts-typechain"; 32 | 33 | async function main() { 34 | const [signer] = await ethers.getSigners(); 35 | // get the official list of Element deployed addresses. 36 | const deploymentAddresses: DeploymentAddresses = ( 37 | await getElementDeploymentAddresses( 38 | "https://raw.githubusercontent.com/element-fi/elf-deploy/main/addresses/goerli.json" 39 | ) 40 | ); 41 | 42 | const userProxyAddress = deploymentAddresses.userProxy; 43 | // get all official element term addresses 44 | const elementTermAddresses = getElementTermAddresses(deploymentAddresses); 45 | // find the term that matches the token symbol 46 | const termAddress = await getTermByTokenSymbol( 47 | elementTermAddresses, 48 | "eP:eyUSDC:06-AUG-21-GMT", 49 | signer 50 | ); 51 | const termExpiration = await getTermExpiration(termAddress, signer); 52 | const termPosition = await getTermPosition(termAddress, signer); 53 | const baseAssetAmount = "1"; // 1 USDC 54 | const baseAssetAddress = deploymentAddresses.tokens.usdc; 55 | const tokenContract = ERC20Permit__factory.connect(baseAssetAddress, signer); 56 | const approval = await tokenContract.approve( 57 | userProxyAddress, 58 | ethers.utils.parseUnits("1000000", 6), 59 | { gasPrice: BigNumber.from("999000000000") } 60 | ); 61 | console.log(await approval.wait(1)); 62 | const tokenDecimals = await tokenContract.decimals(); 63 | const gasPrice = BigNumber.from("999000000000"); 64 | const overrides = 65 | baseAssetAddress === ETH_SENTINEL_ADDRESS 66 | ? { value: baseAssetAmount, gasPrice: gasPrice } 67 | : { gasPrice: gasPrice }; 68 | const result = await mintWithUserProxy( 69 | userProxyAddress, 70 | termExpiration.toNumber(), 71 | termPosition, 72 | baseAssetAmount, 73 | baseAssetAddress, 74 | tokenDecimals, 75 | signer, 76 | overrides 77 | ); 78 | console.log(await result.wait(1)); 79 | } 80 | 81 | main(); 82 | -------------------------------------------------------------------------------- /examples/poolDetails.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Element Finance, Inc 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { ethers } from "hardhat"; 18 | import { getTotalSupply } from "../src/helpers/getTotalSupply"; 19 | import { getReserves } from "../src/helpers/getReserves"; 20 | import { calcSpotPricePt, calcSpotPriceYt } from "../src/helpers/calcSpotPrice"; 21 | import { getSecondsUntilExpiration } from "../src/helpers/getSecondsUntilExpiration"; 22 | import { getLatestBlockTimestamp } from "../src/helpers/getLatestBlockTimestamp"; 23 | import { getUnitSeconds } from "../src/helpers/getUnitSeconds"; 24 | import { calcFixedAPR } from "../src/helpers/calcFixedAPR"; 25 | 26 | async function main() { 27 | const balVault = "0x65748E8287Ce4B9E6D83EE853431958851550311"; // balancer vault address 28 | const base = "0x9A1000D492d40bfccbc03f413A48F5B6516Ec0Fd".toLowerCase(); // base token address 29 | const [signer] = await ethers.getSigners(); 30 | 31 | // calculate principal token spot price 32 | const ptPool = "0x9eB7F54C0eCc4d0D2dfF28a1276e36d598F2B0D1"; // principal token Pool address 33 | const totalSupply = await getTotalSupply(ptPool, signer); 34 | let reserves = await getReserves(ptPool, balVault, signer); 35 | const ptIndex = reserves.tokens[0].toLowerCase() == base ? 1 : 0; 36 | let baseIndex = reserves.tokens[0].toLowerCase() == base ? 0 : 1; 37 | const ptReserves = reserves.balances[ptIndex]; 38 | let baseReserves = reserves.balances[baseIndex]; 39 | const baseDecimals = reserves.decimals[baseIndex]; 40 | const blockTimestamp = await getLatestBlockTimestamp(); 41 | const timeRemainingSeconds = await getSecondsUntilExpiration( 42 | ptPool, 43 | signer, 44 | blockTimestamp 45 | ); 46 | const unitSeconds = await getUnitSeconds(ptPool, signer); 47 | const ptSpotPrice = calcSpotPricePt( 48 | baseReserves.toString(), 49 | ptReserves.toString(), 50 | totalSupply.toString(), 51 | timeRemainingSeconds, 52 | unitSeconds, 53 | baseDecimals 54 | ); 55 | console.log("\nPrincipal Token"); 56 | console.log(`totalSupply: ${totalSupply}`); 57 | console.log(`ptReserves: ${ptReserves}`); 58 | console.log(`baseReserves: ${baseReserves}`); 59 | console.log(`timeRemainingSeconds: ${timeRemainingSeconds}`); 60 | console.log(`unitSeconds: ${unitSeconds}`); 61 | console.log(`ptSpotPrice: ${ptSpotPrice}`); 62 | 63 | // calculate yield token spot price 64 | const ytPool = "0xD75bfF2444FF738d443066ff4688691e6852b217"; // yield token Pool address 65 | reserves = await getReserves(ytPool, balVault, signer); 66 | const ytIndex = reserves.tokens[0].toLowerCase() == base ? 1 : 0; 67 | baseIndex = reserves.tokens[0].toLowerCase() == base ? 0 : 1; 68 | const ytReserves = reserves.balances[ytIndex]; 69 | baseReserves = reserves.balances[baseIndex]; 70 | const ytSpotPrice = calcSpotPriceYt( 71 | baseReserves.toString(), 72 | ytReserves.toString() 73 | ); 74 | console.log("\nYield Token"); 75 | console.log(`ytReserves: ${ytReserves}`); 76 | console.log(`baseReserves: ${baseReserves}`); 77 | console.log(`ytSpotPrice: ${ytSpotPrice}`); 78 | 79 | // calculate fixed APR 80 | const fixedAPR = calcFixedAPR(ptSpotPrice, timeRemainingSeconds); 81 | console.log("\nFixed APR"); 82 | console.log(`fixedAPR: ${fixedAPR}`); 83 | } 84 | 85 | main(); 86 | -------------------------------------------------------------------------------- /examples/poolId.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Element Finance, Inc 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { ethers } from "hardhat"; 18 | import { getPoolId } from "../src/helpers/getPoolId"; 19 | 20 | async function main() { 21 | const [signer] = await ethers.getSigners(); 22 | 23 | let poolID = await getPoolId( 24 | "0x9eB7F54C0eCc4d0D2dfF28a1276e36d598F2B0D1", 25 | signer 26 | ); 27 | console.log("Pool ID: " + poolID); 28 | 29 | poolID = await getPoolId( 30 | "0xD75bfF2444FF738d443066ff4688691e6852b217", 31 | signer 32 | ); 33 | console.log("Pool ID: " + poolID); 34 | 35 | poolID = await getPoolId( 36 | "0x5941DB4d6C500C4FFa57c359eE0C55c6b41D0b61", 37 | signer 38 | ); 39 | console.log("Pool ID: " + poolID); 40 | 41 | poolID = await getPoolId( 42 | "0xcF6894C48c2AF3ddD433CC1EDfEfC74e654cC9B4", 43 | signer 44 | ); 45 | console.log("Pool ID: " + poolID); 46 | } 47 | 48 | main(); 49 | -------------------------------------------------------------------------------- /examples/swap.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Element Finance, Inc 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { ethers } from "hardhat"; 18 | import { 19 | getElementDeploymentAddresses, 20 | getElementTermAddresses, 21 | getPoolIdByTermAddress, 22 | PoolType, 23 | } from "../src/helpers/getElementAddresses"; 24 | import { swap, SwapKind, BALANCER_ETH_SENTINEL } from "../src/swap"; 25 | import { getTermByTokenSymbol } from "../src/helpers/getTermByTokenSymbol"; 26 | import { DeploymentAddresses } from "../typechain/DeploymentAddresses"; 27 | import { BigNumber, PayableOverrides } from "ethers"; 28 | import { ERC20Permit__factory } from "elf-contracts-typechain"; 29 | 30 | async function main() { 31 | const [signer] = await ethers.getSigners(); 32 | const sender = signer.address; 33 | const recipient = signer.address; 34 | // get the official list of Element deployed addresses. 35 | const deploymentAddresses: DeploymentAddresses = ( 36 | await getElementDeploymentAddresses( 37 | "https://raw.githubusercontent.com/element-fi/elf-deploy/main/addresses/goerli.json" 38 | ) 39 | ); 40 | // get all official element term addresses 41 | const elementTermAddresses = getElementTermAddresses(deploymentAddresses); 42 | // find the term that matches the token symbol 43 | const termAddress = await getTermByTokenSymbol( 44 | elementTermAddresses, 45 | "eP:eyUSDC:06-AUG-21-GMT", 46 | signer 47 | ); 48 | // get the poolid associated with the term and PoolType 49 | const poolId = await getPoolIdByTermAddress( 50 | termAddress, 51 | deploymentAddresses, 52 | PoolType.PT 53 | ); 54 | const tokenInAddress = deploymentAddresses.tokens.usdc; 55 | const tokenOutAddress = termAddress; 56 | const balancerVaultAddress = deploymentAddresses.balancerVault; 57 | const tokenContract = ERC20Permit__factory.connect(tokenInAddress, signer); 58 | const approval = await tokenContract.approve( 59 | balancerVaultAddress, 60 | ethers.utils.parseUnits("1000000", 6), 61 | { gasPrice: BigNumber.from("999000000000") } 62 | ); 63 | console.log(await approval.wait(1)); 64 | const amount = BigNumber.from("100000"); // .1 USDC 65 | const kind = SwapKind.GIVEN_IN; 66 | const limit = BigNumber.from("99000"); 67 | const gasPrice = BigNumber.from("999000000000"); 68 | const overrides: PayableOverrides | undefined = 69 | tokenInAddress === BALANCER_ETH_SENTINEL 70 | ? { value: amount, gasPrice: gasPrice } 71 | : { gasPrice: gasPrice }; 72 | const result = await swap( 73 | signer, 74 | sender, 75 | recipient, 76 | poolId, 77 | tokenInAddress, 78 | tokenOutAddress, 79 | balancerVaultAddress, 80 | amount, 81 | kind, 82 | limit, 83 | overrides 84 | ); 85 | console.log(await result.wait(1)); 86 | } 87 | 88 | main(); 89 | -------------------------------------------------------------------------------- /examples/tvl.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Element Finance, Inc 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { ethers } from "hardhat"; 18 | import { 19 | calcTotalValueLocked, 20 | calcTotalValueLockedForTerm, 21 | } from "../src/helpers/calcTotalValueLocked"; 22 | import { 23 | initTokenList, 24 | getPrincipalTokenInfos, 25 | getAssetProxyTokenInfos, 26 | } from "../src/helpers/getTokenInfo"; 27 | import { Currencies, Money } from "ts-money"; 28 | import { ERC20 } from "elf-contracts-typechain/dist/types/ERC20"; 29 | import { getUnderlyingContractsByAddress } from "../src/helpers/getUnderlyingContractsByAddress"; 30 | import { getTokenPrice } from "../src/prices/getTokenPrice"; 31 | 32 | async function main() { 33 | const [signer] = await ethers.getSigners(); 34 | const chainName = "mainnet"; 35 | const tvl = await calcTotalValueLocked(chainName, signer); 36 | console.log("Total TVL: " + tvl.amount / 100); 37 | 38 | const currency = Currencies.USD; 39 | const { tokenList, addressesJson, tokenInfoByAddress } = 40 | initTokenList(chainName); 41 | const assetProxyTokenInfos = getAssetProxyTokenInfos(tokenList.tokens); 42 | const principalTokenInfos = getPrincipalTokenInfos(tokenList.tokens); 43 | const results = await Promise.all( 44 | principalTokenInfos.map(async (tokenInfo) => { 45 | const underlyingContractsByAddress = getUnderlyingContractsByAddress( 46 | chainName, 47 | signer 48 | ); 49 | const baseAssetContract = 50 | underlyingContractsByAddress[tokenInfo.extensions.underlying]; 51 | const baseAssetPrice = await getTokenPrice( 52 | chainName, 53 | baseAssetContract as ERC20, 54 | currency, 55 | signer 56 | ); 57 | const termName = await (baseAssetContract as ERC20).name(); 58 | const termTvl = await calcTotalValueLockedForTerm( 59 | tokenInfo, 60 | addressesJson.addresses.balancerVaultAddress, 61 | underlyingContractsByAddress, 62 | assetProxyTokenInfos, 63 | tokenList.tokens, 64 | tokenInfoByAddress, 65 | baseAssetPrice, 66 | signer 67 | ); 68 | return { termName, termTvl }; 69 | }) 70 | ); 71 | 72 | results.forEach((result) => { 73 | console.log(result.termName + " TVL: " + result.termTvl.amount); 74 | }); 75 | } 76 | 77 | main(); 78 | -------------------------------------------------------------------------------- /hardhat.config.test.ts: -------------------------------------------------------------------------------- 1 | import "@nomiclabs/hardhat-waffle"; 2 | import "hardhat-gas-reporter"; 3 | 4 | import { HardhatUserConfig } from "hardhat/config"; 5 | 6 | import config from "./hardhat.config"; 7 | 8 | const testConfig: HardhatUserConfig = { 9 | ...config, 10 | networks: { 11 | ...config.networks, 12 | hardhat: { 13 | ...config?.networks?.hardhat, 14 | allowUnlimitedContractSize: true, 15 | }, 16 | }, 17 | }; 18 | 19 | export default testConfig; 20 | -------------------------------------------------------------------------------- /hardhat.config.ts: -------------------------------------------------------------------------------- 1 | import "@nomiclabs/hardhat-waffle"; 2 | import "hardhat-typechain"; 3 | import "hardhat-gas-reporter"; 4 | 5 | import { HardhatUserConfig } from "hardhat/config"; 6 | 7 | const MAINNET_PROVIDER_URL = process.env.MAINNET_PROVIDER_URL || ""; 8 | const GOERLI_PROVIDER_URL = process.env.GOERLI_PROVIDER_URL || ""; 9 | const PRIVATE_KEY = 10 | process.env.PRIVATE_KEY || 11 | "0000000000000000000000000000000000000000000000000000000000000000"; 12 | 13 | const config: HardhatUserConfig = { 14 | defaultNetwork: "hardhat", 15 | solidity: { 16 | compilers: [ 17 | { 18 | version: "0.7.1", 19 | settings: { 20 | optimizer: { 21 | enabled: true, 22 | runs: 10000, 23 | }, 24 | }, 25 | }, 26 | { 27 | version: "0.8.0", 28 | settings: { 29 | optimizer: { 30 | enabled: true, 31 | runs: 7500, 32 | }, 33 | }, 34 | }, 35 | ], 36 | overrides: { 37 | "contracts/balancer-core-v2/vault/Vault.sol": { 38 | version: "0.7.1", 39 | settings: { 40 | optimizer: { 41 | enabled: true, 42 | runs: 400, 43 | }, 44 | }, 45 | }, 46 | "contracts/balancer-core-v2/pools/weighted/WeightedPoolFactory.sol": { 47 | version: "0.7.1", 48 | settings: { 49 | optimizer: { 50 | enabled: true, 51 | runs: 800, 52 | }, 53 | }, 54 | }, 55 | }, 56 | }, 57 | mocha: { timeout: 0 }, 58 | networks: { 59 | goerli: { 60 | url: `${GOERLI_PROVIDER_URL}`, 61 | accounts: [`0x${PRIVATE_KEY}`], 62 | }, 63 | mainnet: { 64 | url: `${MAINNET_PROVIDER_URL}`, 65 | accounts: [`0x${PRIVATE_KEY}`], 66 | }, 67 | hardhat: { 68 | forking: { 69 | url: "https://eth-mainnet.alchemyapi.io/v2/kwjMP-X-Vajdk1ItCfU-56Uaq1wwhamK", 70 | blockNumber: 13475006, 71 | }, 72 | }, 73 | }, 74 | }; 75 | 76 | export default config; 77 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "elf-sdk", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "dist/src/index.js", 6 | "types": "dist/src/index.d.ts", 7 | "scripts": { 8 | "update-elf-contracts-typechain": "npm install git+https://github.com/element-fi/elf-contracts-typechain.git", 9 | "update-elf-tokenlist": "npm install git+https://github.com/element-fi/elf-tokenlist.git", 10 | "build": "sh scripts/build.sh", 11 | "test": "npx hardhat compile && rm ./typechain/index.ts && npx hardhat test --config hardhat.config.test.ts ./test/*.ts", 12 | "style-check": "npx prettier --check .", 13 | "style-fix": "npx prettier --write .", 14 | "lint-check": "eslint .", 15 | "lint-fix": "eslint --fix .", 16 | "generate-interfaces": "npm run build && npx ts-node scripts/generate-interfaces.ts" 17 | }, 18 | "_moduleAliases": { 19 | "test": "./test", 20 | "src": "./src" 21 | }, 22 | "author": "", 23 | "license": "ISC", 24 | "devDependencies": { 25 | "@nomiclabs/hardhat-ethers": "^2.0.1", 26 | "@nomiclabs/hardhat-waffle": "^2.0.1", 27 | "@typechain/ethers-v5": "^5.0.0", 28 | "@types/chai-almost": "^1.0.1", 29 | "@types/lodash.keyby": "^4.6.6", 30 | "@types/mocha": "^8.2.0", 31 | "@types/node": "^10.17.60", 32 | "@typescript-eslint/eslint-plugin": "^4.27.0", 33 | "@typescript-eslint/parser": "^4.27.0", 34 | "chai": "^4.2.0", 35 | "chai-almost": "^1.0.1", 36 | "eslint": "^7.28.0", 37 | "ethereum-waffle": "^3.2.2", 38 | "ethers": "^5.0.29", 39 | "hardhat": "^2.6.4", 40 | "hardhat-gas-reporter": "^1.0.4", 41 | "hardhat-typechain": "^0.3.4", 42 | "json-to-ts": "^1.7.0", 43 | "prettier": "^2.2.1", 44 | "ts-generator": "^0.1.1", 45 | "ts-node": "^9.1.1", 46 | "typechain": "^4.0.1", 47 | "typescript": "^4.4.3" 48 | }, 49 | "dependencies": { 50 | "axios": "^0.24.0", 51 | "date-fns": "^2.25.0", 52 | "elf-contracts-typechain": "git+https://github.com/element-fi/elf-contracts-typechain.git", 53 | "elf-tokenlist": "git+https://github.com/element-fi/elf-tokenlist.git", 54 | "lodash.keyby": "^4.6.0", 55 | "ts-money": "^0.4.6", 56 | "tsc": "^2.0.3" 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /scripts/build.sh: -------------------------------------------------------------------------------- 1 | rm -rf compiled 2 | 3 | npx hardhat compile 4 | 5 | tsc --project tsconfig.json 6 | 7 | rm ./typechain/index.ts 8 | 9 | mkdir -p dist 10 | cp -R compiled/* dist/ -------------------------------------------------------------------------------- /scripts/generate-interfaces.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Element Finance, Inc 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | import * as https from "https"; 17 | import JsonToTS from "json-to-ts"; 18 | import * as fs from "fs"; 19 | 20 | // this url should point to either a goerli.json or a mainnet.json. 21 | // ideally, they would both be checked against a schema to ensure they are the same 22 | const url = 23 | "https://raw.githubusercontent.com/element-fi/elf-deploy/main/addresses/goerli.json"; 24 | https 25 | .get(url, (res) => { 26 | let body = ""; 27 | 28 | res.on("data", (chunk) => { 29 | body += chunk; 30 | }); 31 | 32 | res.on("end", () => { 33 | try { 34 | const json = JSON.parse(body); 35 | fs.mkdirSync("typechain", { recursive: true }); 36 | fs.appendFileSync("typechain/DeploymentAddresses.d.ts", " ", "utf8"); 37 | fs.truncateSync("typechain/DeploymentAddresses.d.ts"); 38 | JsonToTS(json, { rootName: "DeploymentAddresses" }).forEach( 39 | (typeInterface) => { 40 | fs.appendFileSync( 41 | "typechain/DeploymentAddresses.d.ts", 42 | "export ", 43 | "utf8" 44 | ); 45 | fs.appendFileSync( 46 | "typechain/DeploymentAddresses.d.ts", 47 | typeInterface, 48 | "utf8" 49 | ); 50 | fs.appendFileSync( 51 | "typechain/DeploymentAddresses.d.ts", 52 | "\n", 53 | "utf8" 54 | ); 55 | console.log(typeInterface); 56 | } 57 | ); 58 | } catch (error) { 59 | console.error(error.message); 60 | } 61 | }); 62 | }) 63 | .on("error", (error) => { 64 | console.error(error.message); 65 | }); 66 | -------------------------------------------------------------------------------- /src/constants/time.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Element Finance, Inc 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | export const ONE_MINUTE_IN_SECONDS = 60; 18 | export const ONE_HOUR_IN_SECONDS = 60 * ONE_MINUTE_IN_SECONDS; 19 | export const ONE_DAY_IN_SECONDS = 24 * ONE_HOUR_IN_SECONDS; 20 | export const ONE_WEEK_IN_SECONDS = 7 * ONE_DAY_IN_SECONDS; 21 | export const THIRTY_DAYS_IN_SECONDS = 30 * ONE_DAY_IN_SECONDS; 22 | export const SIX_MONTHS_IN_SECONDS = 26 * ONE_WEEK_IN_SECONDS; 23 | export const ONE_YEAR_IN_SECONDS = 365 * ONE_DAY_IN_SECONDS; 24 | 25 | export const ONE_MINUTE_IN_MILLISECONDS = 1000 * ONE_MINUTE_IN_SECONDS; 26 | export const ONE_HOUR_IN_MILLISECONDS = 60 * ONE_MINUTE_IN_MILLISECONDS; 27 | export const ONE_DAY_IN_MILLISECONDS = 24 * ONE_HOUR_IN_MILLISECONDS; 28 | export const ONE_WEEK_IN_MILLISECONDS = 7 * ONE_DAY_IN_MILLISECONDS; 29 | export const ONE_YEAR_IN_MILLISECONDS = 365 * ONE_DAY_IN_MILLISECONDS; 30 | export const THIRTY_DAYS_IN_MILLISECONDS = 30 * ONE_DAY_IN_MILLISECONDS; 31 | -------------------------------------------------------------------------------- /src/helpers/calcFixedAPR.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Element Finance, Inc 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { ONE_YEAR_IN_SECONDS } from "../../src/constants/time"; 18 | 19 | export function calcFixedAPR( 20 | spotPrice: number, 21 | secondsUntilMaturity: number 22 | ): number { 23 | if (secondsUntilMaturity > 0) { 24 | const timeRemaining = secondsUntilMaturity / ONE_YEAR_IN_SECONDS; 25 | return ((1 - spotPrice) / spotPrice / timeRemaining) * 100; 26 | } else { 27 | return 0; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/helpers/calcPoolSwap.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Element Finance, Inc 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | export function calcSwapOutGivenInCCPoolUnsafe( 18 | xAmount: string, 19 | xReserves: string, 20 | yReserves: string, 21 | totalSupply: string, 22 | timeRemainingSeconds: number, 23 | tParamSeconds: number, 24 | baseAssetIn: boolean 25 | ): number { 26 | const tS = +totalSupply; 27 | const amountX = +xAmount; 28 | 29 | let xR = +xReserves + tS; 30 | let yR = +yReserves; 31 | 32 | if (baseAssetIn) { 33 | xR = +xReserves; 34 | yR = +yReserves + tS; 35 | } 36 | 37 | const t = timeRemainingSeconds / tParamSeconds; 38 | 39 | const xBefore = xR ** (1 - t); 40 | const yBefore = yR ** (1 - t); 41 | 42 | const xAfter = (xR + amountX) ** (1 - t); 43 | 44 | // this is the real equation, make ascii art for it 45 | const yAfter = (xBefore + yBefore - xAfter) ** (1 / (1 - t)); 46 | 47 | const amountY = yR - yAfter; 48 | 49 | return amountY; 50 | } 51 | 52 | export function calcSwapInGivenOutCCPoolUnsafe( 53 | xAmount: string, 54 | xReserves: string, 55 | yReserves: string, 56 | totalSupply: string, 57 | timeRemainingSeconds: number, 58 | tParamSeconds: number, 59 | baseAssetIn: boolean 60 | ): number { 61 | const tS = +totalSupply; 62 | const amountX = +xAmount; 63 | 64 | let xR = +xReserves + tS; 65 | let yR = +yReserves; 66 | 67 | if (baseAssetIn) { 68 | xR = +xReserves; 69 | yR = +yReserves + tS; 70 | } 71 | 72 | const t = timeRemainingSeconds / tParamSeconds; 73 | 74 | const xBefore = xR ** (1 - t); 75 | const yBefore = yR ** (1 - t); 76 | 77 | const xAfter = (xR - amountX) ** (1 - t); 78 | 79 | // this is the real equation, make ascii art for it 80 | const yAfter = (xBefore + yBefore - xAfter) ** (1 / (1 - t)); 81 | 82 | const amountY = yAfter - yR; 83 | 84 | return amountY; 85 | } 86 | 87 | // Computes how many tokens can be taken out of a pool if `amountIn` are sent, given the current 88 | // balances and weights. In our case the weights are the same so we don't need to add them to our 89 | // calcs 90 | /********************************************************************************************** 91 | // outGivenIn // 92 | // aO = amountOut // 93 | // bO = balanceOut // 94 | // bI = balanceIn / / bI \ (wI / wO) \ // 95 | // aI = amountIn aO = bO * | 1 - | -------------------------- | ^ | // 96 | // wI = weightIn \ \ ( bI + aI ) / / // 97 | // wO = weightOut // 98 | **********************************************************************************************/ 99 | export function calcSwapOutGivenInWeightedPoolUnsafe( 100 | amountIn: string, 101 | balanceOut: string, 102 | balanceIn: string 103 | ): number { 104 | const aI = +amountIn; 105 | const bO = +balanceOut; 106 | const bI = +balanceIn; 107 | 108 | const amountOut = bO * (1 - bI / (bI + aI)); 109 | 110 | return amountOut; 111 | } 112 | 113 | // Computes how many tokens must be sent to a pool in order to take `amountOut`, given the current 114 | // balances and weights. In our case the weights are the same so we don't need to add them to our 115 | // calcs. 116 | /********************************************************************************************** 117 | // inGivenOut // 118 | // aO = amountOut // 119 | // bO = balanceOut // 120 | // bI = balanceIn / / bO \ (wO / wI) \ // 121 | // aI = amountIn aI = bI * | | -------------------------- | ^ - 1 | // 122 | // wI = weightIn \ \ ( bO - aO ) / / // 123 | // wO = weightOut // 124 | **********************************************************************************************/ 125 | export function calcSwapInGivenOutWeightedPoolUnsafe( 126 | amountOut: string, 127 | balanceOut: string, 128 | balanceIn: string 129 | ): number { 130 | const aO = +amountOut; 131 | const bO = +balanceOut; 132 | const bI = +balanceIn; 133 | 134 | const amountIn = bI * (bO / (bO - aO) - 1); 135 | 136 | return amountIn; 137 | } 138 | -------------------------------------------------------------------------------- /src/helpers/calcSpotPrice.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Element Finance, Inc 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | export function calcSpotPricePt( 18 | baseReserves: string, 19 | ptReserves: string, 20 | totalSupply: string, 21 | timeRemainingSeconds: number, 22 | tParamSeconds: number, 23 | decimals: number 24 | ): number { 25 | // normalize decimal places of precision to 18 26 | if (decimals < 0 || decimals > 18) { 27 | // return 0 if decimals fall outside the range between 0 and 18 28 | return 0; 29 | } 30 | const diff = 18 - decimals; 31 | const normalizedBaseReserves = +baseReserves * 10 ** diff; 32 | const normalizedPtReserves = +ptReserves * 10 ** diff; 33 | 34 | const t = timeRemainingSeconds / tParamSeconds; 35 | return (normalizedBaseReserves / (normalizedPtReserves + +totalSupply)) ** t; 36 | } 37 | 38 | export function calcSpotPriceYt( 39 | baseReserves: string, 40 | ytReserves: string 41 | ): number { 42 | return +baseReserves / +ytReserves; 43 | } 44 | -------------------------------------------------------------------------------- /src/helpers/getInterestPerToken.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Element Finance, Inc 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Provider } from "@ethersproject/providers"; 18 | import { 19 | Tranche__factory, 20 | YVaultAssetProxy__factory, 21 | } from "elf-contracts-typechain"; 22 | import { BigNumber, ethers, Signer } from "ethers"; 23 | 24 | const { Zero } = ethers.constants; 25 | /** 26 | * returns the yield accrued per interest token for a given term 27 | * @param termAddress the address of the term 28 | * @param signerOrProvider 29 | * @returns a promise of BigNumber in wei 30 | */ 31 | export async function getInterestPerToken( 32 | termAddress: string, 33 | signerOrProvider: Signer | Provider 34 | ): Promise { 35 | const tranche = Tranche__factory.connect(termAddress, signerOrProvider); 36 | 37 | const balanceOfUnderlying = await tranche.valueSupplied(); 38 | const wrappedPositionAddress = await tranche.position(); 39 | const wrappedPosition = YVaultAssetProxy__factory.connect( 40 | wrappedPositionAddress, 41 | signerOrProvider 42 | ); 43 | const valueOfSharesInUnderlying = await wrappedPosition.balanceOfUnderlying( 44 | tranche.address 45 | ); 46 | 47 | const interestSupply = await tranche.interestSupply(); 48 | 49 | const accumulatedInterest = 50 | valueOfSharesInUnderlying.sub(balanceOfUnderlying); 51 | 52 | return !interestSupply.eq(Zero) 53 | ? accumulatedInterest.mul(ethers.constants.WeiPerEther).div(interestSupply) // precision by expansion 54 | : Zero; 55 | } 56 | -------------------------------------------------------------------------------- /src/helpers/getLatestBlockTimestamp.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Element Finance, Inc 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { providers } from "ethers"; 18 | 19 | /** 20 | * Get timestamp of the latest block 21 | * @returns the timestamp of the latest block 22 | */ 23 | export async function getLatestBlockTimestamp(): Promise { 24 | const provider = providers.getDefaultProvider(); 25 | const blockNumber = await provider.getBlockNumber(); 26 | const block = await provider.getBlock(blockNumber); 27 | return block.timestamp; 28 | } 29 | -------------------------------------------------------------------------------- /src/helpers/getOpenTerms.ts: -------------------------------------------------------------------------------- 1 | import { Provider } from "@ethersproject/providers"; 2 | import { TrancheFactory__factory } from "elf-contracts-typechain"; 3 | import { Signer } from "ethers"; 4 | import { getLatestBlockTimestamp } from "./getLatestBlockTimestamp"; 5 | 6 | /** 7 | * Returns an array of not expired tranche addresses. 8 | * 9 | * @param trancheFactoryAddress The TrancheFactory that deployed the tranches 10 | * @returns a promise of an array of tranche addresses 11 | */ 12 | 13 | export async function getOpenTerms( 14 | trancheFactoryAddress: string, 15 | signerOrProvider: Signer | Provider 16 | ): Promise { 17 | const trancheFactoryContract = TrancheFactory__factory.connect( 18 | trancheFactoryAddress, 19 | signerOrProvider 20 | ); 21 | 22 | const queryFilter = trancheFactoryContract.filters.TrancheCreated( 23 | null, 24 | null, 25 | null 26 | ); 27 | 28 | const trancheEvents = await trancheFactoryContract.queryFilter(queryFilter); 29 | const timestamp = await getLatestBlockTimestamp(); 30 | 31 | const notExpiredTranches: string[] = trancheEvents 32 | .filter((event) => event.args?.expiration.toNumber() > timestamp) 33 | .map((event) => event.args?.trancheAddress); 34 | 35 | return notExpiredTranches; 36 | } 37 | -------------------------------------------------------------------------------- /src/helpers/getPoolId.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Element Finance, Inc 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Signer } from "ethers"; 18 | import { Provider } from "@ethersproject/providers"; 19 | import { BasePool__factory } from "elf-contracts-typechain"; 20 | 21 | /** 22 | * Returns the PoolId for a given pool. 23 | * @param poolAddress any pool with a getPoolId method 24 | * @param signerOrProvider 25 | * @returns a promise for a poolId 26 | */ 27 | export async function getPoolId( 28 | poolAddress: string, 29 | signerOrProvider: Signer | Provider 30 | ): Promise { 31 | const poolContract = BasePool__factory.connect(poolAddress, signerOrProvider); 32 | return poolContract.getPoolId(); 33 | } 34 | -------------------------------------------------------------------------------- /src/helpers/getReserves.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Element Finance, Inc 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Provider } from "@ethersproject/providers"; 18 | import { 19 | Vault__factory, 20 | BasePool__factory, 21 | ERC20__factory, 22 | } from "elf-contracts-typechain"; 23 | import { BigNumber, Signer } from "ethers"; 24 | 25 | export interface ReservesResult { 26 | /** 27 | * addresses of tokens 28 | */ 29 | tokens: string[]; 30 | /** 31 | * balances of tokens in same order as tokens 32 | */ 33 | balances: BigNumber[]; 34 | /** 35 | * decimals of tokens in same order as tokens 36 | */ 37 | decimals: number[]; 38 | } 39 | /** 40 | * Returns the reserves for a given pool. 41 | * @param poolAddress any pool with a getPoolId method 42 | * @param balancerVaultAddress the address of the balancer v2 vault 43 | * @param signerOrProvider 44 | */ 45 | export async function getReserves( 46 | poolAddress: string, 47 | balancerVaultAddress: string, 48 | signerOrProvider: Signer | Provider 49 | ): Promise { 50 | const balancerVault = Vault__factory.connect( 51 | balancerVaultAddress, 52 | signerOrProvider 53 | ); 54 | const poolContract = BasePool__factory.connect(poolAddress, signerOrProvider); 55 | const poolId = await poolContract.getPoolId(); 56 | const poolTokens = await balancerVault.getPoolTokens(poolId); 57 | const decimals: number[] = []; 58 | await Promise.all( 59 | poolTokens.tokens.map(async (token) => { 60 | const poolTokenContract = ERC20__factory.connect(token, signerOrProvider); 61 | const poolTokenDecimals = await poolTokenContract.decimals(); 62 | decimals.push(poolTokenDecimals); 63 | }) 64 | ); 65 | 66 | return { 67 | tokens: poolTokens.tokens, 68 | balances: poolTokens.balances, 69 | decimals: decimals, 70 | }; 71 | } 72 | -------------------------------------------------------------------------------- /src/helpers/getSecondsUntilExpiration.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Element Finance, Inc 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Provider } from "@ethersproject/providers"; 18 | import { BigNumber, Signer } from "ethers"; 19 | import { PrincipalPoolTokenInfo, YieldPoolTokenInfo } from "elf-tokenlist"; 20 | 21 | import { ConvergentCurvePool__factory } from "elf-contracts-typechain"; 22 | 23 | /** 24 | * Get the seconds until expiration for a given pool 25 | * @param poolAddress any pool with a getPoolId method 26 | * @param signerOrProvider 27 | * @param timestamp timestamp of the latest block 28 | * @returns the seconds until expiration 29 | */ 30 | export async function getSecondsUntilExpiration( 31 | poolAddress: string, 32 | signerOrProvider: Signer | Provider, 33 | timestamp: number 34 | ): Promise { 35 | const poolContract = ConvergentCurvePool__factory.connect( 36 | poolAddress, 37 | signerOrProvider 38 | ); 39 | const expiration = await poolContract.expiration(); 40 | const timeUntilExpiration = 41 | BigNumber.from(timestamp) < expiration 42 | ? expiration.sub(BigNumber.from(timestamp)) 43 | : BigNumber.from(0); 44 | return timeUntilExpiration.toNumber(); 45 | } 46 | 47 | /** 48 | * Get the seconds until expiration for a given pool using tokenlist. 49 | * @param poolTokenInfo PoolTokenInfo with extension property expiration 50 | * @param timestamp timestamp of the latest block 51 | * @returns the seconds until expiration 52 | */ 53 | export function getSecondsUntilExpirationByTokenInfo( 54 | poolTokenInfo: PrincipalPoolTokenInfo | YieldPoolTokenInfo, 55 | timestamp: number 56 | ): number { 57 | const expiration = poolTokenInfo.extensions.expiration; 58 | const timeUntilExpiration = 59 | timestamp < expiration ? expiration - timestamp : 0; 60 | return timeUntilExpiration; 61 | } 62 | -------------------------------------------------------------------------------- /src/helpers/getTermByTokenSymbol.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Element Finance, Inc 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | import { Provider } from "@ethersproject/providers"; 17 | import { Signer } from "ethers"; 18 | import { 19 | getTermTokenSymbols, 20 | TermTokenSymbolsResult, 21 | } from "./getTermTokenSymbols"; 22 | 23 | interface TermAddressSymbols { 24 | termAddress: string; 25 | principalTokenSymbol: string; 26 | yieldTokenSymbol: string; 27 | } 28 | 29 | /** 30 | * returns the term matching a token symbol 31 | * @param termAddresses array of terms addresses 32 | * @param tokenSymbol the token symbol to filter on 33 | * @param signerOrProvider 34 | * @returns a promise for a term address 35 | */ 36 | export async function getTermByTokenSymbol( 37 | termAddresses: string[], 38 | tokenSymbol: string, 39 | signerOrProvider: Signer | Provider 40 | ): Promise { 41 | const symbolsList: TermAddressSymbols[] = await Promise.all( 42 | termAddresses.map(async (termAddress): Promise => { 43 | const { principalTokenSymbol, yieldTokenSymbol }: TermTokenSymbolsResult = 44 | await getTermTokenSymbols(termAddress, signerOrProvider); 45 | 46 | return { 47 | termAddress, 48 | principalTokenSymbol, 49 | yieldTokenSymbol, 50 | }; 51 | }) 52 | ); 53 | return termAddresses.find((t) => { 54 | // get the symbols of a particular term address 55 | const term = symbolsList.find(({ termAddress }) => termAddress == t); 56 | 57 | return ( 58 | term?.principalTokenSymbol == tokenSymbol || 59 | term?.yieldTokenSymbol == tokenSymbol 60 | ); 61 | }) as string; 62 | } 63 | -------------------------------------------------------------------------------- /src/helpers/getTermTokenSymbols.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Element Finance, Inc 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Provider } from "@ethersproject/providers"; 18 | import { 19 | Tranche__factory, 20 | InterestToken__factory, 21 | } from "elf-contracts-typechain"; 22 | import { Signer } from "ethers"; 23 | 24 | export interface TermTokenSymbolsResult { 25 | /** 26 | * name of the Principal Token 27 | */ 28 | principalTokenSymbol: string; 29 | /** 30 | * name of the Yield Token 31 | */ 32 | yieldTokenSymbol: string; 33 | } 34 | 35 | /** 36 | * returns the token symbols for a given term 37 | * @param termAddress the address of the term 38 | * @param signerOrProvider 39 | * @returns a promise for a TermTokenSymbolsResult 40 | */ 41 | export async function getTermTokenSymbols( 42 | termAddress: string, 43 | signerOrProvider: Signer | Provider 44 | ): Promise { 45 | const trancheContract = Tranche__factory.connect( 46 | termAddress, 47 | signerOrProvider 48 | ); 49 | const termSymbol = await trancheContract.symbol(); 50 | const interestTokenAddress = await trancheContract.interestToken(); 51 | const interestTokenContract = InterestToken__factory.connect( 52 | interestTokenAddress, 53 | signerOrProvider 54 | ); 55 | const yieldTokenSymbol = await interestTokenContract.symbol(); 56 | return { 57 | principalTokenSymbol: termSymbol, 58 | yieldTokenSymbol: yieldTokenSymbol, 59 | }; 60 | } 61 | -------------------------------------------------------------------------------- /src/helpers/getTerms.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Element Finance, Inc 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Provider } from "@ethersproject/providers"; 18 | import { TrancheFactory__factory } from "elf-contracts-typechain"; 19 | import { Signer } from "ethers"; 20 | 21 | /** 22 | * Returns an array of tranche addresses for a given tranche factory. filterable by wrapped position. 23 | * 24 | * @param trancheFactoryAddress The TrancheFactory that deployed the tranches 25 | * @param wrappedPositionAddress The wrapped position to filter by 26 | * @returns a promise of an array of tranche addresses 27 | */ 28 | export async function getTerms( 29 | trancheFactoryAddress: string, 30 | wrappedPositionAddress: string | null, 31 | signerOrProvider: Signer | Provider 32 | ): Promise { 33 | const trancheFactoryContract = TrancheFactory__factory.connect( 34 | trancheFactoryAddress, 35 | signerOrProvider 36 | ); 37 | 38 | const queryFilter = trancheFactoryContract.filters.TrancheCreated( 39 | null, 40 | wrappedPositionAddress, 41 | null 42 | ); 43 | 44 | const trancheEvents = await trancheFactoryContract.queryFilter(queryFilter); 45 | 46 | const trancheAddresses: string[] = trancheEvents.map( 47 | (event) => event.args?.trancheAddress 48 | ); 49 | 50 | return trancheAddresses; 51 | } 52 | -------------------------------------------------------------------------------- /src/helpers/getTokenInfo.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Element Finance, Inc 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { TokenInfo, TokenList } from "@uniswap/token-lists"; 18 | import keyBy from "lodash.keyby"; 19 | import { 20 | PrincipalTokenInfo, 21 | YieldPoolTokenInfo, 22 | PrincipalPoolTokenInfo, 23 | AssetProxyTokenInfo, 24 | AnyTokenListInfo, 25 | TokenTag, 26 | } from "elf-tokenlist"; 27 | import { AddressesJsonFile } from "elf-tokenlist/dist/AddressesJsonFile"; 28 | 29 | interface InitTokenListResult { 30 | tokenList: TokenList; 31 | addressesJson: AddressesJsonFile; 32 | tokenInfoByAddress: Record; 33 | } 34 | 35 | /** 36 | * Init the tokenlist for given chain 37 | * @param chainName name of the chain that the tokenlist represents 38 | * @returns InitTokenListResult 39 | */ 40 | export function initTokenList(chainName: string): InitTokenListResult { 41 | // eslint-disable-next-line @typescript-eslint/no-var-requires 42 | const tokenList: TokenList = require(`elf-tokenlist/dist/${chainName}.tokenlist.json`); 43 | // eslint-disable-next-line @typescript-eslint/no-var-requires 44 | const addressesJson: AddressesJsonFile = require(`elf-tokenlist/dist/${chainName}.addresses.json`); 45 | const tokenInfos = tokenList.tokens; 46 | const tokenInfoByAddress: Record = keyBy( 47 | tokenInfos, 48 | "address" 49 | ); 50 | return { tokenList, addressesJson, tokenInfoByAddress }; 51 | } 52 | 53 | /** 54 | * Helper function for looking up a tokenlist info 55 | * @param address address of the token 56 | * @param tokenInfoByAddress mapping of TokenInfos by address 57 | * @returns TokenInfo associated with the address param 58 | */ 59 | export function getTokenInfo( 60 | address: string, 61 | tokenInfoByAddress: Record 62 | ): T { 63 | return tokenInfoByAddress[address] as T; 64 | } 65 | 66 | function isAssetProxy(tokenInfo: TokenInfo): tokenInfo is PrincipalTokenInfo { 67 | return !!tokenInfo.tags?.includes(TokenTag.ASSET_PROXY); 68 | } 69 | 70 | /** 71 | * Finds tokenInfos for AssetProxies. 72 | * @param tokenInfos 73 | * @returns list of AssetProxyTokenInfo 74 | */ 75 | export function getAssetProxyTokenInfos( 76 | tokenInfos: TokenInfo[] 77 | ): AssetProxyTokenInfo[] { 78 | return tokenInfos.filter((tokenInfo): tokenInfo is AssetProxyTokenInfo => 79 | isAssetProxy(tokenInfo) 80 | ); 81 | } 82 | 83 | function isPrincipalToken( 84 | tokenInfo: TokenInfo 85 | ): tokenInfo is PrincipalTokenInfo { 86 | return !!tokenInfo?.tags?.includes(TokenTag.PRINCIPAL); 87 | } 88 | 89 | /** 90 | * Finds tokenInfos for Principal Tokens 91 | * @param tokenInfos 92 | * @returns list of PrincipalTokenInfo 93 | */ 94 | export function getPrincipalTokenInfos( 95 | tokenInfos: TokenInfo[] 96 | ): PrincipalTokenInfo[] { 97 | return tokenInfos.filter((tokenInfo): tokenInfo is PrincipalTokenInfo => 98 | isPrincipalToken(tokenInfo) 99 | ); 100 | } 101 | 102 | function isPrincipalPool( 103 | tokenInfo: TokenInfo 104 | ): tokenInfo is PrincipalPoolTokenInfo { 105 | return !!tokenInfo.tags?.includes(TokenTag.CCPOOL); 106 | } 107 | 108 | /** 109 | * Returns a PrincipalTokenInfo given a TokenInfo for a pool 110 | * @param poolInfo 111 | * @param tokenInfos 112 | * @returns PrincipalTokenInfo 113 | */ 114 | export function getPrincipalTokenInfoForPool( 115 | poolInfo: YieldPoolTokenInfo | PrincipalPoolTokenInfo, 116 | tokenInfos: TokenInfo[] 117 | ): PrincipalTokenInfo { 118 | const principalTokenInfos = getPrincipalTokenInfos(tokenInfos); 119 | if (isPrincipalPool(poolInfo)) { 120 | const trancheAddress = poolInfo.extensions.bond; 121 | const trancheInfo = principalTokenInfos.find( 122 | (info) => info.address === trancheAddress 123 | ) as PrincipalTokenInfo; 124 | return trancheInfo; 125 | } 126 | 127 | const interestTokenAddress = poolInfo.extensions.interestToken; 128 | const trancheInfo = principalTokenInfos.find( 129 | (info) => info.extensions.interestToken === interestTokenAddress 130 | ) as PrincipalTokenInfo; 131 | return trancheInfo; 132 | } 133 | 134 | /** 135 | * Returns the TokenInfo of the pool corresponding to a Principal Token 136 | * @param principalTokenAddress 137 | * @param tokenInfos 138 | * @returns PrincipalPoolTokenInfo 139 | */ 140 | export function getPoolInfoForPrincipalToken( 141 | principalTokenAddress: string, 142 | tokenInfos: TokenInfo[] 143 | ): PrincipalPoolTokenInfo { 144 | const principalPools: PrincipalPoolTokenInfo[] = tokenInfos.filter( 145 | (tokenInfo): tokenInfo is PrincipalPoolTokenInfo => 146 | isPrincipalPool(tokenInfo) 147 | ); 148 | return principalPools.find( 149 | ({ extensions: { bond } }) => bond === principalTokenAddress 150 | ) as PrincipalPoolTokenInfo; 151 | } 152 | 153 | function isYieldPool(tokenInfo: TokenInfo): tokenInfo is YieldPoolTokenInfo { 154 | return !!tokenInfo.tags?.includes(TokenTag.WPOOL); 155 | } 156 | 157 | /** 158 | * Returns the TokenInfos for the Yield Pools 159 | * @param tokenInfos 160 | * @returns a list of YieldPoolTokenInfo 161 | */ 162 | export function getYieldPoolTokenInfos( 163 | tokenInfos: TokenInfo[] 164 | ): YieldPoolTokenInfo[] { 165 | return tokenInfos.filter((tokenInfo): tokenInfo is YieldPoolTokenInfo => 166 | isYieldPool(tokenInfo) 167 | ); 168 | } 169 | -------------------------------------------------------------------------------- /src/helpers/getTotalSupply.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Element Finance, Inc 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Provider } from "@ethersproject/providers"; 18 | import { BasePool__factory } from "elf-contracts-typechain"; 19 | import { BigNumber, Signer } from "ethers"; 20 | 21 | /** 22 | * Returns the total supply for a pool. All balancer v2 pools use an 18 decimal Balancer Pool Token 23 | * (BPT) to track the total supply. 24 | * @param poolAddress any pool with a totalSupply method 25 | * @param signerOrProvider 26 | */ 27 | export async function getTotalSupply( 28 | poolAddress: string, 29 | signerOrProvider: Signer | Provider 30 | ): Promise { 31 | const poolContract = BasePool__factory.connect(poolAddress, signerOrProvider); 32 | 33 | const totalSupply = await poolContract.totalSupply(); 34 | 35 | return totalSupply; 36 | } 37 | -------------------------------------------------------------------------------- /src/helpers/getUnderlyingContractsByAddress.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Element Finance, Inc 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Provider } from "@ethersproject/providers"; 18 | import { Signer } from "ethers"; 19 | 20 | import { 21 | DAI__factory, 22 | ERC20__factory, 23 | ERC20Permit__factory, 24 | ERC20, 25 | ERC20Permit, 26 | WETH, 27 | DAI, 28 | } from "elf-contracts-typechain/dist/types"; 29 | import { WETH__factory } from "elf-contracts-typechain/dist/types/factories/WETH__factory"; 30 | import { AddressesJsonFile } from "elf-tokenlist/dist/AddressesJsonFile"; 31 | 32 | /** 33 | * This method creates a token to contract mapping 34 | * @param addressesJsonId mainnet or goerli 35 | * @param signerOrProvider 36 | * @returns a mapping of token addresses to corresponding pool contracts 37 | */ 38 | export function getUnderlyingContractsByAddress( 39 | addressesJsonId: string, 40 | signerOrProvider: Signer | Provider 41 | ): Record { 42 | // eslint-disable-next-line @typescript-eslint/no-var-requires 43 | const AddressesJson: AddressesJsonFile = require(`elf-tokenlist/dist/${addressesJsonId}.addresses.json`); 44 | const { 45 | addresses: { 46 | wethAddress, 47 | wbtcAddress, 48 | usdcAddress, 49 | daiAddress, 50 | "alusd3crv-fAddress": crvalusdAddress, 51 | "mim-3lp3crv-fAddress": crvmimAddress, 52 | "lusd3crv-fAddress": crvlusdAddress, 53 | crv3cryptoAddress, 54 | crvtricryptoAddress, 55 | stecrvAddress, 56 | eurscrvAddress, 57 | }, 58 | } = AddressesJson; 59 | 60 | const wethContract = WETH__factory.connect(wethAddress, signerOrProvider); 61 | const wbtcContract = ERC20__factory.connect(wbtcAddress, signerOrProvider); 62 | const usdcContract = ERC20Permit__factory.connect( 63 | usdcAddress, 64 | signerOrProvider 65 | ); 66 | const daiContract = DAI__factory.connect(daiAddress, signerOrProvider); 67 | const crvlusdContract = ERC20__factory.connect( 68 | crvlusdAddress, 69 | signerOrProvider 70 | ); 71 | const crvalusdContract = ERC20__factory.connect( 72 | crvalusdAddress, 73 | signerOrProvider 74 | ); 75 | const crvmimContract = ERC20__factory.connect( 76 | crvmimAddress, 77 | signerOrProvider 78 | ); 79 | 80 | const crvTricryptoContract = ERC20__factory.connect( 81 | crvtricryptoAddress, 82 | signerOrProvider 83 | ); 84 | const crv3CryptoContract = ERC20__factory.connect( 85 | crv3cryptoAddress, 86 | signerOrProvider 87 | ); 88 | 89 | const steCrvContract = ERC20__factory.connect( 90 | stecrvAddress, 91 | signerOrProvider 92 | ); 93 | const eursCrvContract = ERC20__factory.connect( 94 | eurscrvAddress, 95 | signerOrProvider 96 | ); 97 | 98 | const underlyingContractsByAddress = Object.freeze({ 99 | [wethAddress]: wethContract, 100 | [wbtcAddress]: wbtcContract, 101 | [usdcAddress]: usdcContract, 102 | [daiAddress]: daiContract, 103 | [crvlusdAddress]: crvlusdContract, 104 | [crvalusdAddress]: crvalusdContract, 105 | [crvtricryptoAddress]: crvTricryptoContract, 106 | [crv3cryptoAddress]: crv3CryptoContract, 107 | [crvmimAddress]: crvmimContract, 108 | [stecrvAddress]: steCrvContract, 109 | [eurscrvAddress]: eursCrvContract, 110 | }); 111 | return underlyingContractsByAddress; 112 | } 113 | -------------------------------------------------------------------------------- /src/helpers/getUnitSeconds.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Element Finance, Inc 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Provider } from "@ethersproject/providers"; 18 | import { ConvergentCurvePool__factory } from "elf-contracts-typechain"; 19 | import { Signer } from "ethers"; 20 | 21 | /** 22 | * Get the unit seconds for a given pool 23 | * @param poolAddress any pool with a getPoolId method 24 | * @param signerOrProvider 25 | * @returns the unit seconds 26 | */ 27 | export async function getUnitSeconds( 28 | poolAddress: string, 29 | signerOrProvider: Signer | Provider 30 | ): Promise { 31 | const poolContract = ConvergentCurvePool__factory.connect( 32 | poolAddress, 33 | signerOrProvider 34 | ); 35 | const unitSeconds = await poolContract.unitSeconds(); 36 | return unitSeconds.toNumber(); 37 | } 38 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Element Finance, Inc 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /* 18 | * This is a handwritten root file used to re-export the public and 19 | * importable function, interfaces, etc. for consumers of the SDK 20 | */ 21 | export { mintWithUserProxy } from "./mint"; 22 | export { getTermExpiration } from "./mint"; 23 | export { getTermPosition } from "./mint"; 24 | export { SingleSwap } from "./swap"; 25 | export { swap } from "./swap"; 26 | export { joinConvergentPool } from "./joinPool"; 27 | export { joinWeightedPool } from "./joinPool"; 28 | export { exitConvergentPool } from "./exitPool"; 29 | export { WeightedPoolExitKind } from "./exitPool"; 30 | export { exitWeightedPool } from "./exitPool"; 31 | 32 | export { calcFixedAPR } from "./helpers/calcFixedAPR"; 33 | export { calcSwapOutGivenInCCPoolUnsafe } from "./helpers/calcPoolSwap"; 34 | export { calcSwapInGivenOutCCPoolUnsafe } from "./helpers/calcPoolSwap"; 35 | export { calcSwapOutGivenInWeightedPoolUnsafe } from "./helpers/calcPoolSwap"; 36 | export { calcSwapInGivenOutWeightedPoolUnsafe } from "./helpers/calcPoolSwap"; 37 | export { calcSpotPricePt } from "./helpers/calcSpotPrice"; 38 | export { calcSpotPriceYt } from "./helpers/calcSpotPrice"; 39 | export { PoolType } from "./helpers/getElementAddresses"; 40 | export { getElementDeploymentAddresses } from "./helpers/getElementAddresses"; 41 | export { getElementTermFactoryAddresses } from "./helpers/getElementAddresses"; 42 | export { getElementTermAddresses } from "./helpers/getElementAddresses"; 43 | export { getElementPtPoolAddresses } from "./helpers/getElementAddresses"; 44 | export { getElementYtPoolAddresses } from "./helpers/getElementAddresses"; 45 | export { getPoolIdByTermAddress } from "./helpers/getElementAddresses"; 46 | export { getBaseTokenAddress } from "./helpers/getElementAddresses"; 47 | export { getLatestBlockTimestamp } from "./helpers/getLatestBlockTimestamp"; 48 | export { getPoolId } from "./helpers/getPoolId"; 49 | export { ReservesResult } from "./helpers/getReserves"; 50 | export { getReserves } from "./helpers/getReserves"; 51 | export { TermTokenSymbolsResult } from "./helpers/getTermTokenSymbols"; 52 | export { getTermByTokenSymbol } from "./helpers/getTermByTokenSymbol"; 53 | export { getTerms } from "./helpers/getTerms"; 54 | export { getTermTokenSymbols } from "./helpers/getTermTokenSymbols"; 55 | export { getSecondsUntilExpiration } from "./helpers/getSecondsUntilExpiration"; 56 | export { getTotalSupply } from "./helpers/getTotalSupply"; 57 | export { getUnitSeconds } from "./helpers/getUnitSeconds"; 58 | 59 | export { ONE_MINUTE_IN_SECONDS } from "./constants/time"; 60 | export { ONE_HOUR_IN_SECONDS } from "./constants/time"; 61 | export { ONE_DAY_IN_SECONDS } from "./constants/time"; 62 | export { ONE_WEEK_IN_SECONDS } from "./constants/time"; 63 | export { THIRTY_DAYS_IN_SECONDS } from "./constants/time"; 64 | export { SIX_MONTHS_IN_SECONDS } from "./constants/time"; 65 | export { ONE_YEAR_IN_SECONDS } from "./constants/time"; 66 | export { ONE_MINUTE_IN_MILLISECONDS } from "./constants/time"; 67 | export { ONE_HOUR_IN_MILLISECONDS } from "./constants/time"; 68 | export { ONE_DAY_IN_MILLISECONDS } from "./constants/time"; 69 | export { ONE_WEEK_IN_MILLISECONDS } from "./constants/time"; 70 | export { ONE_YEAR_IN_MILLISECONDS } from "./constants/time"; 71 | export { THIRTY_DAYS_IN_MILLISECONDS } from "./constants/time"; 72 | -------------------------------------------------------------------------------- /src/joinPool.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Element Finance, Inc 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Vault__factory } from "elf-contracts-typechain"; 18 | import { BigNumber, ContractTransaction, Signer } from "ethers"; 19 | import { defaultAbiCoder } from "ethers/lib/utils"; 20 | 21 | /** 22 | * Add liquidity to a ConvergentCurvePool. 23 | * @param signer Who is authorizing the transaction 24 | * @param poolId Balancer V2 PoolId 25 | * @param senderAddress who is depositing the money into the pool 26 | * @param receipientAddress who is receiving the LP token 27 | * @param vaultAddress Balancer V2 Vault address 28 | * @param tokens tokens to deposit, note: sorted alphanumerically. ETH must be sorted as though it 29 | * were WETH. 30 | * @param maxAmountsIn maximum amounts to deposit, same order as tokens. 31 | * @param fromInternalBalance Use the sender's Balancer V2 internal balance first, if available. 32 | * @returns returns the contract transaction. 33 | */ 34 | export async function joinConvergentPool( 35 | signer: Signer, 36 | poolId: string, 37 | senderAddress: string, 38 | receipientAddress: string, 39 | vaultAddress: string, 40 | tokens: string[], 41 | maxAmountsIn: BigNumber[], 42 | fromInternalBalance = false 43 | ): Promise { 44 | // Balancer V2 vault allows userData as a way to pass props through to pool contracts. In this 45 | // case we need to pass the maxAmountsIn. 46 | const userData = defaultAbiCoder.encode(["uint256[]"], [maxAmountsIn]); 47 | 48 | const joinRequest = { 49 | assets: tokens, 50 | maxAmountsIn, 51 | userData, 52 | fromInternalBalance, 53 | }; 54 | 55 | const vaultContract = Vault__factory.connect(vaultAddress, signer); 56 | const joinReceipt = await vaultContract.joinPool( 57 | poolId, 58 | senderAddress, 59 | receipientAddress, 60 | joinRequest 61 | ); 62 | 63 | return joinReceipt; 64 | } 65 | 66 | const ZeroBigNumber = BigNumber.from(0); 67 | enum WeightedPoolJoinKind { 68 | INIT, 69 | EXACT_TOKENS_IN_FOR_BPT_OUT, 70 | TOKEN_IN_FOR_EXACT_BPT_OUT, 71 | } 72 | 73 | /** 74 | * Add liquidity to a WeightedPool. 75 | * @param signer who is authorizing the transaction. 76 | * @param poolId Balancer V2 PoolId. 77 | * @param senderAddress who is depositing the money into the pool. 78 | * @param receipientAddress who is receiving the LP token. 79 | * @param vaultAddress Balancer V2 Vault address. 80 | * @param tokens tokens to deposit, note: sorted alphanumerically. ETH must be sorted as though it 81 | * were WETH. 82 | * @param maxAmountsIn maximum amounts to deposit, same order as tokens. 83 | * @param minBPTOut minimun amount of LP out, setting this creates a slippage tolerangs. 84 | * @param fromInternalBalance use the sender's Balancer V2 internal balance first, if available. 85 | * @param joinKind 86 | * @returns returns the contract transaction. 87 | */ 88 | export async function joinWeightedPool( 89 | signer: Signer, 90 | poolId: string, 91 | senderAddress: string, 92 | receipientAddress: string, 93 | vaultAddress: string, 94 | tokens: string[], 95 | maxAmountsIn: BigNumber[], 96 | minBPTOut: BigNumber = ZeroBigNumber, 97 | fromInternalBalance = false, 98 | joinKind: WeightedPoolJoinKind = WeightedPoolJoinKind.EXACT_TOKENS_IN_FOR_BPT_OUT 99 | ): Promise { 100 | // Balancer V2 vault allows userData as a way to pass props through to pool contracts. In this 101 | // case we need to pass the joinKind, maxAmountsIn and minBPTOut. 102 | const userData = defaultAbiCoder.encode( 103 | ["uint8", "uint256[]", "uint256"], 104 | [joinKind, maxAmountsIn, minBPTOut] 105 | ); 106 | const joinRequest = { 107 | assets: tokens, 108 | maxAmountsIn, 109 | userData, 110 | fromInternalBalance, 111 | }; 112 | 113 | const vaultContract = Vault__factory.connect(vaultAddress, signer); 114 | const joinReceipt = await vaultContract.joinPool( 115 | poolId, 116 | senderAddress, 117 | receipientAddress, 118 | joinRequest 119 | ); 120 | 121 | return joinReceipt; 122 | } 123 | -------------------------------------------------------------------------------- /src/mint.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Element Finance, Inc 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Provider } from "@ethersproject/providers"; 18 | import { Tranche__factory, UserProxy__factory } from "elf-contracts-typechain"; 19 | import { 20 | BigNumber, 21 | ContractTransaction, 22 | PayableOverrides, 23 | Signer, 24 | } from "ethers"; 25 | import { parseUnits } from "ethers/lib/utils"; 26 | 27 | export const ETH_SENTINEL_ADDRESS = 28 | "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; 29 | 30 | /** 31 | * Mints new principal and yield tokens for a given amount of base asset. The base asset must match 32 | * the term's underlying. For terms that accept WETH, ETH can also be used by supplying the ETH_SENTINEL_ADDRESS. 33 | * @param userProxyContractAddress address of Element's UserProxy 34 | * @param termExpiration the exiration date of the term in unix seconds 35 | * @param termPosition the address of the term's wrapped position 36 | * @param baseAssetAmount the amount of base asset to deposit, i.e. "3.14" Ether 37 | * @param baseAssetAddress the address of the token to deposit. Use 38 | * ETH_SENTINEL_ADDRESS to mint with Ether. 39 | * @param baseAssetDecimals the decimal precision of the asset, i.e. 18 for Ether 40 | * @param signerOrProvider 41 | */ 42 | export async function mintWithUserProxy( 43 | userProxyContractAddress: string, 44 | termExpiration: number, 45 | termPosition: string, 46 | baseAssetAmount: string, 47 | baseAssetAddress: string, 48 | baseAssetDecimals: number, 49 | signerOrProvider: Signer | Provider, 50 | overrides?: PayableOverrides 51 | ): Promise { 52 | const userProxyContract = UserProxy__factory.connect( 53 | userProxyContractAddress, 54 | signerOrProvider 55 | ); 56 | 57 | const value = parseUnits(baseAssetAmount, baseAssetDecimals); 58 | 59 | const mintTx = 60 | overrides === undefined 61 | ? await userProxyContract.mint( 62 | value, 63 | baseAssetAddress, 64 | termExpiration, 65 | termPosition, 66 | [] 67 | ) 68 | : await userProxyContract.mint( 69 | value, 70 | baseAssetAddress, 71 | termExpiration, 72 | termPosition, 73 | [], 74 | overrides 75 | ); 76 | 77 | return mintTx; 78 | } 79 | 80 | /** 81 | * get the expiration time in unix seconds for a term. returns a BigNumber that can be converted 82 | * to a number with BigNumber.toNumber() 83 | * @param termAddress the address of the term 84 | * @param signerOrProvider 85 | * @returns 86 | */ 87 | export async function getTermExpiration( 88 | termAddress: string, 89 | signerOrProvider: Signer | Provider 90 | ): Promise { 91 | const termContract = Tranche__factory.connect(termAddress, signerOrProvider); 92 | 93 | const expiration = await termContract.unlockTimestamp(); 94 | return expiration; 95 | } 96 | 97 | /** 98 | * returns the wrapped position address for a given term 99 | * @param termAddress the address of the term 100 | * @param signerOrProvider 101 | * @returns 102 | */ 103 | export async function getTermPosition( 104 | termAddress: string, 105 | signerOrProvider: Signer | Provider 106 | ): Promise { 107 | const termContract = Tranche__factory.connect(termAddress, signerOrProvider); 108 | 109 | const position = await termContract.position(); 110 | return position; 111 | } 112 | -------------------------------------------------------------------------------- /src/prices/coingecko/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Element Finance, Inc 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Currency, Money } from "ts-money"; 18 | import fetch from "axios"; 19 | import { format, subDays } from "date-fns"; 20 | import coinsJSON from "./coins.json"; 21 | 22 | /** 23 | * Lookup object for getting the CoinGecko coin id from the coin or token's 24 | * symbol. 25 | * 26 | * Eg: 27 | * CoinGeckoIds.eth === 'ethereum' // true 28 | * 29 | * This can then be used to make calls to CoinGecko apis about ethereum, ie: price apis. 30 | * 31 | * TODO: This can be auto-generated instead of created at runtime. 32 | */ 33 | const CoinGeckoIds: { 34 | [symbol: string]: string; 35 | } = coinsJSON.reduce( 36 | (memo, value) => ({ ...memo, [value.symbol]: value.id }), 37 | {} 38 | ); 39 | 40 | export function getCoinGeckoId(symbol: string | undefined): string | undefined { 41 | if (!symbol) { 42 | return; 43 | } 44 | 45 | return CoinGeckoIds[symbol.toLowerCase()]; 46 | } 47 | export async function fetchCoinGeckoPrice( 48 | coinGeckoId: string, 49 | currency: Currency 50 | ): Promise { 51 | const currencyCode = currency.code.toLowerCase(); 52 | const result = await fetch( 53 | `https://api.coingecko.com/api/v3/simple/price?ids=${coinGeckoId}&vs_currencies=${currencyCode}` 54 | ); 55 | 56 | // Result looks like: 57 | // { dai: { usd: 1.01 } } 58 | const resultJSON = result.data; 59 | 60 | const price = resultJSON[coinGeckoId][currencyCode]; 61 | 62 | return Money.fromDecimal( 63 | price, 64 | currency, 65 | // Money.fromDecimal will throw if price has more decimals than the currency 66 | // allows unless you pass a rounding function 67 | Math.round 68 | ); 69 | } 70 | 71 | export async function fetchCoinGeckoHistoricalPrice( 72 | coinGeckoId: string, 73 | currency: Currency, 74 | daysAgo = 1 75 | ): Promise { 76 | const dateString = format(subDays(new Date(), daysAgo), "dd-MM-yyyy"); 77 | const currencyCode = currency.code.toLowerCase(); 78 | const result = await fetch( 79 | `https://api.coingecko.com/api/v3/coins/${coinGeckoId}/history?date=${dateString}` 80 | ); 81 | 82 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 83 | const resultJSON = (await result.data) as any; 84 | 85 | const price = resultJSON["market_data"]["current_price"][currencyCode]; 86 | 87 | return Money.fromDecimal( 88 | price, 89 | currency, 90 | // Money.fromDecimal will throw if price has more decimals than the currency 91 | // allows unless you pass a rounding function 92 | Math.round 93 | ); 94 | } 95 | -------------------------------------------------------------------------------- /src/prices/curve/pools.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Element Finance, Inc 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | import { Provider } from "@ethersproject/providers"; 17 | import { Signer, BigNumber } from "ethers"; 18 | import { CurveContract__factory } from "elf-contracts-typechain/dist/types/factories/CurveContract__factory"; 19 | import { CurveStethPool__factory } from "elf-contracts-typechain/dist/types/factories/CurveStethPool__factory"; 20 | import { 21 | CurveStethPool, 22 | CurveContract, 23 | } from "elf-contracts-typechain/dist/types"; 24 | import { CRVLUSD__factory } from "elf-contracts-typechain/dist/types/factories/CRVLUSD__factory"; 25 | import { CRVLUSD } from "elf-contracts-typechain/dist/types/CRVLUSD"; 26 | 27 | /* 28 | * Curve pools that aren't strictly stablecoins are architected such that the LP 29 | * token (like what is used for minting in Element) is separate from the pool 30 | * contract that deals with trading and pricing. 31 | * 32 | * To price one of these assets, use the `withdraw_one_coin` method to price one 33 | * of the assets in the pool against an external price sensor, ie: coingecko. 34 | * 35 | * NOTE: You can find the pool addresses on curve's website at the bottom of a 36 | * pool page. 37 | */ 38 | export function getCrvTriCryptoPoolContract( 39 | signerOrProvider: Signer | Provider 40 | ): CurveContract { 41 | const CRVTriCrytoPoolAddress = "0x80466c64868e1ab14a1ddf27a676c3fcbe638fe5"; 42 | const crvTriCryptoPoolContract = CurveContract__factory.connect( 43 | CRVTriCrytoPoolAddress, 44 | signerOrProvider 45 | ); 46 | return crvTriCryptoPoolContract; 47 | } 48 | 49 | export function getCrv3CryptoPoolContract( 50 | signerOrProvider: Signer | Provider 51 | ): CurveContract { 52 | const CRV3CrytoPoolAddress = "0xD51a44d3FaE010294C616388b506AcdA1bfAAE46"; 53 | const crv3CryptoPoolContract = CurveContract__factory.connect( 54 | CRV3CrytoPoolAddress, 55 | signerOrProvider 56 | ); 57 | return crv3CryptoPoolContract; 58 | } 59 | 60 | export function getSteCrvPoolContract( 61 | signerOrProvider: Signer | Provider 62 | ): CurveStethPool { 63 | const steCRVPoolAddress = "0xDC24316b9AE028F1497c275EB9192a3Ea0f67022"; 64 | const steCrvPoolContract = CurveStethPool__factory.connect( 65 | steCRVPoolAddress, 66 | signerOrProvider 67 | ); 68 | return steCrvPoolContract; 69 | } 70 | -------------------------------------------------------------------------------- /src/prices/curve/stablePools.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Element Finance, Inc 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | import { Provider } from "@ethersproject/providers"; 17 | import { Signer, BigNumber } from "ethers"; 18 | import { CRVLUSD__factory } from "elf-contracts-typechain/dist/types/factories/CRVLUSD__factory"; 19 | import { CRVLUSD } from "elf-contracts-typechain/dist/types/CRVLUSD"; 20 | import { AddressesJsonFile } from "elf-tokenlist/dist/AddressesJsonFile"; 21 | 22 | export function getCurveStablePoolContractsByAddress( 23 | chainName: string, 24 | signerOrProvider: Signer | Provider 25 | ): Record { 26 | // eslint-disable-next-line @typescript-eslint/no-var-requires 27 | const AddressesJson: AddressesJsonFile = require(`elf-tokenlist/dist/${chainName}.addresses.json`); 28 | /** 29 | * Curve stable pools provide a `get_virtual_price` method for getting the price. 30 | */ 31 | const { 32 | addresses: { 33 | eurscrvAddress, 34 | "alusd3crv-fAddress": crvalusdAddress, 35 | "lusd3crv-fAddress": crvlusdAddress, 36 | "mim-3lp3crv-fAddress": crvmimAddress, 37 | }, 38 | } = AddressesJson; 39 | 40 | const crvalusdContract = CRVLUSD__factory.connect( 41 | // Note: the CRVLUSD_factory is the same, so it can handle both alusd and lusd pools. 42 | crvalusdAddress, 43 | signerOrProvider 44 | ); 45 | 46 | const crvlusdContract = CRVLUSD__factory.connect( 47 | crvlusdAddress, 48 | signerOrProvider 49 | ); 50 | 51 | const crvMimContract = CRVLUSD__factory.connect( 52 | crvmimAddress, 53 | signerOrProvider 54 | ); 55 | 56 | const CRVEursPoolAddress = "0x0Ce6a5fF5217e38315f87032CF90686C96627CAA"; 57 | const crvEursPoolContract = CRVLUSD__factory.connect( 58 | CRVEursPoolAddress, 59 | signerOrProvider 60 | ); 61 | 62 | const curveVirtualPriceContractsByAddress = Object.freeze({ 63 | [eurscrvAddress]: crvEursPoolContract, 64 | [crvalusdAddress]: crvalusdContract, 65 | [crvlusdAddress]: crvlusdContract, 66 | [crvmimAddress]: crvMimContract, 67 | }); 68 | return curveVirtualPriceContractsByAddress; 69 | } 70 | 71 | export function isCurveStablePool(chainName: string, address: string): boolean { 72 | // eslint-disable-next-line @typescript-eslint/no-var-requires 73 | const AddressesJson: AddressesJsonFile = require(`elf-tokenlist/dist/${chainName}.addresses.json`); 74 | /** 75 | * Curve stable pools provide a `get_virtual_price` method for getting the price. 76 | */ 77 | const { 78 | addresses: { 79 | eurscrvAddress, 80 | "alusd3crv-fAddress": crvalusdAddress, 81 | "lusd3crv-fAddress": crvlusdAddress, 82 | "mim-3lp3crv-fAddress": crvmimAddress, 83 | }, 84 | } = AddressesJson; 85 | return [ 86 | eurscrvAddress, 87 | crvalusdAddress, 88 | crvlusdAddress, 89 | crvmimAddress, 90 | ].includes(address); 91 | } 92 | -------------------------------------------------------------------------------- /src/swap.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Element Finance, Inc 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Vault__factory } from "elf-contracts-typechain"; 18 | import { 19 | BigNumber, 20 | ContractTransaction, 21 | PayableOverrides, 22 | Signer, 23 | } from "ethers"; 24 | 25 | import { ONE_DAY_IN_SECONDS } from "../src/constants/time"; 26 | 27 | export const BALANCER_ETH_SENTINEL = 28 | "0x0000000000000000000000000000000000000000"; 29 | 30 | export enum SwapKind { 31 | GIVEN_IN, 32 | GIVEN_OUT, 33 | } 34 | 35 | export interface SingleSwap { 36 | poolId: string; 37 | kind: SwapKind; 38 | assetIn: string; 39 | assetOut: string; 40 | amount: BigNumber; 41 | userData: string; 42 | } 43 | 44 | /** 45 | * 46 | * @param signer 47 | * @param sender 48 | * @param recipient 49 | * @param poolId 50 | * @param tokenInAddress 51 | * @param tokenOutAddress 52 | * @param balancerVaultAddress 53 | * @param amount 54 | * @param kind 55 | * @param limit 56 | * @param expirationInSeconds 57 | * @param useETH 58 | * @param wethAddress 59 | * @param fromInternalBalance 60 | * @param toInternalBalance 61 | */ 62 | export async function swap( 63 | signer: Signer, 64 | sender: string, 65 | recipient: string, 66 | poolId: string, 67 | tokenInAddress: string, 68 | tokenOutAddress: string, 69 | balancerVaultAddress: string, 70 | amount: BigNumber, 71 | kind: SwapKind, 72 | limit: BigNumber, 73 | overrides?: PayableOverrides, 74 | expirationInSeconds: number = ONE_DAY_IN_SECONDS, 75 | useETH = false, 76 | wethAddress?: string, 77 | fromInternalBalance = false, 78 | toInternalBalance = false 79 | ): Promise { 80 | const assetIn = 81 | useETH && tokenInAddress === wethAddress 82 | ? BALANCER_ETH_SENTINEL 83 | : tokenInAddress; 84 | 85 | const assetOut = 86 | useETH && tokenOutAddress === wethAddress 87 | ? BALANCER_ETH_SENTINEL 88 | : tokenOutAddress; 89 | 90 | const swap: SingleSwap = { 91 | poolId, 92 | kind, 93 | assetIn, 94 | assetOut, 95 | amount, 96 | // no need to pass data 97 | userData: "0x00", 98 | }; 99 | 100 | const funds = { 101 | sender, 102 | recipient, 103 | fromInternalBalance, 104 | toInternalBalance, 105 | }; 106 | 107 | const deadline = Math.round(Date.now() / 1000) + expirationInSeconds; 108 | const vaultContract = Vault__factory.connect(balancerVaultAddress, signer); 109 | 110 | const swapReceipt = 111 | overrides === undefined 112 | ? await vaultContract.swap(swap, funds, limit, deadline) 113 | : await vaultContract.swap(swap, funds, limit, deadline, overrides); 114 | 115 | return swapReceipt; 116 | } 117 | -------------------------------------------------------------------------------- /test/calcFixedAprTest.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Element Finance, Inc 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { calcFixedAPR } from "../src/helpers/calcFixedAPR"; 18 | import { expect } from "chai"; 19 | import { BigNumber } from "ethers"; 20 | 21 | describe("calcFixedAPR", () => { 22 | it("should properly calculate fixed APR", () => { 23 | const spotPrice = 0.9903009860201194; 24 | const timeUntilMaturity = 11852714; 25 | const result = calcFixedAPR(spotPrice, timeUntilMaturity); 26 | expect(result).to.equal(2.6058485759440213); 27 | }); 28 | }); 29 | 30 | describe("calcFixedAPRTimeZero", () => { 31 | it("should return fixed APR of 0%", () => { 32 | const spotPrice = 0.9903009860201194; 33 | const timeUntilMaturity = 0; 34 | const result = calcFixedAPR(spotPrice, timeUntilMaturity); 35 | expect(result).to.equal(0); 36 | }); 37 | }); 38 | 39 | describe("calcFixedAPRTimeNegative", () => { 40 | it("should return fixed APR of 0%", () => { 41 | const spotPrice = 0.9903009860201194; 42 | const timeUntilMaturity = -4; 43 | const result = calcFixedAPR(spotPrice, timeUntilMaturity); 44 | expect(result).to.equal(0); 45 | }); 46 | }); 47 | -------------------------------------------------------------------------------- /test/calcSpotPriceTest.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Element Finance, Inc 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { calcSpotPricePt, calcSpotPriceYt } from "../src/helpers/calcSpotPrice"; 18 | import { 19 | THIRTY_DAYS_IN_SECONDS, 20 | ONE_YEAR_IN_SECONDS, 21 | } from "../src/constants/time"; 22 | 23 | import { expect } from "chai"; 24 | import { BigNumber } from "ethers"; 25 | 26 | describe("calcSpotPrices", () => { 27 | it("should properly calculate spot price of PT", () => { 28 | const ptReserves = BigNumber.from("1000000000000000"); 29 | const baseReserves = BigNumber.from("1612400925773352"); 30 | const totalSupply = baseReserves.add(ptReserves); 31 | const timeRemainingSeconds = THIRTY_DAYS_IN_SECONDS; 32 | const timeStretch = 4; 33 | const tParamSeconds = timeStretch * ONE_YEAR_IN_SECONDS; 34 | const result = calcSpotPricePt( 35 | baseReserves.toString(), 36 | ptReserves.toString(), 37 | totalSupply.toString(), 38 | timeRemainingSeconds, 39 | tParamSeconds, 40 | 18 41 | ); 42 | expect(result).to.equal(0.9835616438356164); 43 | }); 44 | 45 | it("should properly calculate spot price of YT", () => { 46 | const baseReserves = "24"; 47 | const ytReserves = "12308"; 48 | const result = calcSpotPriceYt(baseReserves, ytReserves); 49 | expect(result).to.equal(0.0019499512512187196); 50 | }); 51 | }); 52 | 53 | describe("calcSpotPricesBadDecimal", () => { 54 | it("should return spot price of 0", () => { 55 | const ptReserves = BigNumber.from("1000000000000000"); 56 | const baseReserves = BigNumber.from("1612400925773352"); 57 | const totalSupply = baseReserves.add(ptReserves); 58 | const timeRemainingSeconds = THIRTY_DAYS_IN_SECONDS; 59 | const timeStretch = 4; 60 | const tParamSeconds = timeStretch * ONE_YEAR_IN_SECONDS; 61 | const result = calcSpotPricePt( 62 | baseReserves.toString(), 63 | ptReserves.toString(), 64 | totalSupply.toString(), 65 | timeRemainingSeconds, 66 | tParamSeconds, 67 | 42 68 | ); 69 | expect(result).to.equal(0); 70 | }); 71 | }); 72 | -------------------------------------------------------------------------------- /test/getSecondsUntilExpirationTest.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Element Finance, Inc 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { expect } from "chai"; 18 | import { ethers } from "hardhat"; 19 | 20 | import { 21 | //eslint-disable-next-line @typescript-eslint/no-unused-vars 22 | getSecondsUntilExpiration, 23 | getSecondsUntilExpirationByTokenInfo, 24 | } from "../src/helpers/getSecondsUntilExpiration"; 25 | import { initTokenList, getTokenInfo } from "../src/helpers/getTokenInfo"; 26 | import { PrincipalPoolTokenInfo } from "elf-tokenlist"; 27 | 28 | describe("getSecondsUntilExpiration", async () => { 29 | it("getsecondsUntilExpirationByTokenInfo() should return the correct time until expiration", async () => { 30 | const blockTimestamp = 1635000391; 31 | const result = initTokenList("mainnet"); 32 | const poolAddress = "0x893B30574BF183d69413717f30b17062eC9DFD8b"; 33 | const poolTokenInfo = getTokenInfo(poolAddress, result.tokenInfoByAddress); 34 | const getSecondsUntilExpirationByTokenInfoResult = 35 | getSecondsUntilExpirationByTokenInfo( 36 | poolTokenInfo as PrincipalPoolTokenInfo, 37 | blockTimestamp 38 | ); 39 | expect(getSecondsUntilExpirationByTokenInfoResult).to.equal(5619867); 40 | }); 41 | 42 | it("getSecondsUntilExpiration() should match getSecondsUntilExpirationByTokenInfo()", async () => { 43 | const [signer] = await ethers.getSigners(); 44 | const blockTimestamp = 1635000391; 45 | const result = initTokenList("mainnet"); 46 | const poolAddress = "0x893B30574BF183d69413717f30b17062eC9DFD8b"; 47 | const poolTokenInfo = getTokenInfo(poolAddress, result.tokenInfoByAddress); 48 | const getSecondsUntilExpirationByTokenInfoResult = 49 | getSecondsUntilExpirationByTokenInfo( 50 | poolTokenInfo as PrincipalPoolTokenInfo, 51 | blockTimestamp 52 | ); 53 | const getSecondsUntilExpirationResult = await getSecondsUntilExpiration( 54 | poolAddress, 55 | signer, 56 | blockTimestamp 57 | ); 58 | expect(getSecondsUntilExpirationByTokenInfoResult).to.equal( 59 | getSecondsUntilExpirationResult 60 | ); 61 | }); 62 | }); 63 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "commonjs", 5 | "esModuleInterop": true, 6 | "moduleResolution": "node", 7 | "strict": true, 8 | "resolveJsonModule": true, 9 | "declaration": true, 10 | "outDir": "compiled/", 11 | "baseUrl": ".", 12 | "paths": { 13 | "src/*": [ 14 | "./src/*" 15 | ] 16 | } 17 | }, 18 | // Include/Exclude is for collections or groups of files or folders, etc.. 19 | "include": [ 20 | "src/**/*.ts", 21 | "examples/**/*.ts" 22 | ], 23 | // Specify separate files directly by their path 24 | "files": [ 25 | "./hardhat.config.ts" 26 | ] 27 | } --------------------------------------------------------------------------------