├── .circleci ├── check_npm_version.sh └── config.yml ├── .env.example ├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── assets ├── legos-autocomplete.gif └── weight.png ├── docs ├── .nojekyll ├── README.md ├── _sidebar.md ├── aave.md ├── balancer.md ├── compound.md ├── curvefi.md ├── dydx.md ├── idle.md ├── index.html ├── kyber.md ├── maker.md ├── material-oceanic.css ├── mstable.md ├── onesplit.md ├── overview_mainnet_address.md ├── quickstart.md ├── synthetix.md ├── uniswap.md └── uniswapV2.md ├── jest.config.js ├── package-lock.json ├── package.json ├── scripts ├── genAddrMainnetOverview.js └── getAbisFromUMA.js ├── src ├── aave │ ├── abi │ │ ├── AToken.json │ │ ├── LendingPool.json │ │ ├── LendingPoolAddessProvider.json │ │ └── LendingPoolCore.json │ ├── contracts.ts │ ├── contracts │ │ ├── FlashloanReceiverBase.sol │ │ ├── IFlashLoanReceiver.sol │ │ ├── ILendingPool.sol │ │ └── ILendingPoolAddressesProvider.sol │ └── index.ts ├── balancer │ ├── abi │ │ ├── BActions.json │ │ ├── BFactory.json │ │ ├── BPool.json │ │ └── ExchangeProxy.json │ ├── contracts.ts │ ├── contracts │ │ ├── BFactory.sol │ │ ├── BPool.sol │ │ └── ExchangeProxy.sol │ └── index.ts ├── compound │ ├── README.md │ ├── abi │ │ ├── CEther.json │ │ ├── CToken.json │ │ ├── CompoundPriceOracle.json │ │ └── Comptroller.json │ ├── contracts.ts │ ├── contracts │ │ ├── ICEther.sol │ │ ├── ICToken.sol │ │ ├── ICompoundPriceOracle.sol │ │ └── IComptroller.sol │ └── index.ts ├── curvefi │ ├── abi │ │ ├── Curve.json │ │ ├── PoolToken.json │ │ └── Zap.json │ ├── contracts.ts │ ├── contracts │ │ ├── ICurveFiCurve.sol │ │ ├── ICurveFiPoolToken.sol │ │ └── ICurveFiZap.sol │ └── index.ts ├── dappsys │ ├── abi │ │ ├── DSProxy.json │ │ └── DSProxyFactory.json │ ├── contracts.ts │ └── index.ts ├── dydx │ ├── abi │ │ ├── AdminImpl.json │ │ ├── CanonicalOrders.json │ │ ├── DaiPriceOracle.json │ │ ├── Expiry.json │ │ ├── ExpiryV2.json │ │ ├── LimitOrders.json │ │ ├── LiquidatorProxyV1ForSoloMargin.json │ │ ├── OperationImpl.json │ │ ├── PayableProxyForSoloMargin.json │ │ ├── PolynomialInterestSetter.json │ │ ├── Refunder.json │ │ ├── SaiPriceOracle.json │ │ ├── SignedOperationProxy.json │ │ ├── SoloMargin.json │ │ ├── StopLimitOrders.json │ │ ├── UsdcPriceOracle.json │ │ └── WethPriceOracle.json │ ├── contracts.ts │ ├── contracts │ │ ├── DydxFlashloanBase.sol │ │ ├── ICallee.sol │ │ └── ISoloMargin.sol │ └── index.ts ├── erc20 │ ├── README.md │ ├── abi │ │ ├── ERC20.json │ │ └── WETH.json │ ├── index.ts │ └── tokens.ts ├── idle │ ├── abi │ │ └── IdleTokenV3.json │ ├── contracts.ts │ └── index.ts ├── index.ts ├── kyber │ ├── abi │ │ └── KyberNetworkProxy.json │ ├── contracts.ts │ ├── contracts │ │ └── KyberNetworkProxy.sol │ └── index.ts ├── maker │ ├── abi │ │ ├── DssCdpManager.json │ │ ├── DssProxyActions.json │ │ ├── Medianizer.json │ │ └── ProxyRegistry.json │ ├── contracts.ts │ ├── contracts │ │ ├── DssProxyActionsBase.sol │ │ ├── IDssProxyActions.sol │ │ └── IMedianizer.sol │ ├── ilks.ts │ ├── index.ts │ └── priceFeeds.ts ├── mstable │ ├── abi │ │ ├── AaveIntegration.json │ │ ├── BasketManager.json │ │ ├── CompoundIntegration.json │ │ ├── DelayedProxyAdmin.json │ │ ├── ForgeValidator.json │ │ ├── Masset.json │ │ ├── MassetValidationHelper.json │ │ ├── MetaToken.json │ │ ├── Nexus.json │ │ ├── RewardsDistributor.json │ │ ├── SavingsContract.json │ │ ├── SavingsManager.json │ │ └── StakingRewardsWithPlatformToken.json │ ├── contracts.ts │ ├── contracts │ │ ├── Masset.sol │ │ └── StakingRewardsWithPlatformToken.sol │ └── index.ts ├── onesplit │ ├── abi │ │ └── OneSplit.json │ ├── contracts.ts │ ├── contracts │ │ └── IOneSplit.sol │ └── index.ts ├── synthetix │ ├── abi │ │ ├── Depot.json │ │ ├── ExchangeRates.json │ │ ├── Exchanger.json │ │ ├── ProxyERC20.json │ │ ├── Synth.json │ │ └── Synthetix.json │ ├── contracts.ts │ ├── contracts │ │ ├── IDepot.sol │ │ ├── ISynth.sol │ │ └── ISynthetix.sol │ └── index.ts ├── uma │ ├── abi │ │ ├── AddressWhitelist.json │ │ ├── DesignatedVotingFactory.json │ │ ├── ExpiringMultiParty.json │ │ ├── ExpiringMultiPartyCreator.json │ │ ├── ExpiringMultiPartyLib.json │ │ ├── FinancialContractsAdmin.json │ │ ├── Finder.json │ │ ├── Governor.json │ │ ├── IdentifierWhitelist.json │ │ ├── Registry.json │ │ ├── Store.json │ │ ├── TokenFactory.json │ │ ├── Voting.json │ │ ├── VotingToken.json │ │ └── WETH9.json │ ├── contracts.ts │ └── index.ts ├── uniswap │ ├── abi │ │ ├── Exchange.json │ │ └── Factory.json │ ├── contracts.ts │ ├── contracts │ │ ├── IUniswapExchange.sol │ │ └── IUniswapFactory.sol │ └── index.ts └── uniswapV2 │ ├── abi │ ├── IUniswapV2Factory.json │ ├── IUniswapV2Pair.json │ ├── IUniswapV2Router01.json │ └── IUniswapV2Router02.json │ ├── contracts.ts │ ├── contracts │ ├── IUniswapV2Factory.sol │ ├── IUniswapV2Pair.sol │ ├── IUniswapV2Router01.sol │ └── IUniswapV2Router02.sol │ └── index.ts ├── tests ├── aave.test.sol ├── aave.test.ts ├── balancer.test.ts ├── compound.test.sol ├── compound.test.ts ├── index.test.ts ├── kyber.test.sol ├── kyber.test.ts ├── maker.test.ts ├── medianizer.test.ts ├── mstable.test.ts ├── synthetix.test.ts ├── test-environment.js ├── uniswap.test.ts ├── uniswapV2.test.ts └── utils.ts ├── tsconfig.json └── yarn.lock /.circleci/check_npm_version.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -o verbose 4 | set -v 5 | 6 | # https://stackoverflow.com/a/29394504/4634583 7 | # Compare semvar easily (this support 3 fields at most) 8 | function ver { printf "%03d%03d%03d" $(echo "$1" | tr '.' ' '); } 9 | 10 | PUBLISHED_PACKAGE_VER=$(npm view @studydefi/money-legos version) 11 | CURRENT_PACKAGE_VER=$(node -p "require('./package.json').version") 12 | 13 | if [[ $((10#$(ver $CURRENT_PACKAGE_VER))) -le $((10#$(ver $PUBLISHED_PACKAGE_VER))) ]]; then 14 | echo "Invalid package version" 15 | exit 1 16 | fi 17 | -------------------------------------------------------------------------------- /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | defaults: &defaults 2 | working_directory: ~/repo 3 | docker: 4 | - image: circleci/node:lts 5 | 6 | jobs: 7 | build: 8 | <<: *defaults 9 | steps: 10 | - checkout 11 | 12 | - restore_cache: 13 | name: Restore Yarn Package Cache 14 | keys: 15 | - yarn-packages-{{ checksum "yarn.lock" }} 16 | 17 | - run: 18 | name: Install Dependencies 19 | command: yarn install --frozen-lockfile 20 | 21 | - run: 22 | name: Run Tests 23 | command: yarn test 24 | 25 | - run: 26 | name: Build Project 27 | command: yarn build 28 | 29 | - save_cache: 30 | name: Save Yarn Package Cache 31 | key: yarn-packages-{{ checksum "yarn.lock" }} 32 | paths: 33 | - ~/.cache/yarn 34 | 35 | - persist_to_workspace: 36 | root: ~/repo 37 | paths: . 38 | 39 | publishDryRun: 40 | <<: *defaults 41 | steps: 42 | - attach_workspace: 43 | at: ~/repo 44 | 45 | - run: 46 | name: Check Package Version Valid on NPM 47 | command: ./.circleci/check_npm_version.sh 48 | 49 | publish: 50 | <<: *defaults 51 | steps: 52 | - attach_workspace: 53 | at: ~/repo 54 | - run: 55 | name: Authenticate with registry 56 | command: echo "//registry.npmjs.org/:_authToken=$npm_TOKEN" > ~/.npmrc 57 | - run: 58 | name: Publish package 59 | command: | 60 | # Sometimes we just wanna update the readme file 61 | if ./.circleci/check_npm_version.sh; then 62 | npm run dist 63 | fi 64 | 65 | workflows: 66 | version: 2 67 | install-publish: 68 | jobs: 69 | - build 70 | - publishDryRun: 71 | requires: 72 | - build 73 | filters: 74 | branches: 75 | ignore: 76 | - master 77 | - publish: 78 | requires: 79 | - build 80 | filters: 81 | branches: 82 | only: 83 | - master 84 | -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | PRIV_KEY= 2 | MAINNET_NODE_URL= 3 | 4 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.sol linguist-language=Solidity 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | .env 4 | .temp_* 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 StudyDeFi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # money-legos 2 | 3 | [![circleci](https://badgen.net/circleci/github/studydefi/money-legos)](https://app.circleci.com/pipelines/github/studydefi/money-legos) 4 | [![npm](https://badgen.net/npm/v/@studydefi/money-legos)](https://www.npmjs.com/package/@studydefi/money-legos) 5 | ![types](https://badgen.net/npm/types/@studydefi/money-legos) 6 | ![minzip](https://badgen.net/bundlephobia/minzip/@studydefi/money-legos) 7 | 8 | ![legos autocomplete](./assets/legos-autocomplete.gif) 9 | 10 | > Get **ABIs**, **Addresses**, and **Solidity Interfaces** to popular DeFi protocols 11 | 12 | **Now with Typescript-powered autocomplete!** 13 | 14 | `money-legos` is an NPM package that provides you with the **mainnet addresses**, **ABIs**, and **Solidity interfaces** for popular DeFi protocols. 15 | 16 | ### Click [here](https://money-legos.studydefi.com/) for docs and visit our Discord [here](https://discord.gg/rBr3U32)! 17 | 18 | Protocols supported: 19 | 20 | - AAVE 21 | - Compound 22 | - Curve Finance 23 | - DappSys 24 | - DyDx 25 | - ERC20 26 | - Idle V3 27 | - Kyber.Network 28 | - MakerDAO 29 | - OneSplit 30 | - UMA Protocol 31 | - Uniswap v1 32 | - Synthetix 33 | - Balancer 34 | - mStable 35 | - Uniswap v2 36 | 37 | Importing specific protocols is also supported: 38 | 39 | size 40 | 41 | ## Install 42 | 43 | ```bash 44 | npm install @studydefi/money-legos 45 | ``` 46 | 47 | ## Usage 48 | 49 | ### JavaScript 50 | 51 | ```javascript 52 | import { legos } from "@studydefi/money-legos"; 53 | 54 | // access ABIs and addresses 55 | legos.erc20.abi; 56 | legos.erc20.dai.address; 57 | 58 | // of many popular DeFi protocols 59 | legos.uniswap.factory.abi; 60 | legos.uniswap.factory.address; 61 | 62 | // import only the protocol you are interested in 63 | import uniswap from "@studydefi/money-legos/uniswap"; 64 | 65 | uniswap.factory.abi; 66 | uniswap.factory.address; 67 | ``` 68 | 69 | ### Solidity 70 | 71 | ```solidity 72 | pragma solidity ^0.5.0; 73 | 74 | import "@studydefi/money-legos/onesplit/contracts/IOneSplit.sol"; 75 | 76 | import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 77 | 78 | 79 | contract OneSplitSwapper { 80 | // Uniswap Mainnet factory address 81 | address constant OneSplitAddress = 0xC586BeF4a0992C495Cf22e1aeEE4E446CECDee0E; 82 | 83 | function _swap(address from, address to, uint256 amountWei) internal { 84 | IERC20 fromIERC20 = IERC20(from); 85 | IERC20 toIERC20 = IERC20(to); 86 | 87 | (uint256 returnAmount, uint256[] memory distribution) = IOneSplit( 88 | OneSplitAddress 89 | ).getExpectedReturn( 90 | fromIERC20, 91 | toIERC20, 92 | amountWei, 93 | 10, 94 | 0 95 | ); 96 | 97 | IOneSplit(OneSplitAddress).swap( 98 | fromIERC20, 99 | toIERC20, 100 | amountWei, 101 | returnAmount, 102 | distribution, 103 | 0 104 | ); 105 | } 106 | } 107 | ``` 108 | -------------------------------------------------------------------------------- /assets/legos-autocomplete.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/studydefi/money-legos/4e4cd1e45e2abeb0950e40c6fe70248322e1f5f2/assets/legos-autocomplete.gif -------------------------------------------------------------------------------- /assets/weight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/studydefi/money-legos/4e4cd1e45e2abeb0950e40c6fe70248322e1f5f2/assets/weight.png -------------------------------------------------------------------------------- /docs/.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/studydefi/money-legos/4e4cd1e45e2abeb0950e40c6fe70248322e1f5f2/docs/.nojekyll -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # money-legos 2 | 3 | ![circleci](https://badgen.net/circleci/github/studydefi/money-legos) 4 | ![npm](https://badgen.net/npm/v/@studydefi/money-legos) 5 | ![types](https://badgen.net/npm/types/@studydefi/money-legos) 6 | ![minzip](https://badgen.net/bundlephobia/minzip/@studydefi/money-legos) 7 | 8 | > Get **ABIs**, **Addresses**, and **Solidity Interfaces** to popular DeFi protocols 9 | 10 | **Now with Typescript-powered autocomplete!** 11 | 12 | - Github: https://github.com/studydefi/money-legos 13 | - NPM: https://www.npmjs.com/package/@studydefi/money-legos 14 | - Twitter: https://twitter.com/studydefi 15 | - Discord: https://discord.gg/rBr3U32 16 | 17 | ## What is this? 18 | 19 | `money-legos` is an NPM package that provides you with the **mainnet addresses**, **ABIs**, and **Solidity interfaces** for popular DeFi protocols. 20 | 21 | ![autocomplete](https://github.com/studydefi/money-legos/blob/master/assets/legos-autocomplete.gif?raw=true) 22 | 23 | ## Protocols supported 24 | 25 | - AAVE 26 | - Compound 27 | - Curve Finance 28 | - DappSys 29 | - DyDx 30 | - ERC20 31 | - Idle V3 32 | - Kyber.Network 33 | - MakerDAO 34 | - OneSplit 35 | - UMA 36 | - Uniswap v1 37 | - Synthetix 38 | - Balancer 39 | - mStable 40 | - Uniswap v2 41 | -------------------------------------------------------------------------------- /docs/_sidebar.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | - Overview 4 | 5 | - [Quick start](quickstart.md) 6 | - [Addresses](overview_mainnet_address.md) 7 | 8 | - Reference Guides 9 | - [Aave](aave.md) 10 | - [Compound](compound.md) 11 | - [CurveFi](curvefi.md) 12 | - [DyDx](dydx.md) 13 | - [Idle V3](idle.md) 14 | - [Kyber Network](kyber.md) 15 | - [Maker](maker.md) 16 | - [OneSplit](onesplit.md) 17 | - [Uniswap V1](uniswap.md) 18 | - [Synthetix](synthetix.md) 19 | - [Balancer](balancer.md) 20 | - [mStable](mstable.md) 21 | - [Uniswap V2](uniswapV2.md) 22 | -------------------------------------------------------------------------------- /docs/dydx.md: -------------------------------------------------------------------------------- 1 | # DyDx 2 | 3 | ## Flashloans On DyDx 4 | 5 | _Special thanks to [kollateral](http://github.com/kollateral/kollateral/) for open sourcing their implementation._ 6 | 7 | DyDx [does not natively have a "flashloan" feature](https://help.dydx.exchange/en/articles/3724602-flash-loans). However you can achieve a similar behavior by executing a series of operations on the [SoloMargin contract](https://etherscan.io/address/0x1e0447b19bb6ecfdae1e4ae1694b0c3659614e4e). In order mimic an Aave flashloan on DyDx, you would need to: 8 | 9 | 1. Borrow `x` amount of tokens. ([Withdraw](https://docs.dydx.exchange/#/protocol?id=withdraw)) 10 | 2. Call a function (i.e. Logic to handle flashloaned funds). ([Call](https://docs.dydx.exchange/#/protocol?id=call)) 11 | 3. Deposit back `x` (+2 wei) amount of tokens. ([Deposit](https://docs.dydx.exchange/#/protocol?id=deposit)) 12 | 13 | All within one transaction. The reason this works is because DyDx natively has this feature called [operate](https://docs.dydx.exchange/#/protocol?id=operations) which allows you to execute __a series of operations without checking if the state is valid until the final step__. That means that you can withdraw as much funds as you like, do anything with it, as long as you deposit back the funds (and have ~2 Wei of assets in your account) within the same transaction. 14 | 15 | Note that doing a flashloan in DyDx is similar to that of doing it in Aave, you'll need to: 16 | 17 | 1. Deploy a smart contract with specific logic to handle flashloaned asset. 18 | 2. Interact with the smart contract deployed from step 1. 19 | 20 | ### Flashloan Logic (Solidity) 21 | 22 | Your smart contract will need to inherit from `DydxFlashloanBase` and have two functions: 23 | 1. An entrypoint function where __you__ call to initiate the flashloan (`initiateFlashLoan` in the example below). 24 | 2. A callback function called `callFunction` that contains the action logic to perform once the loan is given to us. 25 | 26 | 27 | ```js 28 | pragma solidity ^0.5.0; 29 | pragma experimental ABIEncoderV2; 30 | 31 | import "@studydefi/money-legos/dydx/contracts/DydxFlashloanBase.sol"; 32 | import "@studydefi/money-legos/dydx/contracts/ICallee.sol"; 33 | 34 | import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 35 | 36 | 37 | contract DydxFlashloaner is ICallee, DydxFlashloanBase { 38 | struct MyCustomData { 39 | address token; 40 | uint256 repayAmount; 41 | } 42 | 43 | // This is the function that will be called postLoan 44 | // i.e. Encode the logic to handle your flashloaned funds here 45 | function callFunction( 46 | address sender, 47 | Account.Info memory account, 48 | bytes memory data 49 | ) public { 50 | MyCustomData memory mcd = abi.decode(data, (MyCustomData)); 51 | uint256 balOfLoanedToken = IERC20(mcd.token).balanceOf(address(this)); 52 | 53 | // Note that you can ignore the line below 54 | // if your dydx account (this contract in this case) 55 | // has deposited at least ~2 Wei of assets into the account 56 | // to balance out the collaterization ratio 57 | require( 58 | balOfLoanedToken >= mcd.repayAmount, 59 | "Not enough funds to repay dydx loan!" 60 | ); 61 | 62 | // TODO: Encode your logic here 63 | // E.g. arbitrage, liquidate accounts, etc 64 | revert("Hello, you haven't encoded your logic"); 65 | } 66 | 67 | function initiateFlashLoan(address _solo, address _token, uint256 _amount) 68 | external 69 | { 70 | ISoloMargin solo = ISoloMargin(_solo); 71 | 72 | // Get marketId from token address 73 | uint256 marketId = _getMarketIdFromTokenAddress(_solo, _token); 74 | 75 | // Calculate repay amount (_amount + (2 wei)) 76 | // Approve transfer from 77 | uint256 repayAmount = _getRepaymentAmountInternal(_amount); 78 | IERC20(_token).approve(_solo, repayAmount); 79 | 80 | // 1. Withdraw $ 81 | // 2. Call callFunction(...) 82 | // 3. Deposit back $ 83 | Actions.ActionArgs[] memory operations = new Actions.ActionArgs[](3); 84 | 85 | operations[0] = _getWithdrawAction(marketId, _amount); 86 | operations[1] = _getCallAction( 87 | // Encode MyCustomData for callFunction 88 | abi.encode(MyCustomData({token: _token, repayAmount: repayAmount})) 89 | ); 90 | operations[2] = _getDepositAction(marketId, repayAmount); 91 | 92 | Account.Info[] memory accountInfos = new Account.Info[](1); 93 | accountInfos[0] = _getAccountInfo(); 94 | 95 | solo.operate(accountInfos, operations); 96 | } 97 | } 98 | ``` 99 | 100 | ### Flashloan Initiation (JavaScript) 101 | 102 | Once you've deployed the contract, you can then call initiate the flashloan using the example below. Note that you can `MyCustomData` can be anything you desire, and if you would like to encode the data from the JS side, you can use `ethers.utils.defaultAbiCoder`. 103 | 104 | ```js 105 | const dydxFlashloanerContract = new ethers.Contract( 106 | dydxFlashloanerAddress, 107 | def.abi, 108 | wallet 109 | ); 110 | 111 | const main = async () => { 112 | const tx = await dydxFlashloanerContract.initiateFlashLoan( 113 | legos.dydx.soloMargin.address, 114 | legos.erc20.weth.address, // Wanna take out a WETH loan 115 | ethers.utils.parseEther("10"), // Wanna loan 10 WETH 116 | { 117 | gasLimit: 6000000, 118 | } 119 | ); 120 | await tx.wait(); 121 | }; 122 | ``` 123 | -------------------------------------------------------------------------------- /docs/idle.md: -------------------------------------------------------------------------------- 1 | # Idle (V3) 2 | 3 | [Official Idle documentation](https://developers.idle.finance/) 4 | 5 | ## Examples 6 | 7 | Import `@studydefi/money-legos/idle` package 8 | 9 | ```js 10 | const idle = require("@studydefi/money-legos/idle"); 11 | ``` 12 | 13 | List of all available contracts 14 | 15 | ```js 16 | idle.maxYield.dai.address; 17 | idle.maxYield.usdc.address; 18 | idle.maxYield.usdt.address; 19 | idle.maxYield.susd.address; 20 | idle.maxYield.tusd.address; 21 | idle.maxYield.wbtc.address; 22 | 23 | idle.riskAdjusted.dai.address; 24 | idle.riskAdjusted.usdc.address; 25 | idle.riskAdjusted.usdt.address; 26 | 27 | idle.abi; // the same abi for each idle v3 contract 28 | 29 | idle.decimals; // idle mints ERC-20 tokens 30 | ``` 31 | 32 | ### JavaScript 33 | 34 | #### `mintIdleToken` 35 | 36 | ```js 37 | const { ethers } = require("ethers"); 38 | const erc20 = require("@studydefi/money-legos/erc20"); 39 | const idle = require("@studydefi/money-legos/idle"); 40 | 41 | const provider = new ethers.providers.JsonRpcProvider("http://localhost:8545"); 42 | const wallet = new ethers.Wallet(process.env.GANACHE_PRIV_KEY, provider); 43 | 44 | // init contracts 45 | const daiContract = new ethers.Contract(erc20.dai.address, erc20.abi, wallet); 46 | const idleContract = new ethers.Contract( 47 | idle.maxYield.dai.address, 48 | idle.abi, 49 | wallet, 50 | ); 51 | 52 | // approve Idle to spend your DAI 53 | const daiBalanceWei = await daiContract.balanceOf(wallet.address); 54 | await daiContract.approve(idle.maxYield.dai.address, daiBalanceWei); 55 | 56 | // mint idleDAIYield 57 | await idleContract.mintIdleToken(daiBalanceWei, true, { 58 | gasLimit: 4000000, 59 | }); 60 | 61 | // check idleDAI balance 62 | const idleDaiBalance = await idleContract.balanceOf(wallet.address); 63 | console.log( 64 | `idleDAI: ${ethers.utils.formatUnits(idleDaiBalance, idle.decimals)}`, 65 | ); 66 | ``` 67 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | money-legos docs 6 | 7 | 8 | 12 | 16 | 20 | 24 | 28 | 29 | 30 | 31 | 55 | 56 | 57 | 58 |
Loading ...
59 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /docs/material-oceanic.css: -------------------------------------------------------------------------------- 1 | code[class*="language-"], 2 | pre[class*="language-"] { 3 | text-align: left; 4 | white-space: pre; 5 | word-spacing: normal; 6 | word-break: normal; 7 | word-wrap: normal; 8 | color: #c3cee3; 9 | background: #263238; 10 | font-family: Roboto Mono, monospace; 11 | font-size: 1em; 12 | line-height: 1.5em; 13 | 14 | -moz-tab-size: 4; 15 | -o-tab-size: 4; 16 | tab-size: 4; 17 | 18 | -webkit-hyphens: none; 19 | -moz-hyphens: none; 20 | -ms-hyphens: none; 21 | hyphens: none; 22 | } 23 | 24 | code[class*="language-"]::-moz-selection, 25 | pre[class*="language-"]::-moz-selection, 26 | code[class*="language-"] ::-moz-selection, 27 | pre[class*="language-"] ::-moz-selection { 28 | background: #363636; 29 | } 30 | 31 | code[class*="language-"]::selection, 32 | pre[class*="language-"]::selection, 33 | code[class*="language-"] ::selection, 34 | pre[class*="language-"] ::selection { 35 | background: #363636; 36 | } 37 | 38 | :not(pre) > code[class*="language-"] { 39 | white-space: normal; 40 | border-radius: 0.2em; 41 | padding: 0.1em; 42 | } 43 | 44 | pre[class*="language-"] { 45 | overflow: auto; 46 | position: relative; 47 | margin: 0.5em 0; 48 | padding: 1.25em 1em; 49 | } 50 | 51 | .language-css > code, 52 | .language-sass > code, 53 | .language-scss > code { 54 | color: #fd9170; 55 | } 56 | 57 | [class*="language-"] .namespace { 58 | opacity: 0.7; 59 | } 60 | 61 | .token.atrule { 62 | color: #c792ea; 63 | } 64 | 65 | .token.attr-name { 66 | color: #ffcb6b; 67 | } 68 | 69 | .token.attr-value { 70 | color: #c3e88d; 71 | } 72 | 73 | .token.attribute { 74 | color: #c3e88d; 75 | } 76 | 77 | .token.boolean { 78 | color: #c792ea; 79 | } 80 | 81 | .token.builtin { 82 | color: #ffcb6b; 83 | } 84 | 85 | .token.cdata { 86 | color: #80cbc4; 87 | } 88 | 89 | .token.char { 90 | color: #80cbc4; 91 | } 92 | 93 | .token.class { 94 | color: #ffcb6b; 95 | } 96 | 97 | .token.class-name { 98 | color: #f2ff00; 99 | } 100 | 101 | .token.color { 102 | color: #f2ff00; 103 | } 104 | 105 | .token.comment { 106 | color: #546e7a; 107 | } 108 | 109 | .token.constant { 110 | color: #c792ea; 111 | } 112 | 113 | .token.deleted { 114 | color: #f07178; 115 | } 116 | 117 | .token.doctype { 118 | color: #546e7a; 119 | } 120 | 121 | .token.entity { 122 | color: #f07178; 123 | } 124 | 125 | .token.function { 126 | color: #c792ea; 127 | } 128 | 129 | .token.hexcode { 130 | color: #f2ff00; 131 | } 132 | 133 | .token.id { 134 | color: #c792ea; 135 | font-weight: bold; 136 | } 137 | 138 | .token.important { 139 | color: #c792ea; 140 | font-weight: bold; 141 | } 142 | 143 | .token.inserted { 144 | color: #80cbc4; 145 | } 146 | 147 | .token.keyword { 148 | color: #c792ea; 149 | font-style: italic; 150 | } 151 | 152 | .token.number { 153 | color: #fd9170; 154 | } 155 | 156 | .token.operator { 157 | color: #89ddff; 158 | } 159 | 160 | .token.prolog { 161 | color: #546e7a; 162 | } 163 | 164 | .token.property { 165 | color: #80cbc4; 166 | } 167 | 168 | .token.pseudo-class { 169 | color: #c3e88d; 170 | } 171 | 172 | .token.pseudo-element { 173 | color: #c3e88d; 174 | } 175 | 176 | .token.punctuation { 177 | color: #89ddff; 178 | } 179 | 180 | .token.regex { 181 | color: #f2ff00; 182 | } 183 | 184 | .token.selector { 185 | color: #f07178; 186 | } 187 | 188 | .token.string { 189 | color: #c3e88d; 190 | } 191 | 192 | .token.symbol { 193 | color: #c792ea; 194 | } 195 | 196 | .token.tag { 197 | color: #f07178; 198 | } 199 | 200 | .token.unit { 201 | color: #f07178; 202 | } 203 | 204 | .token.url { 205 | color: #fd9170; 206 | } 207 | 208 | .token.variable { 209 | color: #f07178; 210 | } -------------------------------------------------------------------------------- /docs/quickstart.md: -------------------------------------------------------------------------------- 1 | # Quickstart 2 | 3 | ## Install 4 | 5 | ```bash 6 | npm install @studydefi/money-legos 7 | ``` 8 | 9 | ## Javascript Usage 10 | 11 | First import the module: 12 | 13 | ```js 14 | import { legos } from "@studydefi/money-legos"; 15 | ``` 16 | 17 | Navigate the JSON tree full of ABIs and addresses: 18 | 19 | ```js 20 | // protocols 21 | legos.uniswap.factory.abi; 22 | legos.uniswap.factory.address; 23 | 24 | // erc20 tokens 25 | legos.erc20.abi; 26 | legos.erc20.dai.address; 27 | ``` 28 | 29 | You can also import specific protocols: 30 | 31 | ```js 32 | // import only the protocol you are interested in 33 | import uniswap from "@studydefi/money-legos/uniswap"; 34 | 35 | uniswap.factory.abi; 36 | uniswap.factory.address; 37 | ``` 38 | 39 | ## Solidity Usage 40 | 41 | ```js 42 | pragma solidity ^0.5.0; 43 | 44 | import "@studydefi/money-legos/onesplit/contracts/IOneSplit.sol"; 45 | 46 | import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 47 | 48 | 49 | contract OneSplitSwapper { 50 | // Uniswap Mainnet factory address 51 | address constant OneSplitAddress = 0xC586BeF4a0992C495Cf22e1aeEE4E446CECDee0E; 52 | 53 | function _swap(address from, address to, uint256 amountWei) internal { 54 | IERC20 fromIERC20 = IERC20(from); 55 | IERC20 toIERC20 = IERC20(to); 56 | 57 | (uint256 returnAmount, uint256[] memory distribution) = IOneSplit( 58 | OneSplitAddress 59 | ).getExpectedReturn( 60 | fromIERC20, 61 | toIERC20, 62 | amountWei, 63 | 10, 64 | 0 65 | ); 66 | 67 | IOneSplit(OneSplitAddress).swap( 68 | fromIERC20, 69 | toIERC20, 70 | amountWei, 71 | returnAmount, 72 | distribution, 73 | 0 74 | ); 75 | } 76 | } 77 | ``` 78 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: 'ts-jest', 3 | testEnvironment: './tests/test-environment.js', 4 | modulePathIgnorePatterns: ["/dist/"] 5 | }; 6 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@studydefi/money-legos", 3 | "version": "2.4.2", 4 | "main": "index.js", 5 | "types": "index.d.ts", 6 | "repository": "git@github.com:studydefi/money-legos.git", 7 | "author": "Adrian Li ", 8 | "license": "MIT", 9 | "scripts": { 10 | "clean": "rm -rf dist", 11 | "build": "yarn clean && tsc --declaration && cp package.json dist && cp README.md dist", 12 | "postbuild": "copyfiles --verbose -u 1 src/**/*.sol dist", 13 | "build:docs": "embedme docs/* && yarn build && node scripts/genAddrMainnetOverview.js > docs/overview_mainnet_address.md", 14 | "serve:docs": "docsify serve ./docs", 15 | "test": "jest --verbose", 16 | "link": "yarn build && cd dist && npm link", 17 | "prepublishOnly": "echo \"Error: Don't run 'npm publish' in root. Use 'npm run dist' instead.\" && exit 1", 18 | "dist": "cd dist && npm publish --ignore-scripts --access public" 19 | }, 20 | "devDependencies": { 21 | "@types/jest": "^25.2.1", 22 | "@types/node": "^13.13.0", 23 | "copyfiles": "^2.2.0", 24 | "docsify-cli": "^4.4.0", 25 | "dotenv": "^8.2.0", 26 | "embedme": "^1.21.0", 27 | "ethers": "^4.0.46", 28 | "ganache-core": "^2.10.2", 29 | "jest": "^25.3.0", 30 | "json2md": "^1.7.0", 31 | "ts-jest": "^25.3.1", 32 | "typescript": "^3.8.3" 33 | }, 34 | "prettier": { 35 | "trailingComma": "all" 36 | }, 37 | "keywords": [ 38 | "ethereum", 39 | "abi", 40 | "defi", 41 | "defi addresses", 42 | "defi abi", 43 | "ethereum abi", 44 | "ethereum address", 45 | "money-legos" 46 | ], 47 | "dependencies": { 48 | "@openzeppelin/contracts": "^2.5.0" 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /scripts/genAddrMainnetOverview.js: -------------------------------------------------------------------------------- 1 | const json2md = require("json2md"); 2 | const { legos } = require("../dist"); 3 | 4 | const prettyTitle = (t) => t.charAt(0).toUpperCase() + t.slice(1); 5 | const formatToEtherscanLink = (l) => 6 | `[${l}](https://etherscan.io/address/${l})`; 7 | 8 | // Funky protocols with different structures 9 | // Need to construct the markdown a bit differently 10 | const funkyProtocols = ["curvefi", "idle"]; 11 | const noRenderProtocols = ["dappsys"]; 12 | 13 | // Generated markdown 14 | const markdown = [{ h1: "Mainnet Address Overview" }]; 15 | 16 | // Builds the overview page 17 | Object.keys(legos) 18 | .sort() 19 | .forEach((curDefiProtocol) => { 20 | // Don't wanna render these defi libraries 21 | if (noRenderProtocols.includes(curDefiProtocol.toLowerCase())) { 22 | return; 23 | } 24 | 25 | markdown.push({ 26 | h2: prettyTitle(curDefiProtocol), 27 | }); 28 | 29 | markdown.push({ 30 | link: { 31 | title: "Link to ABIs", 32 | source: `https://github.com/studydefi/money-legos/tree/master/src/${curDefiProtocol}/abi`, 33 | }, 34 | }); 35 | 36 | const contracts = legos[curDefiProtocol]; 37 | 38 | // If its a funky protocol, we need to do some custom formatting 39 | // E.g. curveFi, where it has multiple contracts, each for a different 40 | // 41 | if (funkyProtocols.includes(curDefiProtocol.toLowerCase())) { 42 | Object.keys(contracts) 43 | .sort() 44 | .forEach((outerContractName) => { 45 | const ul = []; 46 | 47 | const innerContracts = contracts[outerContractName]; 48 | 49 | Object.keys(innerContracts) 50 | .sort() 51 | .forEach((innerContractName) => { 52 | const innerContract = innerContracts[innerContractName]; 53 | if (Object.keys(innerContract).includes("address")) { 54 | ul.push( 55 | `${innerContractName}: ${formatToEtherscanLink( 56 | innerContract["address"], 57 | )}`, 58 | ); 59 | } 60 | }); 61 | 62 | if (ul.length > 0) { 63 | markdown.push({ 64 | h4: `${outerContractName}`, 65 | }); 66 | markdown.push({ ul }); 67 | } 68 | }); 69 | } 70 | // If its a single contract with no one (e.g. oneSplit) 71 | else if (Object.keys(contracts).includes("address")) { 72 | const ul = [ 73 | `${curDefiProtocol}: ${formatToEtherscanLink(contracts["address"])}`, 74 | ]; 75 | markdown.push({ ul }); 76 | } 77 | // Standard format 78 | else { 79 | const ul = []; 80 | 81 | // Otherwise we can just get k/v from the contracts key 82 | Object.keys(contracts) 83 | .sort() 84 | .forEach((contractName) => { 85 | // Quick reference 86 | const contract = contracts[contractName]; 87 | 88 | // If the current key has "contract" in it 89 | if (Object.keys(contract).includes("address")) { 90 | ul.push( 91 | `${contractName}: ${formatToEtherscanLink(contract["address"])}`, 92 | ); 93 | } 94 | }); 95 | 96 | markdown.push({ ul }); 97 | } 98 | }); 99 | 100 | console.log(json2md(markdown)); 101 | -------------------------------------------------------------------------------- /scripts/getAbisFromUMA.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const fs = require("fs"); 3 | 4 | // Usage: node scripts/getAbisFromUMA.js 5 | 6 | // only include the following contracts 7 | const fileFilter = [ 8 | "Finder", 9 | "VotingToken", 10 | "IdentifierWhitelist", 11 | "Voting", 12 | "Registry", 13 | "FinancialContractsAdmin", 14 | "Store", 15 | "Governor", 16 | "DesignatedVotingFactory", 17 | "WETH9", 18 | "ExpiringMultiPartyLib", 19 | "ExpiringMultiParty", 20 | "TokenFactory", 21 | "AddressWhitelist", 22 | "ExpiringMultiPartyCreator", 23 | ]; 24 | 25 | // get all JSON files from their artifacts directory 26 | const inputPath = process.argv[2]; 27 | const artifactPath = path.join(inputPath, "./core/build/contracts"); 28 | const filenames = fs.readdirSync(artifactPath); 29 | 30 | // create a fresh temp folder to hold ABIs 31 | const outputDir = path.join(process.cwd(), "./src/uma/abi"); 32 | if (fs.existsSync(outputDir)) { 33 | fs.rmdirSync(outputDir, { recursive: true }); 34 | } 35 | fs.mkdirSync(outputDir); 36 | 37 | // write ABIs to new files 38 | filenames.forEach((filename) => { 39 | const contents = require(path.join(artifactPath, filename)); 40 | const name = filename.split(".").slice(0, -1).join("."); 41 | 42 | if (fileFilter.includes(name)) { 43 | const outputPath = path.join(outputDir, filename); 44 | fs.writeFileSync(outputPath, JSON.stringify(contents.abi, null, 2)); 45 | console.log("written:", outputPath); 46 | } 47 | }); 48 | -------------------------------------------------------------------------------- /src/aave/contracts.ts: -------------------------------------------------------------------------------- 1 | import ATokenAbi from "./abi/AToken.json"; 2 | import LendingPoolAbi from "./abi/LendingPool.json"; 3 | import LendingPoolAddressesProviderAbi from "./abi/LendingPoolAddessProvider.json"; 4 | import LendingPoolCoreAbi from "./abi/LendingPoolCore.json"; 5 | 6 | const contracts = { 7 | ATokenAbi, 8 | LendingPoolAddressesProvider: { 9 | abi: LendingPoolAddressesProviderAbi, 10 | address: "0x24a42fd28c976a61df5d00d0599c34c4f90748c8", 11 | }, 12 | LendingPool: { 13 | abi: LendingPoolAbi, 14 | address: "0x398ec7346dcd622edc5ae82352f02be94c62d119", 15 | }, 16 | LendingPoolCore: { 17 | abi: LendingPoolCoreAbi, 18 | address: "0x3dfd23a6c5e8bbcfc9581d2e864a68feb6a076d3", 19 | }, 20 | aETH: { 21 | address: "0x3a3a65aab0dd2a17e3f1947ba16138cd37d08c04", 22 | abi: ATokenAbi, 23 | decimals: 18, 24 | }, 25 | aDAI: { 26 | address: "0xfc1e690f61efd961294b3e1ce3313fbd8aa4f85d", 27 | abi: ATokenAbi, 28 | decimals: 18, 29 | }, 30 | aUSDC: { 31 | address: "0x9ba00d6856a4edf4665bca2c2309936572473b7e", 32 | abi: ATokenAbi, 33 | decimals: 6, 34 | }, 35 | aSUSD: { 36 | address: "0x625ae63000f46200499120b906716420bd059240", 37 | abi: ATokenAbi, 38 | decimals: 18, 39 | }, 40 | aTUSD: { 41 | address: "0x4da9b813057d04baef4e5800e36083717b4a0341", 42 | abi: ATokenAbi, 43 | decimals: 18, 44 | }, 45 | aUSDT: { 46 | address: "0x71fc860f7d3a592a4a98740e39db31d25db65ae8", 47 | abi: ATokenAbi, 48 | decimals: 6, 49 | }, 50 | aBUSD: { 51 | address: "0x6ee0f7bb50a54ab5253da0667b0dc2ee526c30a8", 52 | abi: ATokenAbi, 53 | decimals: 18, 54 | }, 55 | aBAT: { 56 | address: "0xe1ba0fb44ccb0d11b80f92f4f8ed94ca3ff51d00", 57 | abi: ATokenAbi, 58 | decimals: 18, 59 | }, 60 | aKNC: { 61 | address: "0x9d91be44c06d373a8a226e1f3b146956083803eb", 62 | abi: ATokenAbi, 63 | decimals: 18, 64 | }, 65 | aLEND: { 66 | address: "0x7d2d3688df45ce7c552e19c27e007673da9204b8", 67 | abi: ATokenAbi, 68 | decimals: 18, 69 | }, 70 | aLINK: { 71 | address: "0xa64bd6c70cb9051f6a9ba1f163fdc07e0dfb5f84", 72 | abi: ATokenAbi, 73 | decimals: 18, 74 | }, 75 | aMANA: { 76 | address: "0x6fce4a401b6b80ace52baaefe4421bd188e76f6f", 77 | abi: ATokenAbi, 78 | decimals: 18, 79 | }, 80 | aMKR: { 81 | address: "0x7deb5e830be29f91e298ba5ff1356bb7f8146998", 82 | abi: ATokenAbi, 83 | decimals: 18, 84 | }, 85 | aREP: { 86 | address: "0x71010a9d003445ac60c4e6a7017c1e89a477b438", 87 | abi: ATokenAbi, 88 | decimals: 18, 89 | }, 90 | aSNX: { 91 | address: "0x328c4c80bc7aca0834db37e6600a6c49e12da4de", 92 | abi: ATokenAbi, 93 | decimals: 18, 94 | }, 95 | aWBTC: { 96 | address: "0xfc4b8ed459e00e5400be803a9bb3954234fd50e3", 97 | abi: ATokenAbi, 98 | decimals: 8, 99 | }, 100 | aZRX: { 101 | address: "0x6fb0855c404e09c47c3fbca25f08d4e41f9f062f", 102 | abi: ATokenAbi, 103 | decimals: 18, 104 | }, 105 | }; 106 | 107 | export default contracts; 108 | -------------------------------------------------------------------------------- /src/aave/contracts/FlashloanReceiverBase.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.8.0; 2 | 3 | import "./IFlashLoanReceiver.sol"; 4 | 5 | contract FlashLoanReceiverBase is IFlashLoanReceiver { 6 | using SafeMath for uint256; 7 | 8 | address constant ETHADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; 9 | 10 | ILendingPoolAddressesProvider public addressesProvider = ILendingPoolAddressesProvider( 11 | 0x24a42fD28C976A61Df5D00D0599C34c4f90748c8 12 | ); 13 | 14 | function() external payable {} 15 | 16 | function transferFundsBackToPoolInternal(address _reserve, uint256 _amount) 17 | internal 18 | { 19 | address payable core = addressesProvider.getLendingPoolCore(); 20 | transferInternal(core, _reserve, _amount); 21 | } 22 | 23 | function transferInternal( 24 | address payable _destination, 25 | address _reserve, 26 | uint256 _amount 27 | ) internal { 28 | if (_reserve == ETHADDRESS) { 29 | //solium-disable-next-line 30 | _destination.call.value(_amount)(""); 31 | return; 32 | } 33 | 34 | IERC20(_reserve).transfer(_destination, _amount); 35 | } 36 | 37 | function getBalanceInternal(address _target, address _reserve) 38 | internal 39 | view 40 | returns (uint256) 41 | { 42 | if (_reserve == ETHADDRESS) { 43 | return _target.balance; 44 | } 45 | 46 | return IERC20(_reserve).balanceOf(_target); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/aave/contracts/IFlashLoanReceiver.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.8.0; 2 | 3 | import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 4 | 5 | import "./ILendingPoolAddressesProvider.sol"; 6 | 7 | 8 | interface IFlashLoanReceiver { 9 | function executeOperation( 10 | address _reserve, 11 | uint256 _amount, 12 | uint256 _fee, 13 | bytes calldata _params 14 | ) external; 15 | } 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/aave/contracts/ILendingPool.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.8.0; 2 | 3 | interface ILendingPool { 4 | function addressesProvider () external view returns ( address ); 5 | function deposit ( address _reserve, uint256 _amount, uint16 _referralCode ) external payable; 6 | function redeemUnderlying ( address _reserve, address _user, uint256 _amount ) external; 7 | function borrow ( address _reserve, uint256 _amount, uint256 _interestRateMode, uint16 _referralCode ) external; 8 | function repay ( address _reserve, uint256 _amount, address _onBehalfOf ) external payable; 9 | function swapBorrowRateMode ( address _reserve ) external; 10 | function rebalanceFixedBorrowRate ( address _reserve, address _user ) external; 11 | function setUserUseReserveAsCollateral ( address _reserve, bool _useAsCollateral ) external; 12 | function liquidationCall ( address _collateral, address _reserve, address _user, uint256 _purchaseAmount, bool _receiveAToken ) external payable; 13 | function flashLoan ( address _receiver, address _reserve, uint256 _amount, bytes calldata _params ) external; 14 | function getReserveConfigurationData ( address _reserve ) external view returns ( uint256 ltv, uint256 liquidationThreshold, uint256 liquidationDiscount, address interestRateStrategyAddress, bool usageAsCollateralEnabled, bool borrowingEnabled, bool fixedBorrowRateEnabled, bool isActive ); 15 | function getReserveData ( address _reserve ) external view returns ( uint256 totalLiquidity, uint256 availableLiquidity, uint256 totalBorrowsFixed, uint256 totalBorrowsVariable, uint256 liquidityRate, uint256 variableBorrowRate, uint256 fixedBorrowRate, uint256 averageFixedBorrowRate, uint256 utilizationRate, uint256 liquidityIndex, uint256 variableBorrowIndex, address aTokenAddress, uint40 lastUpdateTimestamp ); 16 | function getUserAccountData ( address _user ) external view returns ( uint256 totalLiquidityETH, uint256 totalCollateralETH, uint256 totalBorrowsETH, uint256 availableBorrowsETH, uint256 currentLiquidationThreshold, uint256 ltv, uint256 healthFactor ); 17 | function getUserReserveData ( address _reserve, address _user ) external view returns ( uint256 currentATokenBalance, uint256 currentUnderlyingBalance, uint256 currentBorrowBalance, uint256 principalBorrowBalance, uint256 borrowRateMode, uint256 borrowRate, uint256 liquidityRate, uint256 originationFee, uint256 variableBorrowIndex, uint256 lastUpdateTimestamp, bool usageAsCollateralEnabled ); 18 | function getReserves () external view; 19 | } 20 | -------------------------------------------------------------------------------- /src/aave/contracts/ILendingPoolAddressesProvider.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.8.0; 2 | 3 | /** 4 | @title ILendingPoolAddressesProvider interface 5 | @notice provides the interface to fetch the LendingPoolCore address 6 | */ 7 | 8 | contract ILendingPoolAddressesProvider { 9 | 10 | function getLendingPool() public view returns (address); 11 | function setLendingPoolImpl(address _pool) public; 12 | 13 | function getLendingPoolCore() public view returns (address payable); 14 | function setLendingPoolCoreImpl(address _lendingPoolCore) public; 15 | 16 | function getLendingPoolConfigurator() public view returns (address); 17 | function setLendingPoolConfiguratorImpl(address _configurator) public; 18 | 19 | function getLendingPoolDataProvider() public view returns (address); 20 | function setLendingPoolDataProviderImpl(address _provider) public; 21 | 22 | function getLendingPoolParametersProvider() public view returns (address); 23 | function setLendingPoolParametersProviderImpl(address _parametersProvider) public; 24 | 25 | function getTokenDistributor() public view returns (address); 26 | function setTokenDistributor(address _tokenDistributor) public; 27 | 28 | function getFeeProvider() public view returns (address); 29 | function setFeeProviderImpl(address _feeProvider) public; 30 | 31 | function getLendingPoolLiquidationManager() public view returns (address); 32 | function setLendingPoolLiquidationManager(address _manager) public; 33 | 34 | function getLendingPoolManager() public view returns (address); 35 | function setLendingPoolManager(address _lendingPoolManager) public; 36 | 37 | function getPriceOracle() public view returns (address); 38 | function setPriceOracle(address _priceOracle) public; 39 | 40 | function getLendingRateOracle() public view returns (address); 41 | function setLendingRateOracle(address _lendingRateOracle) public; 42 | 43 | } -------------------------------------------------------------------------------- /src/aave/index.ts: -------------------------------------------------------------------------------- 1 | import { default as contracts } from "./contracts"; 2 | 3 | export = { 4 | ...contracts, 5 | }; 6 | -------------------------------------------------------------------------------- /src/balancer/abi/BActions.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "constant": false, 4 | "inputs": [ 5 | { 6 | "internalType": "contract BFactory", 7 | "name": "factory", 8 | "type": "address" 9 | }, 10 | { "internalType": "address[]", "name": "tokens", "type": "address[]" }, 11 | { "internalType": "uint256[]", "name": "balances", "type": "uint256[]" }, 12 | { "internalType": "uint256[]", "name": "denorms", "type": "uint256[]" }, 13 | { "internalType": "uint256", "name": "swapFee", "type": "uint256" }, 14 | { "internalType": "bool", "name": "finalize", "type": "bool" } 15 | ], 16 | "name": "create", 17 | "outputs": [ 18 | { "internalType": "contract BPool", "name": "pool", "type": "address" } 19 | ], 20 | "payable": false, 21 | "stateMutability": "nonpayable", 22 | "type": "function" 23 | }, 24 | { 25 | "constant": false, 26 | "inputs": [ 27 | { "internalType": "contract BPool", "name": "pool", "type": "address" } 28 | ], 29 | "name": "finalize", 30 | "outputs": [], 31 | "payable": false, 32 | "stateMutability": "nonpayable", 33 | "type": "function" 34 | }, 35 | { 36 | "constant": false, 37 | "inputs": [ 38 | { "internalType": "contract BPool", "name": "pool", "type": "address" }, 39 | { "internalType": "uint256", "name": "poolAmountOut", "type": "uint256" }, 40 | { 41 | "internalType": "uint256[]", 42 | "name": "maxAmountsIn", 43 | "type": "uint256[]" 44 | } 45 | ], 46 | "name": "joinPool", 47 | "outputs": [], 48 | "payable": false, 49 | "stateMutability": "nonpayable", 50 | "type": "function" 51 | }, 52 | { 53 | "constant": false, 54 | "inputs": [ 55 | { "internalType": "contract BPool", "name": "pool", "type": "address" }, 56 | { "internalType": "address", "name": "tokenIn", "type": "address" }, 57 | { "internalType": "uint256", "name": "tokenAmountIn", "type": "uint256" }, 58 | { 59 | "internalType": "uint256", 60 | "name": "minPoolAmountOut", 61 | "type": "uint256" 62 | } 63 | ], 64 | "name": "joinswapExternAmountIn", 65 | "outputs": [], 66 | "payable": false, 67 | "stateMutability": "nonpayable", 68 | "type": "function" 69 | }, 70 | { 71 | "constant": false, 72 | "inputs": [ 73 | { "internalType": "contract BPool", "name": "pool", "type": "address" }, 74 | { "internalType": "address", "name": "newController", "type": "address" } 75 | ], 76 | "name": "setController", 77 | "outputs": [], 78 | "payable": false, 79 | "stateMutability": "nonpayable", 80 | "type": "function" 81 | }, 82 | { 83 | "constant": false, 84 | "inputs": [ 85 | { "internalType": "contract BPool", "name": "pool", "type": "address" }, 86 | { "internalType": "bool", "name": "publicSwap", "type": "bool" } 87 | ], 88 | "name": "setPublicSwap", 89 | "outputs": [], 90 | "payable": false, 91 | "stateMutability": "nonpayable", 92 | "type": "function" 93 | }, 94 | { 95 | "constant": false, 96 | "inputs": [ 97 | { "internalType": "contract BPool", "name": "pool", "type": "address" }, 98 | { "internalType": "uint256", "name": "newFee", "type": "uint256" } 99 | ], 100 | "name": "setSwapFee", 101 | "outputs": [], 102 | "payable": false, 103 | "stateMutability": "nonpayable", 104 | "type": "function" 105 | }, 106 | { 107 | "constant": false, 108 | "inputs": [ 109 | { "internalType": "contract BPool", "name": "pool", "type": "address" }, 110 | { "internalType": "address[]", "name": "tokens", "type": "address[]" }, 111 | { "internalType": "uint256[]", "name": "balances", "type": "uint256[]" }, 112 | { "internalType": "uint256[]", "name": "denorms", "type": "uint256[]" } 113 | ], 114 | "name": "setTokens", 115 | "outputs": [], 116 | "payable": false, 117 | "stateMutability": "nonpayable", 118 | "type": "function" 119 | } 120 | ] 121 | -------------------------------------------------------------------------------- /src/balancer/abi/BFactory.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [], 4 | "payable": false, 5 | "stateMutability": "nonpayable", 6 | "type": "constructor" 7 | }, 8 | { 9 | "anonymous": false, 10 | "inputs": [ 11 | { 12 | "indexed": true, 13 | "internalType": "address", 14 | "name": "caller", 15 | "type": "address" 16 | }, 17 | { 18 | "indexed": true, 19 | "internalType": "address", 20 | "name": "blabs", 21 | "type": "address" 22 | } 23 | ], 24 | "name": "LOG_BLABS", 25 | "type": "event" 26 | }, 27 | { 28 | "anonymous": false, 29 | "inputs": [ 30 | { 31 | "indexed": true, 32 | "internalType": "address", 33 | "name": "caller", 34 | "type": "address" 35 | }, 36 | { 37 | "indexed": true, 38 | "internalType": "address", 39 | "name": "pool", 40 | "type": "address" 41 | } 42 | ], 43 | "name": "LOG_NEW_POOL", 44 | "type": "event" 45 | }, 46 | { 47 | "constant": false, 48 | "inputs": [ 49 | { "internalType": "contract BPool", "name": "pool", "type": "address" } 50 | ], 51 | "name": "collect", 52 | "outputs": [], 53 | "payable": false, 54 | "stateMutability": "nonpayable", 55 | "type": "function" 56 | }, 57 | { 58 | "constant": true, 59 | "inputs": [], 60 | "name": "getBLabs", 61 | "outputs": [{ "internalType": "address", "name": "", "type": "address" }], 62 | "payable": false, 63 | "stateMutability": "view", 64 | "type": "function" 65 | }, 66 | { 67 | "constant": true, 68 | "inputs": [], 69 | "name": "getColor", 70 | "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], 71 | "payable": false, 72 | "stateMutability": "view", 73 | "type": "function" 74 | }, 75 | { 76 | "constant": true, 77 | "inputs": [{ "internalType": "address", "name": "b", "type": "address" }], 78 | "name": "isBPool", 79 | "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], 80 | "payable": false, 81 | "stateMutability": "view", 82 | "type": "function" 83 | }, 84 | { 85 | "constant": false, 86 | "inputs": [], 87 | "name": "newBPool", 88 | "outputs": [ 89 | { "internalType": "contract BPool", "name": "", "type": "address" } 90 | ], 91 | "payable": false, 92 | "stateMutability": "nonpayable", 93 | "type": "function" 94 | }, 95 | { 96 | "constant": false, 97 | "inputs": [{ "internalType": "address", "name": "b", "type": "address" }], 98 | "name": "setBLabs", 99 | "outputs": [], 100 | "payable": false, 101 | "stateMutability": "nonpayable", 102 | "type": "function" 103 | } 104 | ] 105 | -------------------------------------------------------------------------------- /src/balancer/contracts.ts: -------------------------------------------------------------------------------- 1 | import BActions from "./abi/BActions.json"; 2 | import ExchangeProxy from "./abi/ExchangeProxy.json"; 3 | import BFactory from "./abi/BFactory.json"; 4 | import BPool from "./abi/BPool.json"; 5 | 6 | const contracts = { 7 | PoolFactory: { 8 | abi: BFactory, 9 | address: "0x9424B1412450D0f8Fc2255FAf6046b98213B76Bd", 10 | }, 11 | BActions: { 12 | abi: BActions, 13 | address: "0xde4A25A0b9589689945d842c5ba0CF4f0D4eB3ac", 14 | }, 15 | ExchangeProxy: { 16 | abi: ExchangeProxy, 17 | address: "0x6317C5e82A06E1d8bf200d21F4510Ac2c038AC81", 18 | }, 19 | BPool: { 20 | abi: BPool, 21 | }, 22 | }; 23 | 24 | export default contracts; 25 | -------------------------------------------------------------------------------- /src/balancer/contracts/BFactory.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.8.0; 2 | 3 | import "./BPool.sol"; 4 | 5 | interface BFactory { 6 | 7 | function isBPool(address b) external view returns (bool); 8 | function newBPool() external returns (BPool); 9 | 10 | } -------------------------------------------------------------------------------- /src/balancer/contracts/ExchangeProxy.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.8.0; 2 | 3 | 4 | interface ExchangeProxy { 5 | 6 | function batchSwapExactIn( 7 | Swap[] memory swaps, 8 | address tokenIn, 9 | address tokenOut, 10 | uint totalAmountIn, 11 | uint minTotalAmountOut 12 | ) public returns (uint totalAmountOut); 13 | 14 | function batchSwapExactOut( 15 | Swap[] memory swaps, 16 | address tokenIn, 17 | address tokenOut, 18 | uint maxTotalAmountIn 19 | ) public returns (uint totalAmountIn); 20 | 21 | function batchEthInSwapExactIn( 22 | Swap[] memory swaps, 23 | address tokenOut, 24 | uint minTotalAmountOut 25 | ) public payable returns (uint totalAmountOut); 26 | 27 | function batchEthOutSwapExactIn( 28 | Swap[] memory swaps, 29 | address tokenIn, 30 | uint totalAmountIn, 31 | uint minTotalAmountOut 32 | ) public returns (uint totalAmountOut); 33 | 34 | function batchEthInSwapExactOut( 35 | Swap[] memory swaps, 36 | address tokenOut 37 | ) public payable returns (uint totalAmountIn); 38 | 39 | function batchEthOutSwapExactOut( 40 | Swap[] memory swaps, 41 | address tokenIn, 42 | uint maxTotalAmountIn 43 | ) public returns (uint totalAmountIn); 44 | 45 | } -------------------------------------------------------------------------------- /src/balancer/index.ts: -------------------------------------------------------------------------------- 1 | import { default as contracts } from "./contracts"; 2 | 3 | export = { 4 | ...contracts, 5 | }; 6 | -------------------------------------------------------------------------------- /src/compound/README.md: -------------------------------------------------------------------------------- 1 | # Compound 2 | -------------------------------------------------------------------------------- /src/compound/contracts.ts: -------------------------------------------------------------------------------- 1 | import ComptrollerAbi from "./abi/Comptroller.json"; 2 | import CompoundPriceOracleAbi from "./abi/CompoundPriceOracle.json"; 3 | import CTokenAbi from "./abi/CToken.json"; 4 | import CEtherAbi from "./abi/CEther.json"; 5 | 6 | const contracts = { 7 | cToken: { abi: CTokenAbi }, 8 | comptroller: { 9 | address: "0x3d9819210a31b4961b30ef54be2aed79b9c9cd3b", 10 | abi: ComptrollerAbi, 11 | }, 12 | priceOracle: { 13 | address: "0xDDc46a3B076aec7ab3Fc37420A8eDd2959764Ec4", 14 | abi: CompoundPriceOracleAbi, 15 | }, 16 | cEther: { 17 | decimals: 8, 18 | address: "0x4Ddc2D193948926D02f9B1fE9e1daa0718270ED5", 19 | abi: CEtherAbi, 20 | }, 21 | cDAI: { 22 | decimals: 8, 23 | address: "0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643", 24 | abi: CTokenAbi, 25 | }, 26 | cSAI: { 27 | decimals: 8, 28 | address: "0xf5dce57282a584d2746faf1593d3121fcac444dc", 29 | abi: CTokenAbi, 30 | }, 31 | cBAT: { 32 | decimals: 8, 33 | address: "0x6c8c6b02e7b2be14d4fa6022dfd6d75921d90e4e", 34 | abi: CTokenAbi, 35 | }, 36 | cZRX: { 37 | decimals: 8, 38 | address: "0xb3319f5d18bc0d84dd1b4825dcde5d5f7266d407", 39 | abi: CTokenAbi, 40 | }, 41 | cUSDC: { 42 | decimals: 8, 43 | address: "0x39aa39c021dfbae8fac545936693ac917d5e7563", 44 | abi: CTokenAbi, 45 | }, 46 | cREP: { 47 | decimals: 8, 48 | address: "0x158079ee67fce2f58472a96584a73c7ab9ac95c1", 49 | abi: CTokenAbi, 50 | }, 51 | cWBTC: { 52 | decimals: 8, 53 | address: "0xc11b1268c1a384e55c48c2391d8d480264a3a7f4", 54 | abi: CTokenAbi, 55 | }, 56 | }; 57 | 58 | export default contracts; 59 | -------------------------------------------------------------------------------- /src/compound/contracts/ICEther.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.8.0; 2 | 3 | contract ICEther { 4 | function mint() external payable; 5 | function borrow(uint borrowAmount) external returns (uint); 6 | function redeem(uint redeemTokens) external returns (uint); 7 | function redeemUnderlying(uint redeemAmount) external returns (uint); 8 | function repayBorrow() external payable; 9 | function repayBorrowBehalf(address borrower) external payable; 10 | function borrowBalanceCurrent(address account) external returns (uint); 11 | function borrowBalanceStored(address account) external view returns (uint256); 12 | function balanceOfUnderlying(address account) external returns (uint); 13 | function balanceOf(address owner) external view returns (uint256); 14 | function getAccountSnapshot(address account) external view returns (uint, uint, uint, uint); 15 | } -------------------------------------------------------------------------------- /src/compound/contracts/ICToken.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.8.0; 2 | 3 | interface ICToken { 4 | function mint(uint mintAmount) external returns (uint); 5 | function redeem(uint redeemTokens) external returns (uint); 6 | function redeemUnderlying(uint redeemAmount) external returns (uint); 7 | function borrow(uint borrowAmount) external returns (uint); 8 | function repayBorrow(uint repayAmount) external returns (uint); 9 | function repayBorrowBehalf(address borrower, uint repayAmount) external returns (uint); 10 | function exchangeRateCurrent() external returns (uint); 11 | function borrowBalanceCurrent(address account) external returns (uint); 12 | function borrowBalanceStored(address account) external view returns (uint256); 13 | function balanceOfUnderlying(address account) external returns (uint); 14 | function getAccountSnapshot(address account) external view returns (uint, uint, uint, uint); 15 | 16 | function underlying() external view returns (address); 17 | function totalSupply() external view returns (uint256); 18 | function balanceOf(address owner) external view returns (uint256 balance); 19 | function allowance(address, address) external view returns (uint); 20 | function approve(address, uint) external; 21 | function transfer(address, uint) external returns (bool); 22 | function transferFrom(address, address, uint) external returns (bool); 23 | } 24 | -------------------------------------------------------------------------------- /src/compound/contracts/ICompoundPriceOracle.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.8.0; 2 | 3 | contract ICompoundPriceOracle { 4 | function getUnderlyingPrice(address cToken) external view returns (uint256); 5 | } -------------------------------------------------------------------------------- /src/compound/contracts/IComptroller.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.8.0; 2 | 3 | interface IComptroller { 4 | /** 5 | * @notice Marker function used for light validation when updating the comptroller of a market 6 | * @dev Implementations should simply return true. 7 | * @return true 8 | */ 9 | function isComptroller() external view returns (bool); 10 | 11 | /*** Assets You Are In ***/ 12 | 13 | function enterMarkets(address[] calldata cTokens) external returns (uint[] memory); 14 | function exitMarket(address cToken) external returns (uint); 15 | 16 | /*** Policy Hooks ***/ 17 | 18 | function getAccountLiquidity(address account) external view returns (uint, uint, uint); 19 | function getAssetsIn(address account) external view returns (address[] memory); 20 | 21 | function mintAllowed(address cToken, address minter, uint mintAmount) external returns (uint); 22 | function mintVerify(address cToken, address minter, uint mintAmount, uint mintTokens) external; 23 | 24 | function redeemAllowed(address cToken, address redeemer, uint redeemTokens) external returns (uint); 25 | function redeemVerify(address cToken, address redeemer, uint redeemAmount, uint redeemTokens) external; 26 | 27 | function borrowAllowed(address cToken, address borrower, uint borrowAmount) external returns (uint); 28 | function borrowVerify(address cToken, address borrower, uint borrowAmount) external; 29 | 30 | function repayBorrowAllowed( 31 | address cToken, 32 | address payer, 33 | address borrower, 34 | uint repayAmount) external returns (uint); 35 | function repayBorrowVerify( 36 | address cToken, 37 | address payer, 38 | address borrower, 39 | uint repayAmount, 40 | uint borrowerIndex) external; 41 | 42 | function liquidateBorrowAllowed( 43 | address cTokenBorrowed, 44 | address cTokenCollateral, 45 | address liquidator, 46 | address borrower, 47 | uint repayAmount) external returns (uint); 48 | function liquidateBorrowVerify( 49 | address cTokenBorrowed, 50 | address cTokenCollateral, 51 | address liquidator, 52 | address borrower, 53 | uint repayAmount, 54 | uint seizeTokens) external; 55 | 56 | function seizeAllowed( 57 | address cTokenCollateral, 58 | address cTokenBorrowed, 59 | address liquidator, 60 | address borrower, 61 | uint seizeTokens) external returns (uint); 62 | function seizeVerify( 63 | address cTokenCollateral, 64 | address cTokenBorrowed, 65 | address liquidator, 66 | address borrower, 67 | uint seizeTokens) external; 68 | 69 | function transferAllowed(address cToken, address src, address dst, uint transferTokens) external returns (uint); 70 | function transferVerify(address cToken, address src, address dst, uint transferTokens) external; 71 | 72 | /*** Liquidity/Liquidation Calculations ***/ 73 | 74 | function liquidateCalculateSeizeTokens( 75 | address cTokenBorrowed, 76 | address cTokenCollateral, 77 | uint repayAmount) external view returns (uint, uint); 78 | } -------------------------------------------------------------------------------- /src/compound/index.ts: -------------------------------------------------------------------------------- 1 | import { default as contracts } from "./contracts"; 2 | 3 | export = { 4 | ...contracts, 5 | }; 6 | -------------------------------------------------------------------------------- /src/curvefi/abi/PoolToken.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "Transfer", 4 | "inputs": [ 5 | { "type": "address", "name": "_from", "indexed": true }, 6 | { "type": "address", "name": "_to", "indexed": true }, 7 | { "type": "uint256", "name": "_value", "indexed": false } 8 | ], 9 | "anonymous": false, 10 | "type": "event" 11 | }, 12 | { 13 | "name": "Approval", 14 | "inputs": [ 15 | { "type": "address", "name": "_owner", "indexed": true }, 16 | { "type": "address", "name": "_spender", "indexed": true }, 17 | { "type": "uint256", "name": "_value", "indexed": false } 18 | ], 19 | "anonymous": false, 20 | "type": "event" 21 | }, 22 | { 23 | "outputs": [], 24 | "inputs": [ 25 | { "type": "string", "name": "_name" }, 26 | { "type": "string", "name": "_symbol" }, 27 | { "type": "uint256", "name": "_decimals" }, 28 | { "type": "uint256", "name": "_supply" } 29 | ], 30 | "constant": false, 31 | "payable": false, 32 | "type": "constructor" 33 | }, 34 | { 35 | "name": "set_minter", 36 | "outputs": [], 37 | "inputs": [{ "type": "address", "name": "_minter" }], 38 | "constant": false, 39 | "payable": false, 40 | "type": "function", 41 | "gas": 36247 42 | }, 43 | { 44 | "name": "totalSupply", 45 | "outputs": [{ "type": "uint256", "name": "out" }], 46 | "inputs": [], 47 | "constant": true, 48 | "payable": false, 49 | "type": "function", 50 | "gas": 1181 51 | }, 52 | { 53 | "name": "allowance", 54 | "outputs": [{ "type": "uint256", "name": "out" }], 55 | "inputs": [ 56 | { "type": "address", "name": "_owner" }, 57 | { "type": "address", "name": "_spender" } 58 | ], 59 | "constant": true, 60 | "payable": false, 61 | "type": "function", 62 | "gas": 1519 63 | }, 64 | { 65 | "name": "transfer", 66 | "outputs": [{ "type": "bool", "name": "out" }], 67 | "inputs": [ 68 | { "type": "address", "name": "_to" }, 69 | { "type": "uint256", "name": "_value" } 70 | ], 71 | "constant": false, 72 | "payable": false, 73 | "type": "function", 74 | "gas": 74802 75 | }, 76 | { 77 | "name": "transferFrom", 78 | "outputs": [{ "type": "bool", "name": "out" }], 79 | "inputs": [ 80 | { "type": "address", "name": "_from" }, 81 | { "type": "address", "name": "_to" }, 82 | { "type": "uint256", "name": "_value" } 83 | ], 84 | "constant": false, 85 | "payable": false, 86 | "type": "function", 87 | "gas": 111953 88 | }, 89 | { 90 | "name": "approve", 91 | "outputs": [{ "type": "bool", "name": "out" }], 92 | "inputs": [ 93 | { "type": "address", "name": "_spender" }, 94 | { "type": "uint256", "name": "_value" } 95 | ], 96 | "constant": false, 97 | "payable": false, 98 | "type": "function", 99 | "gas": 39012 100 | }, 101 | { 102 | "name": "mint", 103 | "outputs": [], 104 | "inputs": [ 105 | { "type": "address", "name": "_to" }, 106 | { "type": "uint256", "name": "_value" } 107 | ], 108 | "constant": false, 109 | "payable": false, 110 | "type": "function", 111 | "gas": 75733 112 | }, 113 | { 114 | "name": "burn", 115 | "outputs": [], 116 | "inputs": [{ "type": "uint256", "name": "_value" }], 117 | "constant": false, 118 | "payable": false, 119 | "type": "function", 120 | "gas": 75605 121 | }, 122 | { 123 | "name": "burnFrom", 124 | "outputs": [], 125 | "inputs": [ 126 | { "type": "address", "name": "_to" }, 127 | { "type": "uint256", "name": "_value" } 128 | ], 129 | "constant": false, 130 | "payable": false, 131 | "type": "function", 132 | "gas": 112752 133 | }, 134 | { 135 | "name": "name", 136 | "outputs": [{ "type": "string", "name": "out" }], 137 | "inputs": [], 138 | "constant": true, 139 | "payable": false, 140 | "type": "function", 141 | "gas": 7853 142 | }, 143 | { 144 | "name": "symbol", 145 | "outputs": [{ "type": "string", "name": "out" }], 146 | "inputs": [], 147 | "constant": true, 148 | "payable": false, 149 | "type": "function", 150 | "gas": 6906 151 | }, 152 | { 153 | "name": "decimals", 154 | "outputs": [{ "type": "uint256", "name": "out" }], 155 | "inputs": [], 156 | "constant": true, 157 | "payable": false, 158 | "type": "function", 159 | "gas": 1511 160 | }, 161 | { 162 | "name": "balanceOf", 163 | "outputs": [{ "type": "uint256", "name": "out" }], 164 | "inputs": [{ "type": "address", "name": "arg0" }], 165 | "constant": true, 166 | "payable": false, 167 | "type": "function", 168 | "gas": 1695 169 | } 170 | ] 171 | -------------------------------------------------------------------------------- /src/curvefi/abi/Zap.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "outputs": [], 4 | "inputs": [ 5 | { "type": "address[2]", "name": "_coins" }, 6 | { "type": "address[2]", "name": "_underlying_coins" }, 7 | { "type": "address", "name": "_curve" }, 8 | { "type": "address", "name": "_token" } 9 | ], 10 | "constant": false, 11 | "payable": false, 12 | "type": "constructor" 13 | }, 14 | { 15 | "name": "add_liquidity", 16 | "outputs": [], 17 | "inputs": [ 18 | { "type": "uint256[2]", "name": "uamounts" }, 19 | { "type": "uint256", "name": "min_mint_amount" } 20 | ], 21 | "constant": false, 22 | "payable": false, 23 | "type": "function", 24 | "gas": 117283 25 | }, 26 | { 27 | "name": "remove_liquidity", 28 | "outputs": [], 29 | "inputs": [ 30 | { "type": "uint256", "name": "_amount" }, 31 | { "type": "uint256[2]", "name": "min_uamounts" } 32 | ], 33 | "constant": false, 34 | "payable": false, 35 | "type": "function", 36 | "gas": 83606 37 | }, 38 | { 39 | "name": "remove_liquidity_imbalance", 40 | "outputs": [], 41 | "inputs": [ 42 | { "type": "uint256[2]", "name": "uamounts" }, 43 | { "type": "uint256", "name": "max_burn_amount" } 44 | ], 45 | "constant": false, 46 | "payable": false, 47 | "type": "function", 48 | "gas": 96829 49 | }, 50 | { 51 | "name": "calc_withdraw_one_coin", 52 | "outputs": [{ "type": "uint256", "name": "" }], 53 | "inputs": [ 54 | { "type": "uint256", "name": "_token_amount" }, 55 | { "type": "int128", "name": "i" } 56 | ], 57 | "constant": true, 58 | "payable": false, 59 | "type": "function", 60 | "gas": 2945630 61 | }, 62 | { 63 | "name": "remove_liquidity_one_coin", 64 | "outputs": [], 65 | "inputs": [ 66 | { "type": "uint256", "name": "_token_amount" }, 67 | { "type": "int128", "name": "i" }, 68 | { "type": "uint256", "name": "min_uamount" } 69 | ], 70 | "constant": false, 71 | "payable": false, 72 | "type": "function" 73 | }, 74 | { 75 | "name": "remove_liquidity_one_coin", 76 | "outputs": [], 77 | "inputs": [ 78 | { "type": "uint256", "name": "_token_amount" }, 79 | { "type": "int128", "name": "i" }, 80 | { "type": "uint256", "name": "min_uamount" }, 81 | { "type": "bool", "name": "donate_dust" } 82 | ], 83 | "constant": false, 84 | "payable": false, 85 | "type": "function" 86 | }, 87 | { 88 | "name": "withdraw_donated_dust", 89 | "outputs": [], 90 | "inputs": [], 91 | "constant": false, 92 | "payable": false, 93 | "type": "function", 94 | "gas": 63973 95 | }, 96 | { 97 | "name": "coins", 98 | "outputs": [{ "type": "address", "name": "" }], 99 | "inputs": [{ "type": "int128", "name": "arg0" }], 100 | "constant": true, 101 | "payable": false, 102 | "type": "function", 103 | "gas": 1680 104 | }, 105 | { 106 | "name": "underlying_coins", 107 | "outputs": [{ "type": "address", "name": "" }], 108 | "inputs": [{ "type": "int128", "name": "arg0" }], 109 | "constant": true, 110 | "payable": false, 111 | "type": "function", 112 | "gas": 1710 113 | }, 114 | { 115 | "name": "curve", 116 | "outputs": [{ "type": "address", "name": "" }], 117 | "inputs": [], 118 | "constant": true, 119 | "payable": false, 120 | "type": "function", 121 | "gas": 1541 122 | }, 123 | { 124 | "name": "token", 125 | "outputs": [{ "type": "address", "name": "" }], 126 | "inputs": [], 127 | "constant": true, 128 | "payable": false, 129 | "type": "function", 130 | "gas": 1571 131 | } 132 | ] 133 | -------------------------------------------------------------------------------- /src/curvefi/contracts.ts: -------------------------------------------------------------------------------- 1 | import curveAbi from "./abi/Curve.json"; 2 | import poolTokenAbi from "./abi/PoolToken.json"; 3 | import zapAbi from "./abi/Zap.json"; 4 | 5 | // Reference: https://github.com/curvefi/curve-contract/ 6 | 7 | const contracts = { 8 | poolTokenAbi, 9 | curveAbi, 10 | zapAbi, 11 | cDai_cUsdc: { 12 | nCoins: 2, 13 | indexes: { 14 | dai: 0, 15 | usdc: 1, 16 | }, 17 | zap: { 18 | address: "0xeB21209ae4C2c9FF2a86ACA31E123764A3B6Bc06", 19 | }, 20 | curve: { 21 | address: "0xa2b47e3d5c44877cca798226b7b8118f9bfb7a56", 22 | }, 23 | poolToken: { 24 | address: "0x845838df265dcd2c412a1dc9e959c7d08537f8a2", 25 | }, 26 | }, 27 | cDai_cUsdc_Usdt: { 28 | nCoins: 3, 29 | indexes: { 30 | dai: 0, 31 | usdc: 1, 32 | usdt: 2, 33 | }, 34 | zap: { 35 | address: "0xac795D2c97e60DF6a99ff1c814727302fD747a80", 36 | }, 37 | curve: { 38 | address: "0x52ea46506b9cc5ef470c5bf89f17dc28bb35d85c", 39 | }, 40 | poolToken: { 41 | address: "0x9fc689ccada600b6df723d9e47d84d76664a1f23", 42 | }, 43 | }, 44 | yDai_yUsdc_yUsdt_ytUsd: { 45 | nCoins: 4, 46 | indexes: { 47 | dai: 0, 48 | usdc: 1, 49 | usdt: 2, 50 | tusd: 3, 51 | }, 52 | zap: { 53 | address: "0xbBC81d23Ea2c3ec7e56D39296F0cbB648873a5d3", 54 | }, 55 | curve: { 56 | address: "0x45f783cce6b7ff23b2ab2d70e416cdb7d6055f51", 57 | }, 58 | poolToken: { 59 | address: "0xdf5e0e81dff6faf3a7e52ba697820c5e32d806a8", 60 | }, 61 | }, 62 | }; 63 | 64 | export default contracts; 65 | -------------------------------------------------------------------------------- /src/curvefi/contracts/ICurveFiCurve.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.8.0; 2 | 3 | contract ICurveFiCurve { 4 | function get_virtual_price() external returns (uint256 out); 5 | 6 | function add_liquidity(uint256[2] calldata amounts, uint256 deadline) external; 7 | 8 | function get_dy(int128 i, int128 j, uint256 dx) 9 | external 10 | returns (uint256 out); 11 | 12 | function get_dy_underlying(int128 i, int128 j, uint256 dx) 13 | external 14 | returns (uint256 out); 15 | 16 | function exchange( 17 | int128 i, 18 | int128 j, 19 | uint256 dx, 20 | uint256 min_dy 21 | ) external; 22 | 23 | function exchange( 24 | int128 i, 25 | int128 j, 26 | uint256 dx, 27 | uint256 min_dy, 28 | uint256 deadline 29 | ) external; 30 | 31 | function exchange_underlying( 32 | int128 i, 33 | int128 j, 34 | uint256 dx, 35 | uint256 min_dy 36 | ) external; 37 | 38 | function exchange_underlying( 39 | int128 i, 40 | int128 j, 41 | uint256 dx, 42 | uint256 min_dy, 43 | uint256 deadline 44 | ) external; 45 | 46 | function remove_liquidity( 47 | uint256 _amount, 48 | uint256 deadline, 49 | uint256[2] calldata min_amounts 50 | ) external; 51 | 52 | function remove_liquidity_imbalance(uint256[2] calldata amounts, uint256 deadline) 53 | external; 54 | 55 | function commit_new_parameters( 56 | int128 amplification, 57 | int128 new_fee, 58 | int128 new_admin_fee 59 | ) external; 60 | 61 | function apply_new_parameters() external; 62 | 63 | function revert_new_parameters() external; 64 | 65 | function commit_transfer_ownership(address _owner) external; 66 | 67 | function apply_transfer_ownership() external; 68 | 69 | function revert_transfer_ownership() external; 70 | 71 | function withdraw_admin_fees() external; 72 | 73 | function coins(int128 arg0) external returns (address out); 74 | 75 | function underlying_coins(int128 arg0) external returns (address out); 76 | 77 | function balances(int128 arg0) external returns (uint256 out); 78 | 79 | function A() external returns (int128 out); 80 | 81 | function fee() external returns (int128 out); 82 | 83 | function admin_fee() external returns (int128 out); 84 | 85 | function owner() external returns (address out); 86 | 87 | function admin_actions_deadline() external returns (uint256 out); 88 | 89 | function transfer_ownership_deadline() external returns (uint256 out); 90 | 91 | function future_A() external returns (int128 out); 92 | 93 | function future_fee() external returns (int128 out); 94 | 95 | function future_admin_fee() external returns (int128 out); 96 | 97 | function future_owner() external returns (address out); 98 | } 99 | -------------------------------------------------------------------------------- /src/curvefi/contracts/ICurveFiPoolToken.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.8.0; 2 | 3 | contract ICurveFiPoolToken { 4 | function set_minter(address _minter) external; 5 | 6 | function totalSupply() external returns (uint256 out); 7 | 8 | function allowance(address _owner, address _spender) 9 | external 10 | returns (uint256 out); 11 | 12 | function transfer(address _to, uint256 _value) external returns (bool out); 13 | 14 | function transferFrom(address _from, address _to, uint256 _value) 15 | external 16 | returns (bool out); 17 | 18 | function approve(address _spender, uint256 _value) 19 | external 20 | returns (bool out); 21 | 22 | function mint(address _to, uint256 _value) external; 23 | 24 | function burn(uint256 _value) external; 25 | 26 | function burnFrom(address _to, uint256 _value) external; 27 | 28 | function name() external returns (string memory out); 29 | 30 | function symbol() external returns (string memory out); 31 | 32 | function decimals() external returns (uint256 out); 33 | 34 | function balanceOf(address arg0) external returns (uint256 out); 35 | } 36 | -------------------------------------------------------------------------------- /src/curvefi/contracts/ICurveFiZap.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.8.0; 2 | 3 | 4 | contract ICurveFiZap { 5 | function add_liquidity( 6 | uint256[2] calldata uamounts, 7 | uint256 min_mint_amount 8 | ) external; 9 | 10 | function remove_liquidity(uint256 _amount, uint256[2] calldata min_uamounts) 11 | external; 12 | 13 | function remove_liquidity_imbalance( 14 | uint256[2] calldata uamounts, 15 | uint256 max_burn_amount 16 | ) external; 17 | 18 | function calc_withdraw_one_coin(uint256 _token_amount, int128 i) 19 | external 20 | returns (uint256); 21 | 22 | function remove_liquidity_one_coin( 23 | uint256 _token_amount, 24 | int128 i, 25 | uint256 min_uamount 26 | ) external; 27 | 28 | function remove_liquidity_one_coin( 29 | uint256 _token_amount, 30 | int128 i, 31 | uint256 min_uamount, 32 | bool donate_dust 33 | ) external; 34 | 35 | function withdraw_donated_dust() external; 36 | 37 | function coins(int128 arg0) external returns (address); 38 | 39 | function underlying_coins(int128 arg0) external returns (address); 40 | 41 | function curve() external returns (address); 42 | 43 | function token() external returns (address); 44 | } 45 | -------------------------------------------------------------------------------- /src/curvefi/index.ts: -------------------------------------------------------------------------------- 1 | import { default as contracts } from "./contracts"; 2 | 3 | export = { 4 | ...contracts, 5 | }; 6 | -------------------------------------------------------------------------------- /src/dappsys/abi/DSProxyFactory.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [], 4 | "payable": false, 5 | "stateMutability": "nonpayable", 6 | "type": "constructor" 7 | }, 8 | { 9 | "anonymous": false, 10 | "inputs": [ 11 | { 12 | "indexed": true, 13 | "internalType": "address", 14 | "name": "sender", 15 | "type": "address" 16 | }, 17 | { 18 | "indexed": true, 19 | "internalType": "address", 20 | "name": "owner", 21 | "type": "address" 22 | }, 23 | { 24 | "indexed": false, 25 | "internalType": "address", 26 | "name": "proxy", 27 | "type": "address" 28 | }, 29 | { 30 | "indexed": false, 31 | "internalType": "address", 32 | "name": "cache", 33 | "type": "address" 34 | } 35 | ], 36 | "name": "Created", 37 | "type": "event" 38 | }, 39 | { 40 | "constant": false, 41 | "inputs": [], 42 | "name": "build", 43 | "outputs": [ 44 | { 45 | "internalType": "address payable", 46 | "name": "proxy", 47 | "type": "address" 48 | } 49 | ], 50 | "payable": false, 51 | "stateMutability": "nonpayable", 52 | "type": "function" 53 | }, 54 | { 55 | "constant": false, 56 | "inputs": [ 57 | { 58 | "internalType": "address", 59 | "name": "owner", 60 | "type": "address" 61 | } 62 | ], 63 | "name": "build", 64 | "outputs": [ 65 | { 66 | "internalType": "address payable", 67 | "name": "proxy", 68 | "type": "address" 69 | } 70 | ], 71 | "payable": false, 72 | "stateMutability": "nonpayable", 73 | "type": "function" 74 | }, 75 | { 76 | "constant": true, 77 | "inputs": [], 78 | "name": "cache", 79 | "outputs": [ 80 | { 81 | "internalType": "contract DSProxyCache", 82 | "name": "", 83 | "type": "address" 84 | } 85 | ], 86 | "payable": false, 87 | "stateMutability": "view", 88 | "type": "function" 89 | }, 90 | { 91 | "constant": true, 92 | "inputs": [ 93 | { 94 | "internalType": "address", 95 | "name": "", 96 | "type": "address" 97 | } 98 | ], 99 | "name": "isProxy", 100 | "outputs": [ 101 | { 102 | "internalType": "bool", 103 | "name": "", 104 | "type": "bool" 105 | } 106 | ], 107 | "payable": false, 108 | "stateMutability": "view", 109 | "type": "function" 110 | } 111 | ] -------------------------------------------------------------------------------- /src/dappsys/contracts.ts: -------------------------------------------------------------------------------- 1 | import dsProxyAbi from "./abi/DSProxy.json"; 2 | import dsProxyFactoryAbi from "./abi/DSProxyFactory.json"; 3 | 4 | const contracts = { 5 | dsProxy: { 6 | abi: dsProxyAbi, 7 | }, 8 | dsProxyFactory: { 9 | abi: dsProxyFactoryAbi, 10 | }, 11 | }; 12 | 13 | export default contracts; 14 | -------------------------------------------------------------------------------- /src/dappsys/index.ts: -------------------------------------------------------------------------------- 1 | import { default as contracts } from "./contracts"; 2 | 3 | export = { 4 | ...contracts, 5 | }; 6 | -------------------------------------------------------------------------------- /src/dydx/abi/AdminImpl.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "anonymous": false, 4 | "inputs": [ 5 | { "indexed": false, "name": "token", "type": "address" }, 6 | { "indexed": false, "name": "amount", "type": "uint256" } 7 | ], 8 | "name": "LogWithdrawExcessTokens", 9 | "type": "event" 10 | }, 11 | { 12 | "anonymous": false, 13 | "inputs": [ 14 | { "indexed": false, "name": "marketId", "type": "uint256" }, 15 | { "indexed": false, "name": "token", "type": "address" } 16 | ], 17 | "name": "LogAddMarket", 18 | "type": "event" 19 | }, 20 | { 21 | "anonymous": false, 22 | "inputs": [ 23 | { "indexed": false, "name": "marketId", "type": "uint256" }, 24 | { "indexed": false, "name": "isClosing", "type": "bool" } 25 | ], 26 | "name": "LogSetIsClosing", 27 | "type": "event" 28 | }, 29 | { 30 | "anonymous": false, 31 | "inputs": [ 32 | { "indexed": false, "name": "marketId", "type": "uint256" }, 33 | { "indexed": false, "name": "priceOracle", "type": "address" } 34 | ], 35 | "name": "LogSetPriceOracle", 36 | "type": "event" 37 | }, 38 | { 39 | "anonymous": false, 40 | "inputs": [ 41 | { "indexed": false, "name": "marketId", "type": "uint256" }, 42 | { "indexed": false, "name": "interestSetter", "type": "address" } 43 | ], 44 | "name": "LogSetInterestSetter", 45 | "type": "event" 46 | }, 47 | { 48 | "anonymous": false, 49 | "inputs": [ 50 | { "indexed": false, "name": "marketId", "type": "uint256" }, 51 | { 52 | "components": [{ "name": "value", "type": "uint256" }], 53 | "indexed": false, 54 | "name": "marginPremium", 55 | "type": "tuple" 56 | } 57 | ], 58 | "name": "LogSetMarginPremium", 59 | "type": "event" 60 | }, 61 | { 62 | "anonymous": false, 63 | "inputs": [ 64 | { "indexed": false, "name": "marketId", "type": "uint256" }, 65 | { 66 | "components": [{ "name": "value", "type": "uint256" }], 67 | "indexed": false, 68 | "name": "spreadPremium", 69 | "type": "tuple" 70 | } 71 | ], 72 | "name": "LogSetSpreadPremium", 73 | "type": "event" 74 | }, 75 | { 76 | "anonymous": false, 77 | "inputs": [ 78 | { 79 | "components": [{ "name": "value", "type": "uint256" }], 80 | "indexed": false, 81 | "name": "marginRatio", 82 | "type": "tuple" 83 | } 84 | ], 85 | "name": "LogSetMarginRatio", 86 | "type": "event" 87 | }, 88 | { 89 | "anonymous": false, 90 | "inputs": [ 91 | { 92 | "components": [{ "name": "value", "type": "uint256" }], 93 | "indexed": false, 94 | "name": "liquidationSpread", 95 | "type": "tuple" 96 | } 97 | ], 98 | "name": "LogSetLiquidationSpread", 99 | "type": "event" 100 | }, 101 | { 102 | "anonymous": false, 103 | "inputs": [ 104 | { 105 | "components": [{ "name": "value", "type": "uint256" }], 106 | "indexed": false, 107 | "name": "earningsRate", 108 | "type": "tuple" 109 | } 110 | ], 111 | "name": "LogSetEarningsRate", 112 | "type": "event" 113 | }, 114 | { 115 | "anonymous": false, 116 | "inputs": [ 117 | { 118 | "components": [{ "name": "value", "type": "uint256" }], 119 | "indexed": false, 120 | "name": "minBorrowedValue", 121 | "type": "tuple" 122 | } 123 | ], 124 | "name": "LogSetMinBorrowedValue", 125 | "type": "event" 126 | }, 127 | { 128 | "anonymous": false, 129 | "inputs": [ 130 | { "indexed": false, "name": "operator", "type": "address" }, 131 | { "indexed": false, "name": "approved", "type": "bool" } 132 | ], 133 | "name": "LogSetGlobalOperator", 134 | "type": "event" 135 | } 136 | ] 137 | -------------------------------------------------------------------------------- /src/dydx/abi/LiquidatorProxyV1ForSoloMargin.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "constant": true, 4 | "inputs": [], 5 | "name": "SOLO_MARGIN", 6 | "outputs": [{ "name": "", "type": "address" }], 7 | "payable": false, 8 | "stateMutability": "view", 9 | "type": "function" 10 | }, 11 | { 12 | "constant": false, 13 | "inputs": [ 14 | { 15 | "components": [ 16 | { "name": "owner", "type": "address" }, 17 | { "name": "number", "type": "uint256" } 18 | ], 19 | "name": "fromAccount", 20 | "type": "tuple" 21 | }, 22 | { 23 | "components": [ 24 | { "name": "owner", "type": "address" }, 25 | { "name": "number", "type": "uint256" } 26 | ], 27 | "name": "liquidAccount", 28 | "type": "tuple" 29 | }, 30 | { 31 | "components": [{ "name": "value", "type": "uint256" }], 32 | "name": "minLiquidatorRatio", 33 | "type": "tuple" 34 | }, 35 | { "name": "minValueLiquidated", "type": "uint256" }, 36 | { "name": "owedPreferences", "type": "uint256[]" }, 37 | { "name": "heldPreferences", "type": "uint256[]" } 38 | ], 39 | "name": "liquidate", 40 | "outputs": [], 41 | "payable": false, 42 | "stateMutability": "nonpayable", 43 | "type": "function" 44 | }, 45 | { 46 | "inputs": [{ "name": "soloMargin", "type": "address" }], 47 | "payable": false, 48 | "stateMutability": "nonpayable", 49 | "type": "constructor" 50 | } 51 | ] 52 | -------------------------------------------------------------------------------- /src/dydx/abi/OperationImpl.json: -------------------------------------------------------------------------------- 1 | [] -------------------------------------------------------------------------------- /src/dydx/abi/PayableProxyForSoloMargin.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "constant": true, 4 | "inputs": [], 5 | "name": "SOLO_MARGIN", 6 | "outputs": [{ "name": "", "type": "address" }], 7 | "payable": false, 8 | "stateMutability": "view", 9 | "type": "function" 10 | }, 11 | { 12 | "constant": true, 13 | "inputs": [], 14 | "name": "WETH", 15 | "outputs": [{ "name": "", "type": "address" }], 16 | "payable": false, 17 | "stateMutability": "view", 18 | "type": "function" 19 | }, 20 | { 21 | "constant": false, 22 | "inputs": [ 23 | { 24 | "components": [ 25 | { "name": "owner", "type": "address" }, 26 | { "name": "number", "type": "uint256" } 27 | ], 28 | "name": "accounts", 29 | "type": "tuple[]" 30 | }, 31 | { 32 | "components": [ 33 | { "name": "actionType", "type": "uint8" }, 34 | { "name": "accountId", "type": "uint256" }, 35 | { 36 | "components": [ 37 | { "name": "sign", "type": "bool" }, 38 | { "name": "denomination", "type": "uint8" }, 39 | { "name": "ref", "type": "uint8" }, 40 | { "name": "value", "type": "uint256" } 41 | ], 42 | "name": "amount", 43 | "type": "tuple" 44 | }, 45 | { "name": "primaryMarketId", "type": "uint256" }, 46 | { "name": "secondaryMarketId", "type": "uint256" }, 47 | { "name": "otherAddress", "type": "address" }, 48 | { "name": "otherAccountId", "type": "uint256" }, 49 | { "name": "data", "type": "bytes" } 50 | ], 51 | "name": "actions", 52 | "type": "tuple[]" 53 | }, 54 | { "name": "sendEthTo", "type": "address" } 55 | ], 56 | "name": "operate", 57 | "outputs": [], 58 | "payable": true, 59 | "stateMutability": "payable", 60 | "type": "function" 61 | }, 62 | { 63 | "inputs": [ 64 | { "name": "soloMargin", "type": "address" }, 65 | { "name": "weth", "type": "address" } 66 | ], 67 | "payable": false, 68 | "stateMutability": "nonpayable", 69 | "type": "constructor" 70 | }, 71 | { "payable": true, "stateMutability": "payable", "type": "fallback" } 72 | ] 73 | -------------------------------------------------------------------------------- /src/dydx/abi/PolynomialInterestSetter.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "constant": true, 4 | "inputs": [], 5 | "name": "getMaxAPR", 6 | "outputs": [{ "name": "", "type": "uint256" }], 7 | "payable": false, 8 | "stateMutability": "view", 9 | "type": "function" 10 | }, 11 | { 12 | "constant": true, 13 | "inputs": [], 14 | "name": "getCoefficients", 15 | "outputs": [{ "name": "", "type": "uint256[]" }], 16 | "payable": false, 17 | "stateMutability": "view", 18 | "type": "function" 19 | }, 20 | { 21 | "constant": true, 22 | "inputs": [ 23 | { "name": "", "type": "address" }, 24 | { "name": "borrowWei", "type": "uint256" }, 25 | { "name": "supplyWei", "type": "uint256" } 26 | ], 27 | "name": "getInterestRate", 28 | "outputs": [ 29 | { 30 | "components": [{ "name": "value", "type": "uint256" }], 31 | "name": "", 32 | "type": "tuple" 33 | } 34 | ], 35 | "payable": false, 36 | "stateMutability": "view", 37 | "type": "function" 38 | }, 39 | { 40 | "inputs": [ 41 | { 42 | "components": [ 43 | { "name": "maxAPR", "type": "uint128" }, 44 | { "name": "coefficients", "type": "uint128" } 45 | ], 46 | "name": "params", 47 | "type": "tuple" 48 | } 49 | ], 50 | "payable": false, 51 | "stateMutability": "nonpayable", 52 | "type": "constructor" 53 | } 54 | ] 55 | -------------------------------------------------------------------------------- /src/dydx/abi/Refunder.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "constant": true, 4 | "inputs": [{ "name": "", "type": "address" }], 5 | "name": "g_givers", 6 | "outputs": [{ "name": "", "type": "bool" }], 7 | "payable": false, 8 | "stateMutability": "view", 9 | "type": "function" 10 | }, 11 | { 12 | "constant": true, 13 | "inputs": [], 14 | "name": "SOLO_MARGIN", 15 | "outputs": [{ "name": "", "type": "address" }], 16 | "payable": false, 17 | "stateMutability": "view", 18 | "type": "function" 19 | }, 20 | { 21 | "constant": false, 22 | "inputs": [ 23 | { "name": "inputMarketId", "type": "uint256" }, 24 | { "name": "", "type": "uint256" }, 25 | { 26 | "components": [ 27 | { "name": "owner", "type": "address" }, 28 | { "name": "number", "type": "uint256" } 29 | ], 30 | "name": "makerAccount", 31 | "type": "tuple" 32 | }, 33 | { 34 | "components": [ 35 | { "name": "owner", "type": "address" }, 36 | { "name": "number", "type": "uint256" } 37 | ], 38 | "name": "takerAccount", 39 | "type": "tuple" 40 | }, 41 | { 42 | "components": [ 43 | { "name": "sign", "type": "bool" }, 44 | { "name": "value", "type": "uint128" } 45 | ], 46 | "name": "", 47 | "type": "tuple" 48 | }, 49 | { 50 | "components": [ 51 | { "name": "sign", "type": "bool" }, 52 | { "name": "value", "type": "uint128" } 53 | ], 54 | "name": "", 55 | "type": "tuple" 56 | }, 57 | { 58 | "components": [ 59 | { "name": "sign", "type": "bool" }, 60 | { "name": "value", "type": "uint256" } 61 | ], 62 | "name": "inputWei", 63 | "type": "tuple" 64 | }, 65 | { "name": "", "type": "bytes" } 66 | ], 67 | "name": "getTradeCost", 68 | "outputs": [ 69 | { 70 | "components": [ 71 | { "name": "sign", "type": "bool" }, 72 | { "name": "denomination", "type": "uint8" }, 73 | { "name": "ref", "type": "uint8" }, 74 | { "name": "value", "type": "uint256" } 75 | ], 76 | "name": "", 77 | "type": "tuple" 78 | } 79 | ], 80 | "payable": false, 81 | "stateMutability": "nonpayable", 82 | "type": "function" 83 | }, 84 | { 85 | "constant": false, 86 | "inputs": [{ "name": "giver", "type": "address" }], 87 | "name": "addGiver", 88 | "outputs": [], 89 | "payable": false, 90 | "stateMutability": "nonpayable", 91 | "type": "function" 92 | }, 93 | { 94 | "constant": false, 95 | "inputs": [{ "name": "giver", "type": "address" }], 96 | "name": "removeGiver", 97 | "outputs": [], 98 | "payable": false, 99 | "stateMutability": "nonpayable", 100 | "type": "function" 101 | }, 102 | { 103 | "constant": false, 104 | "inputs": [], 105 | "name": "renounceOwnership", 106 | "outputs": [], 107 | "payable": false, 108 | "stateMutability": "nonpayable", 109 | "type": "function" 110 | }, 111 | { 112 | "constant": true, 113 | "inputs": [], 114 | "name": "owner", 115 | "outputs": [{ "name": "", "type": "address" }], 116 | "payable": false, 117 | "stateMutability": "view", 118 | "type": "function" 119 | }, 120 | { 121 | "constant": true, 122 | "inputs": [], 123 | "name": "isOwner", 124 | "outputs": [{ "name": "", "type": "bool" }], 125 | "payable": false, 126 | "stateMutability": "view", 127 | "type": "function" 128 | }, 129 | { 130 | "constant": false, 131 | "inputs": [{ "name": "newOwner", "type": "address" }], 132 | "name": "transferOwnership", 133 | "outputs": [], 134 | "payable": false, 135 | "stateMutability": "nonpayable", 136 | "type": "function" 137 | }, 138 | { 139 | "inputs": [ 140 | { "name": "soloMargin", "type": "address" }, 141 | { "name": "givers", "type": "address[]" } 142 | ], 143 | "payable": false, 144 | "stateMutability": "nonpayable", 145 | "type": "constructor" 146 | }, 147 | { 148 | "anonymous": false, 149 | "inputs": [{ "indexed": false, "name": "giver", "type": "address" }], 150 | "name": "LogGiverAdded", 151 | "type": "event" 152 | }, 153 | { 154 | "anonymous": false, 155 | "inputs": [{ "indexed": false, "name": "giver", "type": "address" }], 156 | "name": "LogGiverRemoved", 157 | "type": "event" 158 | }, 159 | { 160 | "anonymous": false, 161 | "inputs": [ 162 | { 163 | "components": [ 164 | { "name": "owner", "type": "address" }, 165 | { "name": "number", "type": "uint256" } 166 | ], 167 | "indexed": false, 168 | "name": "account", 169 | "type": "tuple" 170 | }, 171 | { "indexed": false, "name": "marketId", "type": "uint256" }, 172 | { "indexed": false, "name": "amount", "type": "uint256" } 173 | ], 174 | "name": "LogRefund", 175 | "type": "event" 176 | }, 177 | { 178 | "anonymous": false, 179 | "inputs": [ 180 | { "indexed": true, "name": "previousOwner", "type": "address" }, 181 | { "indexed": true, "name": "newOwner", "type": "address" } 182 | ], 183 | "name": "OwnershipTransferred", 184 | "type": "event" 185 | } 186 | ] 187 | -------------------------------------------------------------------------------- /src/dydx/abi/UsdcPriceOracle.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "constant": true, 4 | "inputs": [{ "name": "", "type": "address" }], 5 | "name": "getPrice", 6 | "outputs": [ 7 | { 8 | "components": [{ "name": "value", "type": "uint256" }], 9 | "name": "", 10 | "type": "tuple" 11 | } 12 | ], 13 | "payable": false, 14 | "stateMutability": "view", 15 | "type": "function" 16 | }, 17 | { 18 | "constant": true, 19 | "inputs": [], 20 | "name": "ONE_DOLLAR", 21 | "outputs": [{ "name": "", "type": "uint256" }], 22 | "payable": false, 23 | "stateMutability": "view", 24 | "type": "function" 25 | } 26 | ] 27 | -------------------------------------------------------------------------------- /src/dydx/abi/WethPriceOracle.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "constant": true, 4 | "inputs": [{ "name": "", "type": "address" }], 5 | "name": "getPrice", 6 | "outputs": [ 7 | { 8 | "components": [{ "name": "value", "type": "uint256" }], 9 | "name": "", 10 | "type": "tuple" 11 | } 12 | ], 13 | "payable": false, 14 | "stateMutability": "view", 15 | "type": "function" 16 | }, 17 | { 18 | "constant": true, 19 | "inputs": [], 20 | "name": "ONE_DOLLAR", 21 | "outputs": [{ "name": "", "type": "uint256" }], 22 | "payable": false, 23 | "stateMutability": "view", 24 | "type": "function" 25 | }, 26 | { 27 | "constant": true, 28 | "inputs": [], 29 | "name": "MEDIANIZER", 30 | "outputs": [{ "name": "", "type": "address" }], 31 | "payable": false, 32 | "stateMutability": "view", 33 | "type": "function" 34 | }, 35 | { 36 | "inputs": [{ "name": "medianizer", "type": "address" }], 37 | "payable": false, 38 | "stateMutability": "nonpayable", 39 | "type": "constructor" 40 | } 41 | ] 42 | -------------------------------------------------------------------------------- /src/dydx/contracts.ts: -------------------------------------------------------------------------------- 1 | import soloMarginAbi from "./abi/SoloMargin.json"; 2 | import payableProxyForSoloMarginAbi from "./abi/PayableProxyForSoloMargin.json"; 3 | import polynomialInterestSetterAbi from "./abi/PolynomialInterestSetter.json"; 4 | import expiryAbi from "./abi/Expiry.json"; 5 | import expiryV2Abi from "./abi/ExpiryV2.json"; 6 | import daiPriceOracleAbi from "./abi/DaiPriceOracle.json"; 7 | import saiPriceOracleAbi from "./abi/SaiPriceOracle.json"; 8 | import wethPriceOracleAbi from "./abi/WethPriceOracle.json"; 9 | import usdcPriceOracleAbi from "./abi/UsdcPriceOracle.json"; 10 | import adminImplAbi from "./abi/AdminImpl.json"; 11 | import operationImplAbi from "./abi/OperationImpl.json"; 12 | import liquidatorProxyV1ForSoloMarginAbi from "./abi/LiquidatorProxyV1ForSoloMargin.json"; 13 | import limitOrdersAbi from "./abi/LimitOrders.json"; 14 | import stopLimitOrdersAbi from "./abi/StopLimitOrders.json"; 15 | import canonicalOrdersAbi from "./abi/CanonicalOrders.json"; 16 | import signedOperationProxyAbi from "./abi/SignedOperationProxy.json"; 17 | import refunderAbi from "./abi/Refunder.json"; 18 | 19 | const contracts = { 20 | soloMargin: { 21 | address: "0x1e0447b19bb6ecfdae1e4ae1694b0c3659614e4e", 22 | abi: soloMarginAbi, 23 | }, 24 | payableProxyForSoloMargin: { 25 | abi: payableProxyForSoloMarginAbi, 26 | address: "0xa8b39829cE2246f89B31C013b8Cde15506Fb9A76", 27 | }, 28 | polynomialInterestSetter: { 29 | abi: polynomialInterestSetterAbi, 30 | address: "0xaEE83ca85Ad63DFA04993adcd76CB2B3589eCa49", 31 | }, 32 | expiry: { 33 | abi: expiryAbi, 34 | address: "0x0ECE224FBC24D40B446c6a94a142dc41fAe76f2d", 35 | }, 36 | expiryV2: { 37 | abi: expiryV2Abi, 38 | address: "0x739A1DF6725657f6a16dC2d5519DC36FD7911A12", 39 | }, 40 | daiPriceOracle: { 41 | abi: daiPriceOracleAbi, 42 | address: "0x0fBd14718d8FAB8f9f40Ee5c5612b1F0717100A2", 43 | }, 44 | saiPriceOracle: { 45 | abi: saiPriceOracleAbi, 46 | address: "0x787F552BDC17332c98aA360748884513e3cB401a", 47 | }, 48 | wethPriceOracle: { 49 | abi: wethPriceOracleAbi, 50 | address: "0xf61AE328463CD997C7b58e7045CdC613e1cFdb69", 51 | }, 52 | usdcPriceOracle: { 53 | abi: usdcPriceOracleAbi, 54 | address: "0x52f1c952A48a4588f9ae615d38cfdbf8dF036e60", 55 | }, 56 | adminImpl: { 57 | abi: adminImplAbi, 58 | address: "0x8a6629fEba4196E0A61B8E8C94D4905e525bc055", 59 | }, 60 | operationImpl: { 61 | abi: operationImplAbi, 62 | address: "0x56E7d4520ABFECf10b38368b00723d9BD3c21ee1", 63 | }, 64 | liquidatorProxyV1ForSoloMargin: { 65 | abi: liquidatorProxyV1ForSoloMarginAbi, 66 | address: "0xD4B6cd147ad8A0D5376b6FDBa85fE8128C6f0686", 67 | }, 68 | limitOrders: { 69 | abi: limitOrdersAbi, 70 | address: "0xDEf136D9884528e1EB302f39457af0E4d3AD24EB", 71 | }, 72 | stopLimitOrders: { 73 | abi: stopLimitOrdersAbi, 74 | address: "0xbFb635e8c6689ac3874aD9A60FaB1c29270f1710", 75 | }, 76 | canonicalOrders: { 77 | abi: canonicalOrdersAbi, 78 | address: "0xCd81398895bEa7AD9EFF273aeFFc41A9d83B4dAD", 79 | }, 80 | signedOperationProxy: { 81 | abi: signedOperationProxyAbi, 82 | address: "0x2a842bC64343FAD4Ec4a8424ba7ff3c0A70b6e55", 83 | }, 84 | refunder: { 85 | abi: refunderAbi, 86 | address: "0x7454dF5d0758D4E7A538c3aCF4841FA9137F0f74", 87 | }, 88 | }; 89 | 90 | export default contracts; 91 | -------------------------------------------------------------------------------- /src/dydx/contracts/DydxFlashloanBase.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.8.0; 2 | pragma experimental ABIEncoderV2; 3 | 4 | import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 5 | 6 | import "./ISoloMargin.sol"; 7 | 8 | 9 | contract DydxFlashloanBase { 10 | using SafeMath for uint256; 11 | 12 | // -- Internal Helper functions -- // 13 | 14 | function _getMarketIdFromTokenAddress(address _solo, address token) 15 | internal 16 | view 17 | returns (uint256) 18 | { 19 | ISoloMargin solo = ISoloMargin(_solo); 20 | 21 | uint256 numMarkets = solo.getNumMarkets(); 22 | 23 | address curToken; 24 | for (uint256 i = 0; i < numMarkets; i++) { 25 | curToken = solo.getMarketTokenAddress(i); 26 | 27 | if (curToken == token) { 28 | return i; 29 | } 30 | } 31 | 32 | revert("No marketId found for provided token"); 33 | } 34 | 35 | function _getRepaymentAmountInternal(uint256 amount) 36 | internal 37 | view 38 | returns (uint256) 39 | { 40 | // Needs to be overcollateralize 41 | // Needs to provide +2 wei to be safe 42 | return amount + 2; 43 | } 44 | 45 | function _getAccountInfo() internal view returns (Account.Info memory) { 46 | return Account.Info({owner: address(this), number: 1}); 47 | } 48 | 49 | function _getWithdrawAction(uint marketId, uint256 amount) 50 | internal 51 | view 52 | returns (Actions.ActionArgs memory) 53 | { 54 | return 55 | Actions.ActionArgs({ 56 | actionType: Actions.ActionType.Withdraw, 57 | accountId: 0, 58 | amount: Types.AssetAmount({ 59 | sign: false, 60 | denomination: Types.AssetDenomination.Wei, 61 | ref: Types.AssetReference.Delta, 62 | value: amount 63 | }), 64 | primaryMarketId: marketId, 65 | secondaryMarketId: 0, 66 | otherAddress: address(this), 67 | otherAccountId: 0, 68 | data: "" 69 | }); 70 | } 71 | 72 | function _getCallAction(bytes memory data) 73 | internal 74 | view 75 | returns (Actions.ActionArgs memory) 76 | { 77 | return 78 | Actions.ActionArgs({ 79 | actionType: Actions.ActionType.Call, 80 | accountId: 0, 81 | amount: Types.AssetAmount({ 82 | sign: false, 83 | denomination: Types.AssetDenomination.Wei, 84 | ref: Types.AssetReference.Delta, 85 | value: 0 86 | }), 87 | primaryMarketId: 0, 88 | secondaryMarketId: 0, 89 | otherAddress: address(this), 90 | otherAccountId: 0, 91 | data: data 92 | }); 93 | } 94 | 95 | function _getDepositAction(uint marketId, uint256 amount) 96 | internal 97 | view 98 | returns (Actions.ActionArgs memory) 99 | { 100 | return 101 | Actions.ActionArgs({ 102 | actionType: Actions.ActionType.Deposit, 103 | accountId: 0, 104 | amount: Types.AssetAmount({ 105 | sign: true, 106 | denomination: Types.AssetDenomination.Wei, 107 | ref: Types.AssetReference.Delta, 108 | value: amount 109 | }), 110 | primaryMarketId: marketId, 111 | secondaryMarketId: 0, 112 | otherAddress: address(this), 113 | otherAccountId: 0, 114 | data: "" 115 | }); 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /src/dydx/contracts/ICallee.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.8.0; 2 | pragma experimental ABIEncoderV2; 3 | 4 | import { Account } from "./ISoloMargin.sol"; 5 | 6 | 7 | /** 8 | * @title ICallee 9 | * @author dYdX 10 | * 11 | * Interface that Callees for Solo must implement in order to ingest data. 12 | */ 13 | contract ICallee { 14 | 15 | // ============ Public Functions ============ 16 | 17 | /** 18 | * Allows users to send this contract arbitrary data. 19 | * 20 | * @param sender The msg.sender to Solo 21 | * @param accountInfo The account from which the data is being sent 22 | * @param data Arbitrary data given by the sender 23 | */ 24 | function callFunction( 25 | address sender, 26 | Account.Info memory accountInfo, 27 | bytes memory data 28 | ) 29 | public; 30 | } -------------------------------------------------------------------------------- /src/dydx/index.ts: -------------------------------------------------------------------------------- 1 | import { default as contracts } from "./contracts"; 2 | 3 | export = { 4 | ...contracts, 5 | }; 6 | -------------------------------------------------------------------------------- /src/erc20/README.md: -------------------------------------------------------------------------------- 1 | # ERC20 Token 2 | -------------------------------------------------------------------------------- /src/erc20/abi/WETH.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "constant": true, 4 | "inputs": [], 5 | "name": "name", 6 | "outputs": [{ "name": "", "type": "string" }], 7 | "payable": false, 8 | "stateMutability": "view", 9 | "type": "function" 10 | }, 11 | { 12 | "constant": false, 13 | "inputs": [ 14 | { "name": "guy", "type": "address" }, 15 | { "name": "wad", "type": "uint256" } 16 | ], 17 | "name": "approve", 18 | "outputs": [{ "name": "", "type": "bool" }], 19 | "payable": false, 20 | "stateMutability": "nonpayable", 21 | "type": "function" 22 | }, 23 | { 24 | "constant": true, 25 | "inputs": [], 26 | "name": "totalSupply", 27 | "outputs": [{ "name": "", "type": "uint256" }], 28 | "payable": false, 29 | "stateMutability": "view", 30 | "type": "function" 31 | }, 32 | { 33 | "constant": false, 34 | "inputs": [ 35 | { "name": "src", "type": "address" }, 36 | { "name": "dst", "type": "address" }, 37 | { "name": "wad", "type": "uint256" } 38 | ], 39 | "name": "transferFrom", 40 | "outputs": [{ "name": "", "type": "bool" }], 41 | "payable": false, 42 | "stateMutability": "nonpayable", 43 | "type": "function" 44 | }, 45 | { 46 | "constant": false, 47 | "inputs": [{ "name": "wad", "type": "uint256" }], 48 | "name": "withdraw", 49 | "outputs": [], 50 | "payable": false, 51 | "stateMutability": "nonpayable", 52 | "type": "function" 53 | }, 54 | { 55 | "constant": true, 56 | "inputs": [], 57 | "name": "decimals", 58 | "outputs": [{ "name": "", "type": "uint8" }], 59 | "payable": false, 60 | "stateMutability": "view", 61 | "type": "function" 62 | }, 63 | { 64 | "constant": true, 65 | "inputs": [{ "name": "", "type": "address" }], 66 | "name": "balanceOf", 67 | "outputs": [{ "name": "", "type": "uint256" }], 68 | "payable": false, 69 | "stateMutability": "view", 70 | "type": "function" 71 | }, 72 | { 73 | "constant": true, 74 | "inputs": [], 75 | "name": "symbol", 76 | "outputs": [{ "name": "", "type": "string" }], 77 | "payable": false, 78 | "stateMutability": "view", 79 | "type": "function" 80 | }, 81 | { 82 | "constant": false, 83 | "inputs": [ 84 | { "name": "dst", "type": "address" }, 85 | { "name": "wad", "type": "uint256" } 86 | ], 87 | "name": "transfer", 88 | "outputs": [{ "name": "", "type": "bool" }], 89 | "payable": false, 90 | "stateMutability": "nonpayable", 91 | "type": "function" 92 | }, 93 | { 94 | "constant": false, 95 | "inputs": [], 96 | "name": "deposit", 97 | "outputs": [], 98 | "payable": true, 99 | "stateMutability": "payable", 100 | "type": "function" 101 | }, 102 | { 103 | "constant": true, 104 | "inputs": [ 105 | { "name": "", "type": "address" }, 106 | { "name": "", "type": "address" } 107 | ], 108 | "name": "allowance", 109 | "outputs": [{ "name": "", "type": "uint256" }], 110 | "payable": false, 111 | "stateMutability": "view", 112 | "type": "function" 113 | }, 114 | { "payable": true, "stateMutability": "payable", "type": "fallback" }, 115 | { 116 | "anonymous": false, 117 | "inputs": [ 118 | { "indexed": true, "name": "src", "type": "address" }, 119 | { "indexed": true, "name": "guy", "type": "address" }, 120 | { "indexed": false, "name": "wad", "type": "uint256" } 121 | ], 122 | "name": "Approval", 123 | "type": "event" 124 | }, 125 | { 126 | "anonymous": false, 127 | "inputs": [ 128 | { "indexed": true, "name": "src", "type": "address" }, 129 | { "indexed": true, "name": "dst", "type": "address" }, 130 | { "indexed": false, "name": "wad", "type": "uint256" } 131 | ], 132 | "name": "Transfer", 133 | "type": "event" 134 | }, 135 | { 136 | "anonymous": false, 137 | "inputs": [ 138 | { "indexed": true, "name": "dst", "type": "address" }, 139 | { "indexed": false, "name": "wad", "type": "uint256" } 140 | ], 141 | "name": "Deposit", 142 | "type": "event" 143 | }, 144 | { 145 | "anonymous": false, 146 | "inputs": [ 147 | { "indexed": true, "name": "src", "type": "address" }, 148 | { "indexed": false, "name": "wad", "type": "uint256" } 149 | ], 150 | "name": "Withdrawal", 151 | "type": "event" 152 | } 153 | ] 154 | -------------------------------------------------------------------------------- /src/erc20/index.ts: -------------------------------------------------------------------------------- 1 | import { default as tokens } from "./tokens"; 2 | import abi from "./abi/ERC20.json"; 3 | 4 | export = { 5 | ...tokens, 6 | abi, 7 | }; 8 | -------------------------------------------------------------------------------- /src/erc20/tokens.ts: -------------------------------------------------------------------------------- 1 | import ERC20Abi from "./abi/ERC20.json"; 2 | import WETHAbi from "./abi/WETH.json"; 3 | 4 | const tokens = { 5 | eth: { 6 | symbol: "ETH", 7 | decimals: 18, 8 | address: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", 9 | }, 10 | bat: { 11 | symbol: "BAT", 12 | decimals: 18, 13 | address: "0x0d8775f648430679a709e98d2b0cb6250d2887ef", 14 | abi: ERC20Abi, 15 | }, 16 | dai: { 17 | symbol: "DAI", 18 | decimals: 18, 19 | address: "0x6B175474E89094C44Da98b954EedeAC495271d0F", 20 | abi: ERC20Abi, 21 | }, 22 | rep: { 23 | symbol: "REP", 24 | decimals: 18, 25 | address: "0x1985365e9f78359a9B6AD760e32412f4a445E862", 26 | abi: ERC20Abi, 27 | }, 28 | sai: { 29 | symbol: "SAI", 30 | decimals: 18, 31 | address: "0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359", 32 | abi: ERC20Abi, 33 | }, 34 | snx: { 35 | symbol: "SNX", 36 | decimals: 18, 37 | address: "0xc011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f", 38 | abi: ERC20Abi, 39 | }, 40 | usdc: { 41 | symbol: "USDC", 42 | decimals: 6, 43 | address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", 44 | abi: ERC20Abi, 45 | }, 46 | weth: { 47 | symbol: "WETH", 48 | decimals: 18, 49 | address: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", 50 | abi: WETHAbi, 51 | }, 52 | wbtc: { 53 | symbol: "WBTC", 54 | decimals: 8, 55 | address: "0x2260fac5e5542a773aa44fbcfedf7c193bc2c599", 56 | abi: ERC20Abi, 57 | }, 58 | zrx: { 59 | symbol: "ZRX", 60 | decimals: 18, 61 | address: "0xE41d2489571d322189246DaFA5ebDe1F4699F498", 62 | abi: ERC20Abi, 63 | }, 64 | bal: { 65 | symbol: "BAL", 66 | decimals: 18, 67 | address: "0xba100000625a3754423978a60c9317c58a424e3D", 68 | abi: ERC20Abi, 69 | }, 70 | }; 71 | 72 | export default tokens; 73 | -------------------------------------------------------------------------------- /src/idle/contracts.ts: -------------------------------------------------------------------------------- 1 | const contracts = { 2 | maxYield: { 3 | dai: { 4 | address: "0x78751B12Da02728F467A44eAc40F5cbc16Bd7934", 5 | }, 6 | usdc: { 7 | address: "0x12B98C621E8754Ae70d0fDbBC73D6208bC3e3cA6", 8 | }, 9 | usdt: { 10 | address: "0x63D27B3DA94A9E871222CB0A32232674B02D2f2D", 11 | }, 12 | susd: { 13 | address: "0xE79E177d2a5c7085027d7C64c8F271c81430fc9b", 14 | }, 15 | tusd: { 16 | address: "0x51C77689A9c2e8cCBEcD4eC9770a1fA5fA83EeF1", 17 | }, 18 | wbtc: { 19 | address: "0xD6f279B7ccBCD70F8be439d25B9Df93AEb60eC55", 20 | }, 21 | }, 22 | riskAdjusted: { 23 | dai: { 24 | address: "0x1846bdfDB6A0f5c473dEc610144513bd071999fB", 25 | }, 26 | usdc: { 27 | address: "0xcDdB1Bceb7a1979C6caa0229820707429dd3Ec6C", 28 | }, 29 | usdt: { 30 | address: "0x42740698959761BAF1B06baa51EfBD88CB1D862B", 31 | }, 32 | }, 33 | }; 34 | 35 | export default contracts; 36 | -------------------------------------------------------------------------------- /src/idle/index.ts: -------------------------------------------------------------------------------- 1 | import { default as contracts } from "./contracts"; 2 | import abi from "./abi/IdleTokenV3.json"; 3 | 4 | export = { 5 | ...contracts, 6 | abi, 7 | decimals: 18, 8 | }; 9 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import { default as aave } from "./aave"; 2 | import { default as balancer } from "./balancer"; 3 | import { default as compound } from "./compound"; 4 | import { default as curvefi } from "./curvefi"; 5 | import { default as dappsys } from "./dappsys"; 6 | import { default as dydx } from "./dydx"; 7 | import { default as erc20 } from "./erc20"; 8 | import { default as idle } from "./idle"; 9 | import { default as kyber } from "./kyber"; 10 | import { default as maker } from "./maker"; 11 | import { default as mstable } from "./mstable"; 12 | import { default as onesplit } from "./onesplit"; 13 | import { default as synthetix } from "./synthetix"; 14 | import { default as uma } from "./uma"; 15 | import { default as uniswap } from "./uniswap"; 16 | import { default as uniswapV2 } from "./uniswapV2"; 17 | 18 | export const legos = { 19 | aave, 20 | balancer, 21 | compound, 22 | curvefi, 23 | dappsys, 24 | dydx, 25 | erc20, 26 | idle, 27 | kyber, 28 | maker, 29 | mstable, 30 | onesplit, 31 | synthetix, 32 | uma, 33 | uniswap, 34 | uniswapV2, 35 | }; 36 | -------------------------------------------------------------------------------- /src/kyber/contracts.ts: -------------------------------------------------------------------------------- 1 | import networkProxyAbi from "./abi/KyberNetworkProxy.json"; 2 | 3 | const contracts = { 4 | network: { 5 | address: "0x818E6FECD516Ecc3849DAf6845e3EC868087B755", 6 | abi: networkProxyAbi, 7 | }, 8 | }; 9 | 10 | export default contracts; 11 | -------------------------------------------------------------------------------- /src/kyber/contracts/KyberNetworkProxy.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.8.0; 2 | 3 | // Note: Kyber uses it owns ERC20 interface 4 | // See: https://github.com/KyberNetwork/smart-contracts/blob/master/contracts/ERC20Interface.sol 5 | import { IERC20 as ERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 6 | 7 | interface KyberNetworkProxyInterface { 8 | function maxGasPrice() external view returns(uint); 9 | function getUserCapInWei(address user) external view returns(uint); 10 | function getUserCapInTokenWei(address user, ERC20 token) external view returns(uint); 11 | function enabled() external view returns(bool); 12 | function info(bytes32 id) external view returns(uint); 13 | 14 | function getExpectedRate(ERC20 src, ERC20 dest, uint srcQty) external view 15 | returns (uint expectedRate, uint slippageRate); 16 | 17 | function tradeWithHint(ERC20 src, uint srcAmount, ERC20 dest, address destAddress, uint maxDestAmount, 18 | uint minConversionRate, address walletId, bytes calldata hint) external payable returns(uint); 19 | } 20 | 21 | interface SimpleNetworkInterface { 22 | function swapTokenToToken(ERC20 src, uint srcAmount, ERC20 dest, uint minConversionRate) external returns(uint); 23 | function swapEtherToToken(ERC20 token, uint minConversionRate) external payable returns(uint); 24 | function swapTokenToEther(ERC20 token, uint srcAmount, uint minConversionRate) external returns(uint); 25 | } 26 | 27 | contract KyberNetworkProxy is KyberNetworkProxyInterface, SimpleNetworkInterface {} -------------------------------------------------------------------------------- /src/kyber/index.ts: -------------------------------------------------------------------------------- 1 | import { default as contracts } from "./contracts"; 2 | 3 | export = { 4 | ...contracts, 5 | }; 6 | -------------------------------------------------------------------------------- /src/maker/abi/Medianizer.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "constant": false, 4 | "inputs": [{ "name": "owner_", "type": "address" }], 5 | "name": "setOwner", 6 | "outputs": [], 7 | "payable": false, 8 | "type": "function" 9 | }, 10 | { 11 | "constant": false, 12 | "inputs": [{ "name": "", "type": "bytes32" }], 13 | "name": "poke", 14 | "outputs": [], 15 | "payable": false, 16 | "type": "function" 17 | }, 18 | { 19 | "constant": false, 20 | "inputs": [], 21 | "name": "poke", 22 | "outputs": [], 23 | "payable": false, 24 | "type": "function" 25 | }, 26 | { 27 | "constant": true, 28 | "inputs": [], 29 | "name": "compute", 30 | "outputs": [ 31 | { "name": "", "type": "bytes32" }, 32 | { "name": "", "type": "bool" } 33 | ], 34 | "payable": false, 35 | "type": "function" 36 | }, 37 | { 38 | "constant": false, 39 | "inputs": [{ "name": "wat", "type": "address" }], 40 | "name": "set", 41 | "outputs": [], 42 | "payable": false, 43 | "type": "function" 44 | }, 45 | { 46 | "constant": false, 47 | "inputs": [{ "name": "wat", "type": "address" }], 48 | "name": "unset", 49 | "outputs": [], 50 | "payable": false, 51 | "type": "function" 52 | }, 53 | { 54 | "constant": true, 55 | "inputs": [{ "name": "", "type": "address" }], 56 | "name": "indexes", 57 | "outputs": [{ "name": "", "type": "bytes12" }], 58 | "payable": false, 59 | "type": "function" 60 | }, 61 | { 62 | "constant": true, 63 | "inputs": [], 64 | "name": "next", 65 | "outputs": [{ "name": "", "type": "bytes12" }], 66 | "payable": false, 67 | "type": "function" 68 | }, 69 | { 70 | "constant": true, 71 | "inputs": [], 72 | "name": "read", 73 | "outputs": [{ "name": "", "type": "bytes32" }], 74 | "payable": false, 75 | "type": "function" 76 | }, 77 | { 78 | "constant": true, 79 | "inputs": [], 80 | "name": "peek", 81 | "outputs": [ 82 | { "name": "", "type": "bytes32" }, 83 | { "name": "", "type": "bool" } 84 | ], 85 | "payable": false, 86 | "type": "function" 87 | }, 88 | { 89 | "constant": true, 90 | "inputs": [{ "name": "", "type": "bytes12" }], 91 | "name": "values", 92 | "outputs": [{ "name": "", "type": "address" }], 93 | "payable": false, 94 | "type": "function" 95 | }, 96 | { 97 | "constant": false, 98 | "inputs": [{ "name": "min_", "type": "uint96" }], 99 | "name": "setMin", 100 | "outputs": [], 101 | "payable": false, 102 | "type": "function" 103 | }, 104 | { 105 | "constant": false, 106 | "inputs": [{ "name": "authority_", "type": "address" }], 107 | "name": "setAuthority", 108 | "outputs": [], 109 | "payable": false, 110 | "type": "function" 111 | }, 112 | { 113 | "constant": true, 114 | "inputs": [], 115 | "name": "owner", 116 | "outputs": [{ "name": "", "type": "address" }], 117 | "payable": false, 118 | "type": "function" 119 | }, 120 | { 121 | "constant": false, 122 | "inputs": [], 123 | "name": "void", 124 | "outputs": [], 125 | "payable": false, 126 | "type": "function" 127 | }, 128 | { 129 | "constant": false, 130 | "inputs": [ 131 | { "name": "pos", "type": "bytes12" }, 132 | { "name": "wat", "type": "address" } 133 | ], 134 | "name": "set", 135 | "outputs": [], 136 | "payable": false, 137 | "type": "function" 138 | }, 139 | { 140 | "constant": true, 141 | "inputs": [], 142 | "name": "authority", 143 | "outputs": [{ "name": "", "type": "address" }], 144 | "payable": false, 145 | "type": "function" 146 | }, 147 | { 148 | "constant": false, 149 | "inputs": [{ "name": "pos", "type": "bytes12" }], 150 | "name": "unset", 151 | "outputs": [], 152 | "payable": false, 153 | "type": "function" 154 | }, 155 | { 156 | "constant": false, 157 | "inputs": [{ "name": "next_", "type": "bytes12" }], 158 | "name": "setNext", 159 | "outputs": [], 160 | "payable": false, 161 | "type": "function" 162 | }, 163 | { 164 | "constant": true, 165 | "inputs": [], 166 | "name": "min", 167 | "outputs": [{ "name": "", "type": "uint96" }], 168 | "payable": false, 169 | "type": "function" 170 | }, 171 | { 172 | "anonymous": true, 173 | "inputs": [ 174 | { "indexed": true, "name": "sig", "type": "bytes4" }, 175 | { "indexed": true, "name": "guy", "type": "address" }, 176 | { "indexed": true, "name": "foo", "type": "bytes32" }, 177 | { "indexed": true, "name": "bar", "type": "bytes32" }, 178 | { "indexed": false, "name": "wad", "type": "uint256" }, 179 | { "indexed": false, "name": "fax", "type": "bytes" } 180 | ], 181 | "name": "LogNote", 182 | "type": "event" 183 | }, 184 | { 185 | "anonymous": false, 186 | "inputs": [{ "indexed": true, "name": "authority", "type": "address" }], 187 | "name": "LogSetAuthority", 188 | "type": "event" 189 | }, 190 | { 191 | "anonymous": false, 192 | "inputs": [{ "indexed": true, "name": "owner", "type": "address" }], 193 | "name": "LogSetOwner", 194 | "type": "event" 195 | } 196 | ] 197 | -------------------------------------------------------------------------------- /src/maker/abi/ProxyRegistry.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "address", 6 | "name": "factory_", 7 | "type": "address" 8 | } 9 | ], 10 | "payable": false, 11 | "stateMutability": "nonpayable", 12 | "type": "constructor" 13 | }, 14 | { 15 | "constant": false, 16 | "inputs": [], 17 | "name": "build", 18 | "outputs": [ 19 | { 20 | "internalType": "address payable", 21 | "name": "proxy", 22 | "type": "address" 23 | } 24 | ], 25 | "payable": false, 26 | "stateMutability": "nonpayable", 27 | "type": "function" 28 | }, 29 | { 30 | "constant": false, 31 | "inputs": [ 32 | { 33 | "internalType": "address", 34 | "name": "owner", 35 | "type": "address" 36 | } 37 | ], 38 | "name": "build", 39 | "outputs": [ 40 | { 41 | "internalType": "address payable", 42 | "name": "proxy", 43 | "type": "address" 44 | } 45 | ], 46 | "payable": false, 47 | "stateMutability": "nonpayable", 48 | "type": "function" 49 | }, 50 | { 51 | "constant": true, 52 | "inputs": [ 53 | { 54 | "internalType": "address", 55 | "name": "", 56 | "type": "address" 57 | } 58 | ], 59 | "name": "proxies", 60 | "outputs": [ 61 | { 62 | "internalType": "contract DSProxy", 63 | "name": "", 64 | "type": "address" 65 | } 66 | ], 67 | "payable": false, 68 | "stateMutability": "view", 69 | "type": "function" 70 | } 71 | ] -------------------------------------------------------------------------------- /src/maker/contracts.ts: -------------------------------------------------------------------------------- 1 | import makerProxyRegistryAbi from "./abi/ProxyRegistry.json"; 2 | import dssCdpManagerAbi from "./abi/DssCdpManager.json"; 3 | import dssProxyActionsAbi from "./abi/DssProxyActions.json"; 4 | 5 | // Reference: https://changelog.makerdao.com/ 6 | 7 | const contracts = { 8 | proxyRegistry: { 9 | address: "0x4678f0a6958e4D2Bc4F1BAF7Bc52E8F3564f3fE4", 10 | abi: makerProxyRegistryAbi, 11 | }, 12 | dssCdpManager: { 13 | address: "0x5ef30b9986345249bc32d8928B7ee64DE9435E39", 14 | abi: dssCdpManagerAbi, 15 | }, 16 | dssProxyActions: { 17 | address: "0x82ecd135dce65fbc6dbdd0e4237e0af93ffd5038", 18 | abi: dssProxyActionsAbi, 19 | }, 20 | jug: { 21 | address: "0x19c0976f590D67707E62397C87829d896Dc0f1F1", 22 | }, 23 | daiJoin: { 24 | address: "0x9759A6Ac90977b93B58547b4A71c78317f391A28", 25 | }, 26 | batAJoin: { 27 | address: "0x3D0B1912B66114d4096F48A8CEe3A56C231772cA", 28 | }, 29 | ethAJoin: { 30 | address: "0x2F0b23f53734252Bda2277357e97e1517d6B042A", 31 | }, 32 | usdcJoin: { 33 | address: "0xA191e578a6736167326d05c119CE0c90849E84B7", 34 | }, 35 | }; 36 | 37 | export default contracts; 38 | -------------------------------------------------------------------------------- /src/maker/contracts/IMedianizer.sol: -------------------------------------------------------------------------------- 1 | interface IMedianizer { 2 | function setOwner(address owner_) external; 3 | 4 | function poke(bytes32) external; 5 | 6 | function poke() external; 7 | 8 | function compute() external returns (bytes32, bool); 9 | 10 | function set(address wat) external; 11 | 12 | function unset(address wat) external; 13 | 14 | function indexes(address) external returns (bytes12); 15 | 16 | function next() external returns (bytes12); 17 | 18 | function read() external returns (bytes32); 19 | 20 | function peek() external returns (bytes32, bool); 21 | 22 | function values(bytes12) external returns (address); 23 | 24 | function setMin(uint96 min_) external; 25 | 26 | function setAuthority(address authority_) external; 27 | 28 | function owner() external returns (address); 29 | 30 | function void() external; 31 | 32 | function set(bytes12 pos, address wat) external; 33 | 34 | function authority() external returns (address); 35 | 36 | function unset(bytes12 pos) external; 37 | 38 | function setNext(bytes12 next_) external; 39 | 40 | function min() external returns (uint96); 41 | } 42 | -------------------------------------------------------------------------------- /src/maker/ilks.ts: -------------------------------------------------------------------------------- 1 | import erc20 from "../erc20"; 2 | 3 | const ilks = { 4 | batA: { 5 | symbol: "BAT-A", 6 | token: { address: erc20.bat.address }, 7 | }, 8 | ethA: { 9 | symbol: "ETH-A", 10 | token: { address: erc20.eth.address }, 11 | }, 12 | usdcA: { 13 | symbol: "USDC-A", 14 | token: { address: erc20.usdc.address }, 15 | }, 16 | }; 17 | 18 | export default ilks; 19 | -------------------------------------------------------------------------------- /src/maker/index.ts: -------------------------------------------------------------------------------- 1 | import { default as contracts } from "./contracts"; 2 | import { default as ilks } from "./ilks"; 3 | import { default as priceFeeds } from "./priceFeeds"; 4 | 5 | export = { 6 | ...contracts, 7 | ...ilks, 8 | ...priceFeeds 9 | }; 10 | -------------------------------------------------------------------------------- /src/maker/priceFeeds.ts: -------------------------------------------------------------------------------- 1 | import medianizerAbi from "./abi/Medianizer.json"; 2 | 3 | const priceFeeds = { 4 | ethUsdPriceFeed: { 5 | address: "0x729d19f657bd0614b4985cf1d82531c67569197b", 6 | abi: medianizerAbi, 7 | } 8 | }; 9 | 10 | export default priceFeeds; 11 | -------------------------------------------------------------------------------- /src/mstable/abi/MassetValidationHelper.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "constant": true, 4 | "inputs": [ 5 | { "internalType": "address", "name": "_mAsset", "type": "address" }, 6 | { "internalType": "address", "name": "_input", "type": "address" }, 7 | { "internalType": "address", "name": "_output", "type": "address" } 8 | ], 9 | "name": "getMaxSwap", 10 | "outputs": [ 11 | { "internalType": "bool", "name": "", "type": "bool" }, 12 | { "internalType": "string", "name": "", "type": "string" }, 13 | { "internalType": "uint256", "name": "", "type": "uint256" }, 14 | { "internalType": "uint256", "name": "", "type": "uint256" } 15 | ], 16 | "payable": false, 17 | "stateMutability": "view", 18 | "type": "function" 19 | }, 20 | { 21 | "constant": true, 22 | "inputs": [ 23 | { "internalType": "address", "name": "_mAsset", "type": "address" }, 24 | { 25 | "internalType": "uint256", 26 | "name": "_mAssetQuantity", 27 | "type": "uint256" 28 | }, 29 | { "internalType": "address", "name": "_outputBasset", "type": "address" } 30 | ], 31 | "name": "getRedeemValidity", 32 | "outputs": [ 33 | { "internalType": "bool", "name": "", "type": "bool" }, 34 | { "internalType": "string", "name": "", "type": "string" }, 35 | { "internalType": "uint256", "name": "output", "type": "uint256" }, 36 | { 37 | "internalType": "uint256", 38 | "name": "bassetQuantityArg", 39 | "type": "uint256" 40 | } 41 | ], 42 | "payable": false, 43 | "stateMutability": "view", 44 | "type": "function" 45 | }, 46 | { 47 | "constant": true, 48 | "inputs": [ 49 | { "internalType": "address", "name": "_mAsset", "type": "address" } 50 | ], 51 | "name": "suggestMintAsset", 52 | "outputs": [ 53 | { "internalType": "bool", "name": "", "type": "bool" }, 54 | { "internalType": "string", "name": "", "type": "string" }, 55 | { "internalType": "address", "name": "", "type": "address" } 56 | ], 57 | "payable": false, 58 | "stateMutability": "view", 59 | "type": "function" 60 | }, 61 | { 62 | "constant": true, 63 | "inputs": [ 64 | { "internalType": "address", "name": "_mAsset", "type": "address" } 65 | ], 66 | "name": "suggestRedeemAsset", 67 | "outputs": [ 68 | { "internalType": "bool", "name": "", "type": "bool" }, 69 | { "internalType": "string", "name": "", "type": "string" }, 70 | { "internalType": "address", "name": "", "type": "address" } 71 | ], 72 | "payable": false, 73 | "stateMutability": "view", 74 | "type": "function" 75 | } 76 | ] 77 | -------------------------------------------------------------------------------- /src/mstable/abi/RewardsDistributor.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "address", 6 | "name": "_nexus", 7 | "type": "address" 8 | }, 9 | { 10 | "internalType": "address[]", 11 | "name": "_fundManagers", 12 | "type": "address[]" 13 | } 14 | ], 15 | "payable": false, 16 | "stateMutability": "nonpayable", 17 | "type": "constructor" 18 | }, 19 | { 20 | "anonymous": false, 21 | "inputs": [ 22 | { 23 | "indexed": false, 24 | "internalType": "address", 25 | "name": "funder", 26 | "type": "address" 27 | }, 28 | { 29 | "indexed": false, 30 | "internalType": "address", 31 | "name": "recipient", 32 | "type": "address" 33 | }, 34 | { 35 | "indexed": false, 36 | "internalType": "address", 37 | "name": "rewardToken", 38 | "type": "address" 39 | }, 40 | { 41 | "indexed": false, 42 | "internalType": "uint256", 43 | "name": "amount", 44 | "type": "uint256" 45 | } 46 | ], 47 | "name": "DistributedReward", 48 | "type": "event" 49 | }, 50 | { 51 | "anonymous": false, 52 | "inputs": [ 53 | { 54 | "indexed": true, 55 | "internalType": "address", 56 | "name": "_address", 57 | "type": "address" 58 | } 59 | ], 60 | "name": "RemovedFundManager", 61 | "type": "event" 62 | }, 63 | { 64 | "anonymous": false, 65 | "inputs": [ 66 | { 67 | "indexed": true, 68 | "internalType": "address", 69 | "name": "_address", 70 | "type": "address" 71 | } 72 | ], 73 | "name": "Whitelisted", 74 | "type": "event" 75 | }, 76 | { 77 | "constant": true, 78 | "inputs": [], 79 | "name": "nexus", 80 | "outputs": [ 81 | { 82 | "internalType": "contract INexus", 83 | "name": "", 84 | "type": "address" 85 | } 86 | ], 87 | "payable": false, 88 | "stateMutability": "view", 89 | "type": "function" 90 | }, 91 | { 92 | "constant": true, 93 | "inputs": [ 94 | { 95 | "internalType": "address", 96 | "name": "", 97 | "type": "address" 98 | } 99 | ], 100 | "name": "whitelist", 101 | "outputs": [ 102 | { 103 | "internalType": "bool", 104 | "name": "", 105 | "type": "bool" 106 | } 107 | ], 108 | "payable": false, 109 | "stateMutability": "view", 110 | "type": "function" 111 | }, 112 | { 113 | "constant": false, 114 | "inputs": [ 115 | { 116 | "internalType": "address", 117 | "name": "_address", 118 | "type": "address" 119 | } 120 | ], 121 | "name": "addFundManager", 122 | "outputs": [], 123 | "payable": false, 124 | "stateMutability": "nonpayable", 125 | "type": "function" 126 | }, 127 | { 128 | "constant": false, 129 | "inputs": [ 130 | { 131 | "internalType": "address", 132 | "name": "_address", 133 | "type": "address" 134 | } 135 | ], 136 | "name": "removeFundManager", 137 | "outputs": [], 138 | "payable": false, 139 | "stateMutability": "nonpayable", 140 | "type": "function" 141 | }, 142 | { 143 | "constant": false, 144 | "inputs": [ 145 | { 146 | "internalType": "contract IRewardsDistributionRecipient[]", 147 | "name": "_recipients", 148 | "type": "address[]" 149 | }, 150 | { 151 | "internalType": "uint256[]", 152 | "name": "_amounts", 153 | "type": "uint256[]" 154 | } 155 | ], 156 | "name": "distributeRewards", 157 | "outputs": [], 158 | "payable": false, 159 | "stateMutability": "nonpayable", 160 | "type": "function" 161 | } 162 | ] 163 | -------------------------------------------------------------------------------- /src/mstable/contracts.ts: -------------------------------------------------------------------------------- 1 | import Masset from "./abi/Masset.json"; 2 | import MetaToken from "./abi/MetaToken.json"; 3 | import MassetValidationHelper from "./abi/MassetValidationHelper.json"; 4 | import ForgeValidator from "./abi/ForgeValidator.json"; 5 | import BasketManager from "./abi/BasketManager.json"; 6 | import AaveIntegration from "./abi/AaveIntegration.json"; 7 | import CompoundIntegration from "./abi/CompoundIntegration.json"; 8 | import Nexus from "./abi/Nexus.json"; 9 | import DelayedProxyAdmin from "./abi/DelayedProxyAdmin.json"; 10 | import SavingsManager from "./abi/SavingsManager.json"; 11 | import SavingsContract from "./abi/SavingsContract.json"; 12 | import RewardsDistributor from "./abi/RewardsDistributor.json"; 13 | import StakingRewardsWithPlatformToken from "./abi/StakingRewardsWithPlatformToken.json"; 14 | 15 | const contracts = { 16 | mUSD: { 17 | symbol: "mUSD", 18 | decimals: 18, 19 | abi: Masset, 20 | address: "0xe2f2a5C287993345a840Db3B0845fbC70f5935a5", 21 | }, 22 | MTA: { 23 | abi: MetaToken, 24 | address: "0xa3bed4e1c75d00fa6f4e5e6922db7261b5e9acd2", 25 | }, 26 | MassetValidationHelper: { 27 | abi: MassetValidationHelper, 28 | address: "0xabcc93c3be238884cc3309c19afd128fafc16911", 29 | }, 30 | ForgeValidator: { 31 | abi: ForgeValidator, 32 | address: "0xbB90D06371030fFa150E463621c22950b212eaa1", 33 | }, 34 | BasketManager: { 35 | abi: BasketManager, 36 | address: "0x66126B4aA2a1C07536Ef8E5e8bD4EfDA1FdEA96D", 37 | }, 38 | AaveIntegration: { 39 | abi: AaveIntegration, 40 | address: "0xf617346a0fb6320e9e578e0c9b2a4588283d9d39", 41 | }, 42 | CompoundIntegration: { 43 | abi: CompoundIntegration, 44 | address: "0xd55684f4369040c12262949ff78299f2bc9db735", 45 | }, 46 | Nexus: { 47 | abi: Nexus, 48 | address: "0xAFcE80b19A8cE13DEc0739a1aaB7A028d6845Eb3", 49 | }, 50 | DelayedProxyAdmin: { 51 | abi: DelayedProxyAdmin, 52 | address: "0x5C8eb57b44C1c6391fC7a8A0cf44d26896f92386", 53 | }, 54 | SavingsManager: { 55 | abi: SavingsManager, 56 | address: "0x7046b0bfc4c5eeb90559c0805dd9c1a6f4815370", 57 | }, 58 | SavingsContract: { 59 | abi: SavingsContract, 60 | address: "0xcf3f73290803fc04425bee135a4caeb2bab2c2a1", 61 | }, 62 | RewardsDistributor: { 63 | abi: RewardsDistributor, 64 | address: "0x04dfdfa471b79cc9e6e8c355e6c71f8ec4916c50", 65 | }, 66 | StakingRewardsWithPlatformToken: { 67 | abi: StakingRewardsWithPlatformToken, 68 | }, 69 | }; 70 | 71 | export default contracts; 72 | -------------------------------------------------------------------------------- /src/mstable/contracts/Masset.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.8.0; 2 | 3 | interface Masset { 4 | 5 | /** 6 | * @dev Mint a single bAsset, at a 1:1 ratio with the bAsset. This contract 7 | * must have approval to spend the senders bAsset 8 | * @param _bAsset Address of the bAsset to mint 9 | * @param _bAssetQuantity Quantity in bAsset units 10 | * @return massetMinted Number of newly minted mAssets 11 | */ 12 | function mint(address _bAsset, uint256 _bAssetQuantity) external returns (uint256 massetMinted); 13 | 14 | 15 | /** 16 | * @dev Mint a single bAsset, at a 1:1 ratio with the bAsset. This contract 17 | * must have approval to spend the senders bAsset 18 | * @param _bAsset Address of the bAsset to mint 19 | * @param _bAssetQuantity Quantity in bAsset units 20 | * @param _recipient receipient of the newly minted mAsset tokens 21 | * @return massetMinted Number of newly minted mAssets 22 | */ 23 | function mintTo(address _bAsset, uint256 _bAssetQuantity, address _recipient) external returns (uint256 massetMinted); 24 | 25 | 26 | /** 27 | * @dev Mint with multiple bAssets, at a 1:1 ratio to mAsset. This contract 28 | * must have approval to spend the senders bAssets 29 | * @param _bAssets Non-duplicate address array of bAssets with which to mint 30 | * @param _bAssetQuantity Quantity of each bAsset to mint. Order of array 31 | * should mirror the above 32 | * @param _recipient Address to receive the newly minted mAsset tokens 33 | * @return massetMinted Number of newly minted mAssets 34 | */ 35 | function mintMulti(address[] calldata _bAssets, uint256[] calldata _bAssetQuantity, address _recipient) external returns(uint256 massetMinted); 36 | 37 | 38 | /** 39 | * @dev Simply swaps one bAsset for another bAsset or this mAsset at a 1:1 ratio. 40 | * bAsset <> bAsset swaps will incur a small fee (swapFee()). Swap 41 | * is valid if it does not result in the input asset exceeding its maximum weight. 42 | * @param _input bAsset to deposit 43 | * @param _output Asset to receive - either a bAsset or mAsset(this) 44 | * @param _quantity Units of input bAsset to swap 45 | * @param _recipient Address to credit output asset 46 | * @return output Units of output asset returned 47 | */ 48 | function swap(address _input, address _output, uint256 _quantity, address _recipient) external returns (uint256 output); 49 | 50 | 51 | 52 | /** 53 | * @dev Determines both if a trade is valid, and the expected fee or output. 54 | * Swap is valid if it does not result in the input asset exceeding its maximum weight. 55 | * @param _input bAsset to deposit 56 | * @param _output Asset to receive - bAsset or mAsset(this) 57 | * @param _quantity Units of input bAsset to swap 58 | * @return valid Bool to signify that swap is current valid 59 | * @return reason If swap is invalid, this is the reason 60 | * @return output Units of _output asset the trade would return 61 | */ 62 | function getSwapOutput(address _input, address _output, uint256 _quantity) external view returns (bool, string memory, uint256 output); 63 | 64 | 65 | /** 66 | * @dev Credits the sender with a certain quantity of selected bAsset, in exchange for burning the 67 | * relative mAsset quantity from the sender. Sender also incurs a small mAsset fee, if any. 68 | * @param _bAsset Address of the bAsset to redeem 69 | * @param _bAssetQuantity Units of the bAsset to redeem 70 | * @return massetMinted Relative number of mAsset units burned to pay for the bAssets 71 | */ 72 | function redeem(address _bAsset, uint256 _bAssetQuantity) external returns (uint256 massetRedeemed); 73 | 74 | 75 | /** 76 | * @dev Credits a recipient with a certain quantity of selected bAsset, in exchange for burning the 77 | * relative Masset quantity from the sender. Sender also incurs a small fee, if any. 78 | * @param _bAsset Address of the bAsset to redeem 79 | * @param _bAssetQuantity Units of the bAsset to redeem 80 | * @param _recipient Address to credit with withdrawn bAssets 81 | * @return massetMinted Relative number of mAsset units burned to pay for the bAssets 82 | */ 83 | function redeemTo(address _bAsset, uint256 _bAssetQuantity, address _recipient) external returns (uint256 massetRedeemed); 84 | 85 | 86 | 87 | /** 88 | * @dev Credits a recipient with a proportionate amount of bAssets, relative to current vault 89 | * balance levels and desired mAsset quantity. Burns the mAsset as payment. 90 | * @param _mAssetQuantity Quantity of mAsset to redeem 91 | * @param _recipient Address to credit the withdrawn bAssets 92 | */ 93 | function redeemMasset(uint256 _mAssetQuantity, address _recipient) external; 94 | } -------------------------------------------------------------------------------- /src/mstable/contracts/StakingRewardsWithPlatformToken.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.8.0; 2 | 3 | import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 4 | 5 | interface StakingRewardsWithPlatformToken { 6 | 7 | /** 8 | * @dev Stakes a given amount of the StakingToken for the sender 9 | * @param _amount Units of StakingToken 10 | */ 11 | function stake(uint256 _amount) external; 12 | 13 | 14 | /** 15 | * @dev Stakes a given amount of the StakingToken for a given beneficiary 16 | * @param _beneficiary Staked tokens are credited to this address 17 | * @param _amount Units of StakingToken 18 | */ 19 | function stake(address _beneficiary, uint256 _amount) external; 20 | 21 | 22 | /** 23 | * @dev Withdraws stake from pool and claims any rewards 24 | */ 25 | function exit() external; 26 | 27 | 28 | /** 29 | * @dev Withdraws given stake amount from the pool 30 | * @param _amount Units of the staked token to withdraw 31 | */ 32 | function withdraw(uint256 _amount) external; 33 | 34 | 35 | /** 36 | * @dev Claims outstanding rewards (both platform and native) for the sender. 37 | * First updates outstanding reward allocation and then transfers. 38 | */ 39 | function claimReward() external; 40 | 41 | 42 | /** 43 | * @dev Claims outstanding rewards for the sender. Only the native 44 | * rewards token, and not the platform rewards 45 | */ 46 | function claimRewardOnly() external; 47 | 48 | 49 | /** 50 | * @dev Gets the RewardsToken 51 | */ 52 | function getRewardToken() external view returns (IERC20); 53 | 54 | 55 | /** 56 | * @dev Gets the last applicable timestamp for this reward period 57 | */ 58 | function lastTimeRewardApplicable() external view returns (uint256); 59 | 60 | 61 | /** 62 | * @dev Calculates the amount of unclaimed rewards a user has earned 63 | * @return 'Reward' per staked token 64 | */ 65 | function rewardPerToken() external view returns (uint256, uint256); 66 | 67 | 68 | /** 69 | * @dev Calculates the amount of unclaimed rewards a user has earned 70 | * @param _account User address 71 | * @return Total reward amount earned 72 | */ 73 | function earned(address _account) external view returns (uint256, uint256); 74 | } -------------------------------------------------------------------------------- /src/mstable/index.ts: -------------------------------------------------------------------------------- 1 | import { default as contracts } from "./contracts"; 2 | 3 | export = { 4 | ...contracts, 5 | }; 6 | -------------------------------------------------------------------------------- /src/onesplit/contracts.ts: -------------------------------------------------------------------------------- 1 | import oneSplitAbi from "./abi/OneSplit.json"; 2 | 3 | const contracts = { 4 | address: "0xC586BeF4a0992C495Cf22e1aeEE4E446CECDee0E", // Alternatively 1split.eth 5 | abi: oneSplitAbi, 6 | }; 7 | 8 | export default contracts; 9 | -------------------------------------------------------------------------------- /src/onesplit/contracts/IOneSplit.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.8.0; 2 | 3 | import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 4 | 5 | 6 | contract IOneSplitConsts { 7 | // disableFlags = FLAG_DISABLE_UNISWAP + FLAG_DISABLE_KYBER + ... 8 | uint256 public constant FLAG_DISABLE_UNISWAP = 0x01; 9 | uint256 public constant FLAG_DISABLE_KYBER = 0x02; 10 | uint256 public constant FLAG_ENABLE_KYBER_UNISWAP_RESERVE = 0x100000000; // Turned off by default 11 | uint256 public constant FLAG_ENABLE_KYBER_OASIS_RESERVE = 0x200000000; // Turned off by default 12 | uint256 public constant FLAG_ENABLE_KYBER_BANCOR_RESERVE = 0x400000000; // Turned off by default 13 | uint256 public constant FLAG_DISABLE_BANCOR = 0x04; 14 | uint256 public constant FLAG_DISABLE_OASIS = 0x08; 15 | uint256 public constant FLAG_DISABLE_COMPOUND = 0x10; 16 | uint256 public constant FLAG_DISABLE_FULCRUM = 0x20; 17 | uint256 public constant FLAG_DISABLE_CHAI = 0x40; 18 | uint256 public constant FLAG_DISABLE_AAVE = 0x80; 19 | uint256 public constant FLAG_DISABLE_SMART_TOKEN = 0x100; 20 | uint256 public constant FLAG_ENABLE_MULTI_PATH_ETH = 0x200; // Turned off by default 21 | uint256 public constant FLAG_DISABLE_BDAI = 0x400; 22 | uint256 public constant FLAG_DISABLE_IEARN = 0x800; 23 | uint256 public constant FLAG_DISABLE_CURVE_COMPOUND = 0x1000; 24 | uint256 public constant FLAG_DISABLE_CURVE_USDT = 0x2000; 25 | uint256 public constant FLAG_DISABLE_CURVE_Y = 0x4000; 26 | uint256 public constant FLAG_DISABLE_CURVE_BINANCE = 0x8000; 27 | uint256 public constant FLAG_ENABLE_MULTI_PATH_DAI = 0x10000; // Turned off by default 28 | uint256 public constant FLAG_ENABLE_MULTI_PATH_USDC = 0x20000; // Turned off by default 29 | uint256 public constant FLAG_DISABLE_CURVE_SYNTHETIX = 0x40000; 30 | uint256 public constant FLAG_DISABLE_WETH = 0x80000; 31 | uint256 public constant FLAG_ENABLE_UNISWAP_COMPOUND = 0x100000; // Works only when one of assets is ETH or FLAG_ENABLE_MULTI_PATH_ETH 32 | uint256 public constant FLAG_ENABLE_UNISWAP_CHAI = 0x200000; // Works only when ETH<>DAI or FLAG_ENABLE_MULTI_PATH_ETH 33 | uint256 public constant FLAG_ENABLE_UNISWAP_AAVE = 0x400000; // Works only when one of assets is ETH or FLAG_ENABLE_MULTI_PATH_ETH 34 | uint256 public constant FLAG_DISABLE_IDLE = 0x800000; 35 | } 36 | 37 | 38 | contract IOneSplit is IOneSplitConsts { 39 | function getExpectedReturn( 40 | IERC20 fromToken, 41 | IERC20 toToken, 42 | uint256 amount, 43 | uint256 parts, 44 | uint256 disableFlags 45 | ) 46 | public 47 | view 48 | returns( 49 | uint256 returnAmount, 50 | uint256[] memory distribution 51 | ); 52 | 53 | function swap( 54 | IERC20 fromToken, 55 | IERC20 toToken, 56 | uint256 amount, 57 | uint256 minReturn, 58 | uint256[] memory distribution, 59 | uint256 disableFlags 60 | ) public payable; 61 | } 62 | -------------------------------------------------------------------------------- /src/onesplit/index.ts: -------------------------------------------------------------------------------- 1 | import { default as contracts } from "./contracts"; 2 | 3 | export = { 4 | ...contracts, 5 | }; 6 | -------------------------------------------------------------------------------- /src/synthetix/contracts/IDepot.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.4.24; 2 | 3 | 4 | interface IDepot { 5 | // Views 6 | function fundsWallet() external view returns (address payable); 7 | 8 | function maxEthPurchase() external view returns (uint); 9 | 10 | function minimumDepositAmount() external view returns (uint); 11 | 12 | function synthsReceivedForEther(uint amount) external view returns (uint); 13 | 14 | function totalSellableDeposits() external view returns (uint); 15 | 16 | // Mutative functions 17 | function depositSynths(uint amount) external; 18 | 19 | function exchangeEtherForSynths() external payable returns (uint); 20 | 21 | function exchangeEtherForSynthsAtRate(uint guaranteedRate) external payable returns (uint); 22 | 23 | function withdrawMyDepositedSynths() external; 24 | 25 | // Note: On mainnet no SNX has been deposited. The following functions are kept alive for testnet SNX faucets. 26 | function exchangeEtherForSNX() external payable returns (uint); 27 | 28 | function exchangeEtherForSNXAtRate(uint guaranteedRate, uint guaranteedSynthetixRate) external payable returns (uint); 29 | 30 | function exchangeSynthsForSNX(uint synthAmount) external returns (uint); 31 | 32 | function exchangeSynthsForSNXAtRate(uint synthAmount, uint guaranteedRate) external returns (uint); 33 | } -------------------------------------------------------------------------------- /src/synthetix/contracts/ISynth.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.4.24; 2 | 3 | 4 | interface ISynth { 5 | // Views 6 | function currencyKey() external view returns (bytes32); 7 | 8 | function transferableSynths(address account) external view returns (uint); 9 | 10 | // Mutative functions 11 | function transferAndSettle(address to, uint value) external returns (bool); 12 | 13 | function transferFromAndSettle( 14 | address from, 15 | address to, 16 | uint value 17 | ) external returns (bool); 18 | 19 | // Restricted: used internally to Synthetix 20 | function burn(address account, uint amount) external; 21 | 22 | function issue(address account, uint amount) external; 23 | } -------------------------------------------------------------------------------- /src/synthetix/contracts/ISynthetix.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.4.24; 2 | 3 | import "./ISynth.sol"; 4 | 5 | 6 | interface ISynthetix { 7 | // Views 8 | function availableCurrencyKeys() external view returns (bytes32[] memory); 9 | 10 | function availableSynthCount() external view returns (uint); 11 | 12 | function collateral(address account) external view returns (uint); 13 | 14 | function collateralisationRatio(address issuer) external view returns (uint); 15 | 16 | function debtBalanceOf(address issuer, bytes32 currencyKey) external view returns (uint); 17 | 18 | function debtBalanceOfAndTotalDebt(address issuer, bytes32 currencyKey) 19 | external 20 | view 21 | returns (uint debtBalance, uint totalSystemValue); 22 | 23 | function isWaitingPeriod(bytes32 currencyKey) external view returns (bool); 24 | 25 | function maxIssuableSynths(address issuer) external view returns (uint maxIssuable); 26 | 27 | function remainingIssuableSynths(address issuer) 28 | external 29 | view 30 | returns ( 31 | uint maxIssuable, 32 | uint alreadyIssued, 33 | uint totalSystemDebt 34 | ); 35 | 36 | function synths(bytes32 currencyKey) external view returns (ISynth); 37 | 38 | function synthsByAddress(address synthAddress) external view returns (bytes32); 39 | 40 | function totalIssuedSynths(bytes32 currencyKey) external view returns (uint); 41 | 42 | function totalIssuedSynthsExcludeEtherCollateral(bytes32 currencyKey) external view returns (uint); 43 | 44 | function transferableSynthetix(address account) external view returns (uint); 45 | 46 | // Mutative Functions 47 | function burnSynths(uint amount) external; 48 | 49 | function burnSynthsOnBehalf(address burnForAddress, uint amount) external; 50 | 51 | function burnSynthsToTarget() external; 52 | 53 | function burnSynthsToTargetOnBehalf(address burnForAddress) external; 54 | 55 | function exchange( 56 | bytes32 sourceCurrencyKey, 57 | uint sourceAmount, 58 | bytes32 destinationCurrencyKey 59 | ) external returns (uint amountReceived); 60 | 61 | function exchangeOnBehalf( 62 | address exchangeForAddress, 63 | bytes32 sourceCurrencyKey, 64 | uint sourceAmount, 65 | bytes32 destinationCurrencyKey 66 | ) external returns (uint amountReceived); 67 | 68 | function issueMaxSynths() external; 69 | 70 | function issueMaxSynthsOnBehalf(address issueForAddress) external; 71 | 72 | function issueSynths(uint amount) external; 73 | 74 | function issueSynthsOnBehalf(address issueForAddress, uint amount) external; 75 | 76 | function mint() external returns (bool); 77 | 78 | function settle(bytes32 currencyKey) 79 | external 80 | returns ( 81 | uint reclaimed, 82 | uint refunded, 83 | uint numEntries 84 | ); 85 | 86 | function liquidateDelinquentAccount(address account, uint susdAmount) external returns (bool); 87 | } -------------------------------------------------------------------------------- /src/synthetix/index.ts: -------------------------------------------------------------------------------- 1 | import { default as contracts } from "./contracts"; 2 | 3 | export = { 4 | ...contracts, 5 | }; 6 | -------------------------------------------------------------------------------- /src/uma/abi/AddressWhitelist.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "anonymous": false, 4 | "inputs": [ 5 | { 6 | "indexed": true, 7 | "internalType": "address", 8 | "name": "addedAddress", 9 | "type": "address" 10 | } 11 | ], 12 | "name": "AddedToWhitelist", 13 | "type": "event" 14 | }, 15 | { 16 | "anonymous": false, 17 | "inputs": [ 18 | { 19 | "indexed": true, 20 | "internalType": "address", 21 | "name": "previousOwner", 22 | "type": "address" 23 | }, 24 | { 25 | "indexed": true, 26 | "internalType": "address", 27 | "name": "newOwner", 28 | "type": "address" 29 | } 30 | ], 31 | "name": "OwnershipTransferred", 32 | "type": "event" 33 | }, 34 | { 35 | "anonymous": false, 36 | "inputs": [ 37 | { 38 | "indexed": true, 39 | "internalType": "address", 40 | "name": "removedAddress", 41 | "type": "address" 42 | } 43 | ], 44 | "name": "RemovedFromWhitelist", 45 | "type": "event" 46 | }, 47 | { 48 | "inputs": [], 49 | "name": "owner", 50 | "outputs": [ 51 | { 52 | "internalType": "address", 53 | "name": "", 54 | "type": "address" 55 | } 56 | ], 57 | "stateMutability": "view", 58 | "type": "function", 59 | "constant": true 60 | }, 61 | { 62 | "inputs": [], 63 | "name": "renounceOwnership", 64 | "outputs": [], 65 | "stateMutability": "nonpayable", 66 | "type": "function" 67 | }, 68 | { 69 | "inputs": [ 70 | { 71 | "internalType": "address", 72 | "name": "newOwner", 73 | "type": "address" 74 | } 75 | ], 76 | "name": "transferOwnership", 77 | "outputs": [], 78 | "stateMutability": "nonpayable", 79 | "type": "function" 80 | }, 81 | { 82 | "inputs": [ 83 | { 84 | "internalType": "address", 85 | "name": "", 86 | "type": "address" 87 | } 88 | ], 89 | "name": "whitelist", 90 | "outputs": [ 91 | { 92 | "internalType": "enum AddressWhitelist.Status", 93 | "name": "", 94 | "type": "uint8" 95 | } 96 | ], 97 | "stateMutability": "view", 98 | "type": "function", 99 | "constant": true 100 | }, 101 | { 102 | "inputs": [ 103 | { 104 | "internalType": "uint256", 105 | "name": "", 106 | "type": "uint256" 107 | } 108 | ], 109 | "name": "whitelistIndices", 110 | "outputs": [ 111 | { 112 | "internalType": "address", 113 | "name": "", 114 | "type": "address" 115 | } 116 | ], 117 | "stateMutability": "view", 118 | "type": "function", 119 | "constant": true 120 | }, 121 | { 122 | "inputs": [ 123 | { 124 | "internalType": "address", 125 | "name": "newElement", 126 | "type": "address" 127 | } 128 | ], 129 | "name": "addToWhitelist", 130 | "outputs": [], 131 | "stateMutability": "nonpayable", 132 | "type": "function" 133 | }, 134 | { 135 | "inputs": [ 136 | { 137 | "internalType": "address", 138 | "name": "elementToRemove", 139 | "type": "address" 140 | } 141 | ], 142 | "name": "removeFromWhitelist", 143 | "outputs": [], 144 | "stateMutability": "nonpayable", 145 | "type": "function" 146 | }, 147 | { 148 | "inputs": [ 149 | { 150 | "internalType": "address", 151 | "name": "elementToCheck", 152 | "type": "address" 153 | } 154 | ], 155 | "name": "isOnWhitelist", 156 | "outputs": [ 157 | { 158 | "internalType": "bool", 159 | "name": "", 160 | "type": "bool" 161 | } 162 | ], 163 | "stateMutability": "view", 164 | "type": "function", 165 | "constant": true 166 | }, 167 | { 168 | "inputs": [], 169 | "name": "getWhitelist", 170 | "outputs": [ 171 | { 172 | "internalType": "address[]", 173 | "name": "activeWhitelist", 174 | "type": "address[]" 175 | } 176 | ], 177 | "stateMutability": "view", 178 | "type": "function", 179 | "constant": true 180 | } 181 | ] -------------------------------------------------------------------------------- /src/uma/abi/ExpiringMultiPartyLib.json: -------------------------------------------------------------------------------- 1 | [] -------------------------------------------------------------------------------- /src/uma/abi/FinancialContractsAdmin.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "anonymous": false, 4 | "inputs": [ 5 | { 6 | "indexed": true, 7 | "internalType": "address", 8 | "name": "previousOwner", 9 | "type": "address" 10 | }, 11 | { 12 | "indexed": true, 13 | "internalType": "address", 14 | "name": "newOwner", 15 | "type": "address" 16 | } 17 | ], 18 | "name": "OwnershipTransferred", 19 | "type": "event" 20 | }, 21 | { 22 | "inputs": [], 23 | "name": "owner", 24 | "outputs": [ 25 | { 26 | "internalType": "address", 27 | "name": "", 28 | "type": "address" 29 | } 30 | ], 31 | "stateMutability": "view", 32 | "type": "function", 33 | "constant": true 34 | }, 35 | { 36 | "inputs": [], 37 | "name": "renounceOwnership", 38 | "outputs": [], 39 | "stateMutability": "nonpayable", 40 | "type": "function" 41 | }, 42 | { 43 | "inputs": [ 44 | { 45 | "internalType": "address", 46 | "name": "newOwner", 47 | "type": "address" 48 | } 49 | ], 50 | "name": "transferOwnership", 51 | "outputs": [], 52 | "stateMutability": "nonpayable", 53 | "type": "function" 54 | }, 55 | { 56 | "inputs": [ 57 | { 58 | "internalType": "address", 59 | "name": "financialContract", 60 | "type": "address" 61 | } 62 | ], 63 | "name": "callEmergencyShutdown", 64 | "outputs": [], 65 | "stateMutability": "nonpayable", 66 | "type": "function" 67 | }, 68 | { 69 | "inputs": [ 70 | { 71 | "internalType": "address", 72 | "name": "financialContract", 73 | "type": "address" 74 | } 75 | ], 76 | "name": "callRemargin", 77 | "outputs": [], 78 | "stateMutability": "nonpayable", 79 | "type": "function" 80 | } 81 | ] -------------------------------------------------------------------------------- /src/uma/abi/Finder.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "anonymous": false, 4 | "inputs": [ 5 | { 6 | "indexed": true, 7 | "internalType": "bytes32", 8 | "name": "interfaceName", 9 | "type": "bytes32" 10 | }, 11 | { 12 | "indexed": true, 13 | "internalType": "address", 14 | "name": "newImplementationAddress", 15 | "type": "address" 16 | } 17 | ], 18 | "name": "InterfaceImplementationChanged", 19 | "type": "event" 20 | }, 21 | { 22 | "anonymous": false, 23 | "inputs": [ 24 | { 25 | "indexed": true, 26 | "internalType": "address", 27 | "name": "previousOwner", 28 | "type": "address" 29 | }, 30 | { 31 | "indexed": true, 32 | "internalType": "address", 33 | "name": "newOwner", 34 | "type": "address" 35 | } 36 | ], 37 | "name": "OwnershipTransferred", 38 | "type": "event" 39 | }, 40 | { 41 | "inputs": [ 42 | { 43 | "internalType": "bytes32", 44 | "name": "", 45 | "type": "bytes32" 46 | } 47 | ], 48 | "name": "interfacesImplemented", 49 | "outputs": [ 50 | { 51 | "internalType": "address", 52 | "name": "", 53 | "type": "address" 54 | } 55 | ], 56 | "stateMutability": "view", 57 | "type": "function", 58 | "constant": true 59 | }, 60 | { 61 | "inputs": [], 62 | "name": "owner", 63 | "outputs": [ 64 | { 65 | "internalType": "address", 66 | "name": "", 67 | "type": "address" 68 | } 69 | ], 70 | "stateMutability": "view", 71 | "type": "function", 72 | "constant": true 73 | }, 74 | { 75 | "inputs": [], 76 | "name": "renounceOwnership", 77 | "outputs": [], 78 | "stateMutability": "nonpayable", 79 | "type": "function" 80 | }, 81 | { 82 | "inputs": [ 83 | { 84 | "internalType": "address", 85 | "name": "newOwner", 86 | "type": "address" 87 | } 88 | ], 89 | "name": "transferOwnership", 90 | "outputs": [], 91 | "stateMutability": "nonpayable", 92 | "type": "function" 93 | }, 94 | { 95 | "inputs": [ 96 | { 97 | "internalType": "bytes32", 98 | "name": "interfaceName", 99 | "type": "bytes32" 100 | }, 101 | { 102 | "internalType": "address", 103 | "name": "implementationAddress", 104 | "type": "address" 105 | } 106 | ], 107 | "name": "changeImplementationAddress", 108 | "outputs": [], 109 | "stateMutability": "nonpayable", 110 | "type": "function" 111 | }, 112 | { 113 | "inputs": [ 114 | { 115 | "internalType": "bytes32", 116 | "name": "interfaceName", 117 | "type": "bytes32" 118 | } 119 | ], 120 | "name": "getImplementationAddress", 121 | "outputs": [ 122 | { 123 | "internalType": "address", 124 | "name": "", 125 | "type": "address" 126 | } 127 | ], 128 | "stateMutability": "view", 129 | "type": "function", 130 | "constant": true 131 | } 132 | ] -------------------------------------------------------------------------------- /src/uma/abi/IdentifierWhitelist.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "anonymous": false, 4 | "inputs": [ 5 | { 6 | "indexed": true, 7 | "internalType": "address", 8 | "name": "previousOwner", 9 | "type": "address" 10 | }, 11 | { 12 | "indexed": true, 13 | "internalType": "address", 14 | "name": "newOwner", 15 | "type": "address" 16 | } 17 | ], 18 | "name": "OwnershipTransferred", 19 | "type": "event" 20 | }, 21 | { 22 | "anonymous": false, 23 | "inputs": [ 24 | { 25 | "indexed": true, 26 | "internalType": "bytes32", 27 | "name": "identifier", 28 | "type": "bytes32" 29 | } 30 | ], 31 | "name": "SupportedIdentifierAdded", 32 | "type": "event" 33 | }, 34 | { 35 | "anonymous": false, 36 | "inputs": [ 37 | { 38 | "indexed": true, 39 | "internalType": "bytes32", 40 | "name": "identifier", 41 | "type": "bytes32" 42 | } 43 | ], 44 | "name": "SupportedIdentifierRemoved", 45 | "type": "event" 46 | }, 47 | { 48 | "inputs": [], 49 | "name": "owner", 50 | "outputs": [ 51 | { 52 | "internalType": "address", 53 | "name": "", 54 | "type": "address" 55 | } 56 | ], 57 | "stateMutability": "view", 58 | "type": "function", 59 | "constant": true 60 | }, 61 | { 62 | "inputs": [], 63 | "name": "renounceOwnership", 64 | "outputs": [], 65 | "stateMutability": "nonpayable", 66 | "type": "function" 67 | }, 68 | { 69 | "inputs": [ 70 | { 71 | "internalType": "address", 72 | "name": "newOwner", 73 | "type": "address" 74 | } 75 | ], 76 | "name": "transferOwnership", 77 | "outputs": [], 78 | "stateMutability": "nonpayable", 79 | "type": "function" 80 | }, 81 | { 82 | "inputs": [ 83 | { 84 | "internalType": "bytes32", 85 | "name": "identifier", 86 | "type": "bytes32" 87 | } 88 | ], 89 | "name": "addSupportedIdentifier", 90 | "outputs": [], 91 | "stateMutability": "nonpayable", 92 | "type": "function" 93 | }, 94 | { 95 | "inputs": [ 96 | { 97 | "internalType": "bytes32", 98 | "name": "identifier", 99 | "type": "bytes32" 100 | } 101 | ], 102 | "name": "removeSupportedIdentifier", 103 | "outputs": [], 104 | "stateMutability": "nonpayable", 105 | "type": "function" 106 | }, 107 | { 108 | "inputs": [ 109 | { 110 | "internalType": "bytes32", 111 | "name": "identifier", 112 | "type": "bytes32" 113 | } 114 | ], 115 | "name": "isIdentifierSupported", 116 | "outputs": [ 117 | { 118 | "internalType": "bool", 119 | "name": "", 120 | "type": "bool" 121 | } 122 | ], 123 | "stateMutability": "view", 124 | "type": "function", 125 | "constant": true 126 | } 127 | ] -------------------------------------------------------------------------------- /src/uma/abi/TokenFactory.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "string", 6 | "name": "tokenName", 7 | "type": "string" 8 | }, 9 | { 10 | "internalType": "string", 11 | "name": "tokenSymbol", 12 | "type": "string" 13 | }, 14 | { 15 | "internalType": "uint8", 16 | "name": "tokenDecimals", 17 | "type": "uint8" 18 | } 19 | ], 20 | "name": "createToken", 21 | "outputs": [ 22 | { 23 | "internalType": "contract ExpandedIERC20", 24 | "name": "newToken", 25 | "type": "address" 26 | } 27 | ], 28 | "stateMutability": "nonpayable", 29 | "type": "function" 30 | } 31 | ] -------------------------------------------------------------------------------- /src/uma/contracts.ts: -------------------------------------------------------------------------------- 1 | import addressWhitelistAbi from "./abi/AddressWhitelist.json"; 2 | import designatedVotingFactoryAbi from "./abi/DesignatedVotingFactory.json"; 3 | import expiringMultiPartyAbi from "./abi/ExpiringMultiParty.json"; 4 | import expiringMultiPartyCreatorAbi from "./abi/ExpiringMultiPartyCreator.json"; 5 | import financialContractsAdminAbi from "./abi/FinancialContractsAdmin.json"; 6 | import finderAbi from "./abi/Finder.json"; 7 | import governorAbi from "./abi/Governor.json"; 8 | import identifierWhitelistAbi from "./abi/IdentifierWhitelist.json"; 9 | import registryAbi from "./abi/Registry.json"; 10 | import storeAbi from "./abi/Store.json"; 11 | import tokenFactoryAbi from "./abi/TokenFactory.json"; 12 | import votingAbi from "./abi/Voting.json"; 13 | import votingTokenAbi from "./abi/VotingToken.json"; 14 | import weth9Abi from "./abi/WETH9.json"; 15 | 16 | const contracts = { 17 | addressWhitelist: { 18 | abi: addressWhitelistAbi, 19 | address: "0xdBF90434dF0B98219f87d112F37d74B1D90758c7", 20 | }, 21 | designatedVotingFactory: { 22 | abi: designatedVotingFactoryAbi, 23 | address: "0xE81EeE5Da165fA6863bBc82dF66E62d18625d592", 24 | }, 25 | expiringMultiParty: { 26 | abi: expiringMultiPartyAbi, 27 | }, 28 | expiringMultiPartyLib: { 29 | abi: [], 30 | address: "0xCb08678e4381Be3E264E6A0037E3297Ca56a583e", 31 | }, 32 | expiringMultiPartyCreator: { 33 | abi: expiringMultiPartyCreatorAbi, 34 | address: "0xad8fD1f418FB860A383c9D4647880af7f043Ef39", 35 | }, 36 | financialContractsAdmin: { 37 | abi: financialContractsAdminAbi, 38 | address: "0x4E6CCB1dA3C7844887F9A5aF4e8450d9fd90317A", 39 | }, 40 | finder: { 41 | abi: finderAbi, 42 | address: "0x40f941E48A552bF496B154Af6bf55725f18D77c3", 43 | }, 44 | governor: { 45 | abi: governorAbi, 46 | address: "0x592349F7DeDB2b75f9d4F194d4b7C16D82E507Dc", 47 | }, 48 | identifierWhitelist: { 49 | abi: identifierWhitelistAbi, 50 | address: "0xcF649d9Da4D1362C4DAEa67573430Bd6f945e570", 51 | }, 52 | registry: { 53 | abi: registryAbi, 54 | address: "0x3e532e6222afe9Bcf02DCB87216802c75D5113aE", 55 | }, 56 | store: { 57 | abi: storeAbi, 58 | address: "0x54f44eA3D2e7aA0ac089c4d8F7C93C27844057BF", 59 | }, 60 | tokenFactory: { 61 | abi: tokenFactoryAbi, 62 | address: "0x7c96d6235CfaaCcAc5d80fCe74E6032B25dd1F03", 63 | }, 64 | voting: { 65 | abi: votingAbi, 66 | address: "0x9921810C710E7c3f7A7C6831e30929f19537a545", 67 | }, 68 | votingToken: { 69 | abi: votingTokenAbi, 70 | address: "0x04Fa0d235C4abf4BcF4787aF4CF447DE572eF828", 71 | }, 72 | weth9: { 73 | abi: weth9Abi, 74 | address: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", 75 | }, 76 | }; 77 | 78 | export default contracts; 79 | -------------------------------------------------------------------------------- /src/uma/index.ts: -------------------------------------------------------------------------------- 1 | import { default as contracts } from "./contracts"; 2 | 3 | export = { 4 | ...contracts, 5 | }; 6 | -------------------------------------------------------------------------------- /src/uniswap/abi/Factory.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "NewExchange", 4 | "inputs": [ 5 | { 6 | "type": "address", 7 | "name": "token", 8 | "indexed": true 9 | }, 10 | { 11 | "type": "address", 12 | "name": "exchange", 13 | "indexed": true 14 | } 15 | ], 16 | "anonymous": false, 17 | "type": "event" 18 | }, 19 | { 20 | "name": "initializeFactory", 21 | "outputs": [], 22 | "inputs": [ 23 | { 24 | "type": "address", 25 | "name": "template" 26 | } 27 | ], 28 | "constant": false, 29 | "payable": false, 30 | "type": "function", 31 | "gas": 35725 32 | }, 33 | { 34 | "name": "createExchange", 35 | "outputs": [ 36 | { 37 | "type": "address", 38 | "name": "out" 39 | } 40 | ], 41 | "inputs": [ 42 | { 43 | "type": "address", 44 | "name": "token" 45 | } 46 | ], 47 | "constant": false, 48 | "payable": false, 49 | "type": "function", 50 | "gas": 187911 51 | }, 52 | { 53 | "name": "getExchange", 54 | "outputs": [ 55 | { 56 | "type": "address", 57 | "name": "out" 58 | } 59 | ], 60 | "inputs": [ 61 | { 62 | "type": "address", 63 | "name": "token" 64 | } 65 | ], 66 | "constant": true, 67 | "payable": false, 68 | "type": "function", 69 | "gas": 715 70 | }, 71 | { 72 | "name": "getToken", 73 | "outputs": [ 74 | { 75 | "type": "address", 76 | "name": "out" 77 | } 78 | ], 79 | "inputs": [ 80 | { 81 | "type": "address", 82 | "name": "exchange" 83 | } 84 | ], 85 | "constant": true, 86 | "payable": false, 87 | "type": "function", 88 | "gas": 745 89 | }, 90 | { 91 | "name": "getTokenWithId", 92 | "outputs": [ 93 | { 94 | "type": "address", 95 | "name": "out" 96 | } 97 | ], 98 | "inputs": [ 99 | { 100 | "type": "uint256", 101 | "name": "token_id" 102 | } 103 | ], 104 | "constant": true, 105 | "payable": false, 106 | "type": "function", 107 | "gas": 736 108 | }, 109 | { 110 | "name": "exchangeTemplate", 111 | "outputs": [ 112 | { 113 | "type": "address", 114 | "name": "out" 115 | } 116 | ], 117 | "inputs": [], 118 | "constant": true, 119 | "payable": false, 120 | "type": "function", 121 | "gas": 633 122 | }, 123 | { 124 | "name": "tokenCount", 125 | "outputs": [ 126 | { 127 | "type": "uint256", 128 | "name": "out" 129 | } 130 | ], 131 | "inputs": [], 132 | "constant": true, 133 | "payable": false, 134 | "type": "function", 135 | "gas": 663 136 | } 137 | ] -------------------------------------------------------------------------------- /src/uniswap/contracts.ts: -------------------------------------------------------------------------------- 1 | import exchangeAbi from "./abi/Exchange.json"; 2 | import factoryAbi from "./abi/Factory.json"; 3 | 4 | const contracts = { 5 | factory: { 6 | address: "0xc0a47dFe034B400B47bDaD5FecDa2621de6c4d95", 7 | abi: factoryAbi, 8 | }, 9 | exchange: { 10 | abi: exchangeAbi, 11 | }, 12 | }; 13 | 14 | export default contracts; 15 | -------------------------------------------------------------------------------- /src/uniswap/contracts/IUniswapExchange.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.8.0; 2 | 3 | interface IUniswapExchange { 4 | // Address of ERC20 token sold on this exchange 5 | function tokenAddress() external view returns (address token); 6 | // Address of Uniswap Factory 7 | function factoryAddress() external view returns (address factory); 8 | // Provide Liquidity 9 | function addLiquidity(uint256 min_liquidity, uint256 max_tokens, uint256 deadline) external payable returns (uint256); 10 | function removeLiquidity(uint256 amount, uint256 min_eth, uint256 min_tokens, uint256 deadline) external returns (uint256, uint256); 11 | // Get Prices 12 | function getEthToTokenInputPrice(uint256 eth_sold) external view returns (uint256 tokens_bought); 13 | function getEthToTokenOutputPrice(uint256 tokens_bought) external view returns (uint256 eth_sold); 14 | function getTokenToEthInputPrice(uint256 tokens_sold) external view returns (uint256 eth_bought); 15 | function getTokenToEthOutputPrice(uint256 eth_bought) external view returns (uint256 tokens_sold); 16 | // Trade ETH to ERC20 17 | function ethToTokenSwapInput(uint256 min_tokens, uint256 deadline) external payable returns (uint256 tokens_bought); 18 | function ethToTokenTransferInput(uint256 min_tokens, uint256 deadline, address recipient) external payable returns (uint256 tokens_bought); 19 | function ethToTokenSwapOutput(uint256 tokens_bought, uint256 deadline) external payable returns (uint256 eth_sold); 20 | function ethToTokenTransferOutput(uint256 tokens_bought, uint256 deadline, address recipient) external payable returns (uint256 eth_sold); 21 | // Trade ERC20 to ETH 22 | function tokenToEthSwapInput(uint256 tokens_sold, uint256 min_eth, uint256 deadline) external returns (uint256 eth_bought); 23 | function tokenToEthTransferInput(uint256 tokens_sold, uint256 min_eth, uint256 deadline, address recipient) external returns (uint256 eth_bought); 24 | function tokenToEthSwapOutput(uint256 eth_bought, uint256 max_tokens, uint256 deadline) external returns (uint256 tokens_sold); 25 | function tokenToEthTransferOutput(uint256 eth_bought, uint256 max_tokens, uint256 deadline, address recipient) external returns (uint256 tokens_sold); 26 | // Trade ERC20 to ERC20 27 | function tokenToTokenSwapInput(uint256 tokens_sold, uint256 min_tokens_bought, uint256 min_eth_bought, uint256 deadline, address token_addr) external returns (uint256 tokens_bought); 28 | function tokenToTokenTransferInput(uint256 tokens_sold, uint256 min_tokens_bought, uint256 min_eth_bought, uint256 deadline, address recipient, address token_addr) external returns (uint256 tokens_bought); 29 | function tokenToTokenSwapOutput(uint256 tokens_bought, uint256 max_tokens_sold, uint256 max_eth_sold, uint256 deadline, address token_addr) external returns (uint256 tokens_sold); 30 | function tokenToTokenTransferOutput(uint256 tokens_bought, uint256 max_tokens_sold, uint256 max_eth_sold, uint256 deadline, address recipient, address token_addr) external returns (uint256 tokens_sold); 31 | // Trade ERC20 to Custom Pool 32 | function tokenToExchangeSwapInput(uint256 tokens_sold, uint256 min_tokens_bought, uint256 min_eth_bought, uint256 deadline, address exchange_addr) external returns (uint256 tokens_bought); 33 | function tokenToExchangeTransferInput(uint256 tokens_sold, uint256 min_tokens_bought, uint256 min_eth_bought, uint256 deadline, address recipient, address exchange_addr) external returns (uint256 tokens_bought); 34 | function tokenToExchangeSwapOutput(uint256 tokens_bought, uint256 max_tokens_sold, uint256 max_eth_sold, uint256 deadline, address exchange_addr) external returns (uint256 tokens_sold); 35 | function tokenToExchangeTransferOutput(uint256 tokens_bought, uint256 max_tokens_sold, uint256 max_eth_sold, uint256 deadline, address recipient, address exchange_addr) external returns (uint256 tokens_sold); 36 | // ERC20 comaptibility for liquidity tokens 37 | function name() external view returns (bytes32); 38 | function symbol() external view returns (bytes32); 39 | function decimals() external view returns (uint256); 40 | function transfer(address _to, uint256 _value) external returns (bool); 41 | function transferFrom(address _from, address _to, uint256 value) external returns (bool); 42 | function approve(address _spender, uint256 _value) external returns (bool); 43 | function allowance(address _owner, address _spender) external view returns (uint256); 44 | function balanceOf(address _owner) external view returns (uint256); 45 | function totalSupply() external view returns (uint256); 46 | // Never use 47 | function setup(address token_addr) external; 48 | } 49 | -------------------------------------------------------------------------------- /src/uniswap/contracts/IUniswapFactory.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.8.0; 2 | 3 | interface IUniswapFactory { 4 | // Create Exchange 5 | function createExchange(address token) external returns (address exchange); 6 | // Get Exchange and Token Info 7 | function getExchange(address token) external view returns (address exchange); 8 | function getToken(address exchange) external view returns (address token); 9 | function getTokenWithId(uint256 tokenId) external view returns (address token); 10 | // Never use 11 | function initializeFactory(address template) external; 12 | } -------------------------------------------------------------------------------- /src/uniswap/index.ts: -------------------------------------------------------------------------------- 1 | import { default as contracts } from "./contracts"; 2 | 3 | export = { 4 | ...contracts, 5 | }; 6 | -------------------------------------------------------------------------------- /src/uniswapV2/abi/IUniswapV2Factory.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "anonymous": false, 4 | "inputs": [ 5 | { 6 | "indexed": true, 7 | "internalType": "address", 8 | "name": "token0", 9 | "type": "address" 10 | }, 11 | { 12 | "indexed": true, 13 | "internalType": "address", 14 | "name": "token1", 15 | "type": "address" 16 | }, 17 | { 18 | "indexed": false, 19 | "internalType": "address", 20 | "name": "pair", 21 | "type": "address" 22 | }, 23 | { 24 | "indexed": false, 25 | "internalType": "uint256", 26 | "name": "", 27 | "type": "uint256" 28 | } 29 | ], 30 | "name": "PairCreated", 31 | "type": "event" 32 | }, 33 | { 34 | "constant": true, 35 | "inputs": [ 36 | { 37 | "internalType": "uint256", 38 | "name": "", 39 | "type": "uint256" 40 | } 41 | ], 42 | "name": "allPairs", 43 | "outputs": [ 44 | { 45 | "internalType": "address", 46 | "name": "pair", 47 | "type": "address" 48 | } 49 | ], 50 | "payable": false, 51 | "stateMutability": "view", 52 | "type": "function" 53 | }, 54 | { 55 | "constant": true, 56 | "inputs": [], 57 | "name": "allPairsLength", 58 | "outputs": [ 59 | { 60 | "internalType": "uint256", 61 | "name": "", 62 | "type": "uint256" 63 | } 64 | ], 65 | "payable": false, 66 | "stateMutability": "view", 67 | "type": "function" 68 | }, 69 | { 70 | "constant": false, 71 | "inputs": [ 72 | { 73 | "internalType": "address", 74 | "name": "tokenA", 75 | "type": "address" 76 | }, 77 | { 78 | "internalType": "address", 79 | "name": "tokenB", 80 | "type": "address" 81 | } 82 | ], 83 | "name": "createPair", 84 | "outputs": [ 85 | { 86 | "internalType": "address", 87 | "name": "pair", 88 | "type": "address" 89 | } 90 | ], 91 | "payable": false, 92 | "stateMutability": "nonpayable", 93 | "type": "function" 94 | }, 95 | { 96 | "constant": true, 97 | "inputs": [], 98 | "name": "feeTo", 99 | "outputs": [ 100 | { 101 | "internalType": "address", 102 | "name": "", 103 | "type": "address" 104 | } 105 | ], 106 | "payable": false, 107 | "stateMutability": "view", 108 | "type": "function" 109 | }, 110 | { 111 | "constant": true, 112 | "inputs": [], 113 | "name": "feeToSetter", 114 | "outputs": [ 115 | { 116 | "internalType": "address", 117 | "name": "", 118 | "type": "address" 119 | } 120 | ], 121 | "payable": false, 122 | "stateMutability": "view", 123 | "type": "function" 124 | }, 125 | { 126 | "constant": true, 127 | "inputs": [ 128 | { 129 | "internalType": "address", 130 | "name": "tokenA", 131 | "type": "address" 132 | }, 133 | { 134 | "internalType": "address", 135 | "name": "tokenB", 136 | "type": "address" 137 | } 138 | ], 139 | "name": "getPair", 140 | "outputs": [ 141 | { 142 | "internalType": "address", 143 | "name": "pair", 144 | "type": "address" 145 | } 146 | ], 147 | "payable": false, 148 | "stateMutability": "view", 149 | "type": "function" 150 | }, 151 | { 152 | "constant": false, 153 | "inputs": [ 154 | { 155 | "internalType": "address", 156 | "name": "", 157 | "type": "address" 158 | } 159 | ], 160 | "name": "setFeeTo", 161 | "outputs": [], 162 | "payable": false, 163 | "stateMutability": "nonpayable", 164 | "type": "function" 165 | }, 166 | { 167 | "constant": false, 168 | "inputs": [ 169 | { 170 | "internalType": "address", 171 | "name": "", 172 | "type": "address" 173 | } 174 | ], 175 | "name": "setFeeToSetter", 176 | "outputs": [], 177 | "payable": false, 178 | "stateMutability": "nonpayable", 179 | "type": "function" 180 | } 181 | ] 182 | -------------------------------------------------------------------------------- /src/uniswapV2/contracts.ts: -------------------------------------------------------------------------------- 1 | import factoryAbi from "./abi/IUniswapV2Factory.json"; 2 | import pairAbi from "./abi/IUniswapV2Pair.json"; 3 | import router01Abi from "./abi/IUniswapV2Router01.json"; 4 | import router02Abi from "./abi/IUniswapV2Router02.json"; 5 | 6 | const contracts = { 7 | factory: { 8 | address: "0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f", 9 | abi: factoryAbi, 10 | }, 11 | pair: { 12 | abi: pairAbi, 13 | }, 14 | router01: { 15 | address: "0xf164fC0Ec4E93095b804a4795bBe1e041497b92a", 16 | abi: router01Abi, 17 | }, 18 | router02: { 19 | address: "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D", 20 | abi: router02Abi, 21 | }, 22 | }; 23 | 24 | export default contracts; 25 | -------------------------------------------------------------------------------- /src/uniswapV2/contracts/IUniswapV2Factory.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.0; 2 | 3 | interface IUniswapV2Factory { 4 | event PairCreated(address indexed token0, address indexed token1, address pair, uint); 5 | 6 | function getPair(address tokenA, address tokenB) external view returns (address pair); 7 | function allPairs(uint) external view returns (address pair); 8 | function allPairsLength() external view returns (uint); 9 | 10 | function feeTo() external view returns (address); 11 | function feeToSetter() external view returns (address); 12 | 13 | function createPair(address tokenA, address tokenB) external returns (address pair); 14 | } -------------------------------------------------------------------------------- /src/uniswapV2/contracts/IUniswapV2Pair.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.0; 2 | 3 | interface IUniswapV2Pair { 4 | event Approval(address indexed owner, address indexed spender, uint value); 5 | event Transfer(address indexed from, address indexed to, uint value); 6 | 7 | function name() external pure returns (string memory); 8 | function symbol() external pure returns (string memory); 9 | function decimals() external pure returns (uint8); 10 | function totalSupply() external view returns (uint); 11 | function balanceOf(address owner) external view returns (uint); 12 | function allowance(address owner, address spender) external view returns (uint); 13 | 14 | function approve(address spender, uint value) external returns (bool); 15 | function transfer(address to, uint value) external returns (bool); 16 | function transferFrom(address from, address to, uint value) external returns (bool); 17 | 18 | function DOMAIN_SEPARATOR() external view returns (bytes32); 19 | function PERMIT_TYPEHASH() external pure returns (bytes32); 20 | function nonces(address owner) external view returns (uint); 21 | 22 | function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external; 23 | 24 | event Mint(address indexed sender, uint amount0, uint amount1); 25 | event Burn(address indexed sender, uint amount0, uint amount1, address indexed to); 26 | event Swap( 27 | address indexed sender, 28 | uint amount0In, 29 | uint amount1In, 30 | uint amount0Out, 31 | uint amount1Out, 32 | address indexed to 33 | ); 34 | event Sync(uint112 reserve0, uint112 reserve1); 35 | 36 | function MINIMUM_LIQUIDITY() external pure returns (uint); 37 | function factory() external view returns (address); 38 | function token0() external view returns (address); 39 | function token1() external view returns (address); 40 | function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast); 41 | function price0CumulativeLast() external view returns (uint); 42 | function price1CumulativeLast() external view returns (uint); 43 | function kLast() external view returns (uint); 44 | 45 | function mint(address to) external returns (uint liquidity); 46 | function burn(address to) external returns (uint amount0, uint amount1); 47 | function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external; 48 | function skim(address to) external; 49 | function sync() external; 50 | } -------------------------------------------------------------------------------- /src/uniswapV2/contracts/IUniswapV2Router01.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.6.2; 2 | 3 | interface IUniswapV2Router01 { 4 | function factory() external pure returns (address); 5 | function WETH() external pure returns (address); 6 | 7 | function addLiquidity( 8 | address tokenA, 9 | address tokenB, 10 | uint amountADesired, 11 | uint amountBDesired, 12 | uint amountAMin, 13 | uint amountBMin, 14 | address to, 15 | uint deadline 16 | ) external returns (uint amountA, uint amountB, uint liquidity); 17 | function addLiquidityETH( 18 | address token, 19 | uint amountTokenDesired, 20 | uint amountTokenMin, 21 | uint amountETHMin, 22 | address to, 23 | uint deadline 24 | ) external payable returns (uint amountToken, uint amountETH, uint liquidity); 25 | function removeLiquidity( 26 | address tokenA, 27 | address tokenB, 28 | uint liquidity, 29 | uint amountAMin, 30 | uint amountBMin, 31 | address to, 32 | uint deadline 33 | ) external returns (uint amountA, uint amountB); 34 | function removeLiquidityETH( 35 | address token, 36 | uint liquidity, 37 | uint amountTokenMin, 38 | uint amountETHMin, 39 | address to, 40 | uint deadline 41 | ) external returns (uint amountToken, uint amountETH); 42 | function removeLiquidityWithPermit( 43 | address tokenA, 44 | address tokenB, 45 | uint liquidity, 46 | uint amountAMin, 47 | uint amountBMin, 48 | address to, 49 | uint deadline, 50 | bool approveMax, uint8 v, bytes32 r, bytes32 s 51 | ) external returns (uint amountA, uint amountB); 52 | function removeLiquidityETHWithPermit( 53 | address token, 54 | uint liquidity, 55 | uint amountTokenMin, 56 | uint amountETHMin, 57 | address to, 58 | uint deadline, 59 | bool approveMax, uint8 v, bytes32 r, bytes32 s 60 | ) external returns (uint amountToken, uint amountETH); 61 | function swapExactTokensForTokens( 62 | uint amountIn, 63 | uint amountOutMin, 64 | address[] calldata path, 65 | address to, 66 | uint deadline 67 | ) external returns (uint[] memory amounts); 68 | function swapTokensForExactTokens( 69 | uint amountOut, 70 | uint amountInMax, 71 | address[] calldata path, 72 | address to, 73 | uint deadline 74 | ) external returns (uint[] memory amounts); 75 | function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) 76 | external 77 | payable 78 | returns (uint[] memory amounts); 79 | function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline) 80 | external 81 | returns (uint[] memory amounts); 82 | function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) 83 | external 84 | returns (uint[] memory amounts); 85 | function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline) 86 | external 87 | payable 88 | returns (uint[] memory amounts); 89 | 90 | function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB); 91 | function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut); 92 | function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn); 93 | function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts); 94 | function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts); 95 | } -------------------------------------------------------------------------------- /src/uniswapV2/contracts/IUniswapV2Router02.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.6.2; 2 | 3 | interface IUniswapV2Router01 { 4 | function factory() external pure returns (address); 5 | function WETH() external pure returns (address); 6 | 7 | function addLiquidity( 8 | address tokenA, 9 | address tokenB, 10 | uint amountADesired, 11 | uint amountBDesired, 12 | uint amountAMin, 13 | uint amountBMin, 14 | address to, 15 | uint deadline 16 | ) external returns (uint amountA, uint amountB, uint liquidity); 17 | function addLiquidityETH( 18 | address token, 19 | uint amountTokenDesired, 20 | uint amountTokenMin, 21 | uint amountETHMin, 22 | address to, 23 | uint deadline 24 | ) external payable returns (uint amountToken, uint amountETH, uint liquidity); 25 | function removeLiquidity( 26 | address tokenA, 27 | address tokenB, 28 | uint liquidity, 29 | uint amountAMin, 30 | uint amountBMin, 31 | address to, 32 | uint deadline 33 | ) external returns (uint amountA, uint amountB); 34 | function removeLiquidityETH( 35 | address token, 36 | uint liquidity, 37 | uint amountTokenMin, 38 | uint amountETHMin, 39 | address to, 40 | uint deadline 41 | ) external returns (uint amountToken, uint amountETH); 42 | function removeLiquidityWithPermit( 43 | address tokenA, 44 | address tokenB, 45 | uint liquidity, 46 | uint amountAMin, 47 | uint amountBMin, 48 | address to, 49 | uint deadline, 50 | bool approveMax, uint8 v, bytes32 r, bytes32 s 51 | ) external returns (uint amountA, uint amountB); 52 | function removeLiquidityETHWithPermit( 53 | address token, 54 | uint liquidity, 55 | uint amountTokenMin, 56 | uint amountETHMin, 57 | address to, 58 | uint deadline, 59 | bool approveMax, uint8 v, bytes32 r, bytes32 s 60 | ) external returns (uint amountToken, uint amountETH); 61 | function swapExactTokensForTokens( 62 | uint amountIn, 63 | uint amountOutMin, 64 | address[] calldata path, 65 | address to, 66 | uint deadline 67 | ) external returns (uint[] memory amounts); 68 | function swapTokensForExactTokens( 69 | uint amountOut, 70 | uint amountInMax, 71 | address[] calldata path, 72 | address to, 73 | uint deadline 74 | ) external returns (uint[] memory amounts); 75 | function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) 76 | external 77 | payable 78 | returns (uint[] memory amounts); 79 | function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline) 80 | external 81 | returns (uint[] memory amounts); 82 | function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) 83 | external 84 | returns (uint[] memory amounts); 85 | function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline) 86 | external 87 | payable 88 | returns (uint[] memory amounts); 89 | 90 | function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB); 91 | function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut); 92 | function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn); 93 | function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts); 94 | function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts); 95 | } 96 | 97 | interface IUniswapV2Router02 is IUniswapV2Router01 { 98 | function removeLiquidityETHSupportingFeeOnTransferTokens( 99 | address token, 100 | uint liquidity, 101 | uint amountTokenMin, 102 | uint amountETHMin, 103 | address to, 104 | uint deadline 105 | ) external returns (uint amountETH); 106 | function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens( 107 | address token, 108 | uint liquidity, 109 | uint amountTokenMin, 110 | uint amountETHMin, 111 | address to, 112 | uint deadline, 113 | bool approveMax, uint8 v, bytes32 r, bytes32 s 114 | ) external returns (uint amountETH); 115 | 116 | function swapExactTokensForTokensSupportingFeeOnTransferTokens( 117 | uint amountIn, 118 | uint amountOutMin, 119 | address[] calldata path, 120 | address to, 121 | uint deadline 122 | ) external; 123 | function swapExactETHForTokensSupportingFeeOnTransferTokens( 124 | uint amountOutMin, 125 | address[] calldata path, 126 | address to, 127 | uint deadline 128 | ) external payable; 129 | function swapExactTokensForETHSupportingFeeOnTransferTokens( 130 | uint amountIn, 131 | uint amountOutMin, 132 | address[] calldata path, 133 | address to, 134 | uint deadline 135 | ) external; 136 | } -------------------------------------------------------------------------------- /src/uniswapV2/index.ts: -------------------------------------------------------------------------------- 1 | import { default as contracts } from "./contracts"; 2 | 3 | export = { 4 | ...contracts, 5 | }; 6 | -------------------------------------------------------------------------------- /tests/aave.test.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.8.0; 2 | pragma experimental ABIEncoderV2; 3 | 4 | import "@studydefi/money-legos/aave/contracts/ILendingPool.sol"; 5 | import "@studydefi/money-legos/aave/contracts/IFlashLoanReceiver.sol"; 6 | import "@studydefi/money-legos/aave/contracts/FlashloanReceiverBase.sol"; 7 | 8 | import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 9 | 10 | contract ContractWithFlashLoan is FlashLoanReceiverBase { 11 | address constant AaveLendingPoolAddressProviderAddress = 0x24a42fD28C976A61Df5D00D0599C34c4f90748c8; 12 | 13 | struct MyCustomData { 14 | address a; 15 | uint b; 16 | } 17 | 18 | function executeOperation( 19 | address _reserve, 20 | uint _amount, 21 | uint _fee, 22 | bytes calldata _params 23 | ) external { 24 | // You can pass in some byte-encoded params 25 | MyCustomData memory myCustomData = abi.decode(_params, (MyCustomData)); 26 | // myCustomData.a 27 | 28 | // Function is called when loan is given to contract 29 | // Do your logic here, e.g. arbitrage, liquidate compound, etc 30 | // Note that if you don't do your logic, it WILL fail 31 | 32 | // TODO: Change line below 33 | revert("Hello, you haven't implemented your flashloan logic"); 34 | 35 | transferFundsBackToPoolInternal(_reserve, _amount.add(_fee)); 36 | } 37 | 38 | // Entry point 39 | function initateFlashLoan( 40 | address contractWithFlashLoan, 41 | address assetToFlashLoan, 42 | uint amountToLoan, 43 | bytes calldata _params 44 | ) external { 45 | // Get Aave lending pool 46 | ILendingPool lendingPool = ILendingPool( 47 | ILendingPoolAddressesProvider(AaveLendingPoolAddressProviderAddress) 48 | .getLendingPool() 49 | ); 50 | 51 | // Ask for a flashloan 52 | // LendingPool will now execute the `executeOperation` function above 53 | lendingPool.flashLoan( 54 | contractWithFlashLoan, // Which address to callback into, alternatively: address(this) 55 | assetToFlashLoan, 56 | amountToLoan, 57 | _params 58 | ); 59 | } 60 | } -------------------------------------------------------------------------------- /tests/balancer.test.ts: -------------------------------------------------------------------------------- 1 | jest.setTimeout(100000); 2 | 3 | import { Wallet, Contract, ethers } from "ethers"; 4 | import erc20 from "../src/erc20"; 5 | import balancer from "../src/balancer"; 6 | import mstable from "../src/mstable"; 7 | import { fromWei } from "./utils"; 8 | import { parseUnits } from "ethers/utils"; 9 | 10 | const { parseEther, bigNumberify } = ethers.utils; 11 | 12 | const MAX_UINT256 = bigNumberify("2").pow("256").sub("1"); 13 | 14 | // Note: 15 | // Balancer uses Smart Order Router (SOR), an off-chain linear optimization of routing orders across pools. 16 | // SOR exists in the Bronze release as a way to aggregate liquidity across all Balancer pools. 17 | // Future releases of Balancer will accomplish this on-chain and allow aggregate contract fillable liquidity. 18 | // See more: https://docs.balancer.finance/protocol/sor 19 | const ETH_MUSD_50_50_POOL_ADDRESS = 20 | "0xe036cce08cf4e23d33bc6b18e53caf532afa8513"; 21 | const MUSD_USDC_50_50_POOL_ADDRESS = 22 | "0x72Cd8f4504941Bf8c5a21d1Fd83A96499FD71d2C"; 23 | 24 | describe("balancer", () => { 25 | let wallet: Wallet; 26 | let weth: Contract; 27 | let mUSD: Contract; 28 | let usdc: Contract; 29 | let exchangeProxy: Contract; 30 | 31 | beforeAll(async () => { 32 | ethers.errors.setLogLevel("error"); 33 | 34 | // @ts-ignore 35 | wallet = global.wallet; 36 | weth = new ethers.Contract(erc20.weth.address, erc20.weth.abi, wallet); 37 | mUSD = new ethers.Contract(mstable.mUSD.address, mstable.mUSD.abi, wallet); 38 | usdc = new ethers.Contract(erc20.usdc.address, erc20.usdc.abi, wallet); 39 | exchangeProxy = new ethers.Contract( 40 | balancer.ExchangeProxy.address, 41 | balancer.ExchangeProxy.abi, 42 | wallet, 43 | ); 44 | }); 45 | 46 | test("Swap ETH -> mUSD", async () => { 47 | // given 48 | const beforeWei = await mUSD.balanceOf(wallet.address); 49 | const before = parseFloat(fromWei(beforeWei)); 50 | expect(before).toEqual(0); 51 | 52 | // when 53 | const tokenInParam = parseEther("10"); 54 | const tokenOutParam = 0; 55 | const maxPrice = MAX_UINT256; 56 | const swap = [ 57 | ETH_MUSD_50_50_POOL_ADDRESS, 58 | tokenInParam, 59 | tokenOutParam, 60 | maxPrice, 61 | ]; 62 | const swaps: any = [swap]; 63 | 64 | const tokenOut = mUSD.address; 65 | const minTotalAmountOut = 1; 66 | await exchangeProxy.batchEthInSwapExactIn( 67 | swaps, 68 | tokenOut, 69 | minTotalAmountOut, 70 | { 71 | gasLimit: 500000, 72 | value: tokenInParam, 73 | }, 74 | ); 75 | 76 | // then 77 | const afterWei = await mUSD.balanceOf(wallet.address); 78 | const after = parseFloat(fromWei(afterWei)); 79 | expect(after).toBeGreaterThan(0); 80 | }); 81 | 82 | test("Swap some mUSD -> USDC", async () => { 83 | // given 84 | const beforeWei = await usdc.balanceOf(wallet.address); 85 | const before = parseFloat(fromWei(beforeWei)); 86 | expect(before).toEqual(0); 87 | 88 | const mUSDToSell = parseEther("1000"); 89 | await mUSD.approve(exchangeProxy.address, mUSDToSell); 90 | 91 | // when 92 | const tokenInParam = mUSDToSell; 93 | const tokenOutParam = 0; 94 | const maxPrice = MAX_UINT256; 95 | const swap = [ 96 | MUSD_USDC_50_50_POOL_ADDRESS, 97 | tokenInParam, 98 | tokenOutParam, 99 | maxPrice, 100 | ]; 101 | const swaps: any = [swap]; 102 | 103 | const tokenIn = mUSD.addressPromise; 104 | const tokenOut = usdc.address; 105 | const totalAmountIn = mUSDToSell; 106 | const minTotalAmountOut = 1; 107 | await exchangeProxy.batchSwapExactIn( 108 | swaps, 109 | tokenIn, 110 | tokenOut, 111 | totalAmountIn, 112 | minTotalAmountOut, 113 | { 114 | gasLimit: 500000, 115 | }, 116 | ); 117 | 118 | // then 119 | const afterWei = await usdc.balanceOf(wallet.address); 120 | const after = parseFloat(fromWei(afterWei)); 121 | expect(after).toBeGreaterThan(0); 122 | }); 123 | 124 | test("Add liquidity to a pool", async () => { 125 | const pool = new ethers.Contract( 126 | MUSD_USDC_50_50_POOL_ADDRESS, 127 | balancer.BPool.abi, 128 | wallet, 129 | ); 130 | 131 | // given 132 | const beforeWei = await pool.balanceOf(wallet.address); 133 | const before = parseFloat(fromWei(beforeWei)); 134 | expect(before).toEqual(0); 135 | 136 | await mUSD.approve(pool.address, MAX_UINT256); 137 | await usdc.approve(pool.address, MAX_UINT256); 138 | 139 | const poolAmountOut = parseEther("5"); 140 | const maxAmountsIn = [ 141 | parseUnits("1000", mstable.mUSD.decimals), 142 | parseUnits("1000", erc20.usdc.decimals), 143 | ]; 144 | await pool.joinPool(poolAmountOut, maxAmountsIn, { gasLimit: 500000 }); 145 | 146 | const afterWei = await pool.balanceOf(wallet.address); 147 | const after = parseFloat(fromWei(afterWei)); 148 | expect(after).toEqual(parseFloat(fromWei(poolAmountOut))); 149 | }); 150 | }); 151 | -------------------------------------------------------------------------------- /tests/index.test.ts: -------------------------------------------------------------------------------- 1 | jest.setTimeout(100000); 2 | 3 | import { Wallet, Contract, ethers } from "ethers"; 4 | import { fromWei } from "./utils"; 5 | 6 | // import legos 7 | import erc20 from "../src/erc20"; 8 | 9 | describe("initial conditions", () => { 10 | let wallet: Wallet, daiContract: Contract; 11 | 12 | beforeAll(async () => { 13 | ethers.errors.setLogLevel("error"); 14 | 15 | // @ts-ignore 16 | wallet = global.wallet; 17 | daiContract = new ethers.Contract( 18 | erc20.dai.address, 19 | erc20.abi, 20 | wallet, 21 | ); 22 | }); 23 | 24 | test("initial DAI balance of 0", async () => { 25 | const daiBalance = await daiContract.balanceOf(wallet.address); 26 | expect(fromWei(daiBalance)).toBe("0.0"); 27 | }); 28 | 29 | test("initial ETH balance of 1000 ETH", async () => { 30 | // note: this is set in test-environment.js when we spin up the test chain 31 | const ethBalance = await wallet.getBalance(); 32 | expect(fromWei(ethBalance)).toBe("1000.0"); 33 | }); 34 | }); 35 | -------------------------------------------------------------------------------- /tests/kyber.test.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.8.0; 2 | 3 | import "@studydefi/money-legos/kyber/contracts/KyberNetworkProxy.sol"; 4 | import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 5 | 6 | contract KyberLiteBase { 7 | // Uniswap Mainnet factory address 8 | address constant KyberNetworkProxyAddress = 0x818E6FECD516Ecc3849DAf6845e3EC868087B755; 9 | 10 | function _ethToToken(address tokenAddress, uint ethAmount) internal returns (uint) { 11 | return _ethToToken(tokenAddress, ethAmount, uint(1)); 12 | } 13 | 14 | function _ethToToken(address tokenAddress, uint ethAmount, uint minConversionRate) internal returns (uint) { 15 | IERC20 token = IERC20(tokenAddress); 16 | return KyberNetworkProxy(KyberNetworkProxyAddress).swapEtherToToken.value(ethAmount)(token, minConversionRate); 17 | } 18 | 19 | function _tokenToEth(address tokenAddress, uint tokenAmount) internal returns (uint) { 20 | return _tokenToEth(tokenAddress, tokenAmount, uint(1)); 21 | } 22 | 23 | function _tokenToEth(address tokenAddress, uint tokenAmount, uint minConversionRate) internal returns (uint) { 24 | KyberNetworkProxy kyber = KyberNetworkProxy(KyberNetworkProxyAddress); 25 | 26 | IERC20 token = IERC20(tokenAddress); 27 | 28 | token.approve(address(kyber), tokenAmount); 29 | 30 | return kyber.swapTokenToEther(token, tokenAmount, minConversionRate); 31 | } 32 | 33 | function _tokenToToken(address from, address to, uint tokenAmount, uint minConversionRate) internal returns (uint) { 34 | KyberNetworkProxy kyber = KyberNetworkProxy(KyberNetworkProxyAddress); 35 | 36 | IERC20(from).approve(address(kyber), tokenAmount); 37 | 38 | return kyber.swapTokenToToken(IERC20(from), tokenAmount, IERC20(to), minConversionRate); 39 | } 40 | 41 | function _tokenToToken(address from, address to, uint tokenAmount) internal returns (uint) { 42 | return _tokenToToken(from, to, tokenAmount, uint(1)); 43 | } 44 | 45 | function ethToToken(address tokenAddress) public payable { 46 | IERC20 token = IERC20(tokenAddress); 47 | uint256 tokensAmount = _ethToToken(tokenAddress, msg.value, uint(1)); 48 | token.transfer(msg.sender, tokensAmount); 49 | } 50 | } -------------------------------------------------------------------------------- /tests/kyber.test.ts: -------------------------------------------------------------------------------- 1 | jest.setTimeout(500000); 2 | 3 | import { Wallet, Contract, ethers } from "ethers"; 4 | import { fromWei } from "./utils"; 5 | 6 | // import legos 7 | import erc20 from "../src/erc20"; 8 | import kyber from "../src/kyber"; 9 | 10 | const { parseEther, bigNumberify } = ethers.utils; 11 | 12 | describe("kyber", () => { 13 | let wallet: Wallet, daiContract: Contract; 14 | 15 | beforeAll(async () => { 16 | ethers.errors.setLogLevel("error"); 17 | 18 | // @ts-ignore 19 | wallet = global.wallet; 20 | daiContract = new ethers.Contract(erc20.dai.address, erc20.abi, wallet); 21 | }); 22 | 23 | test("buy DAI from Kyber.Network", async () => { 24 | const kyberNetworkContract = new ethers.Contract( 25 | kyber.network.address, 26 | kyber.network.abi, 27 | wallet, 28 | ); 29 | 30 | const ethToSwap = 5; 31 | const ethBeforeWei = await wallet.getBalance(); 32 | const daiBeforeWei = await daiContract.balanceOf(wallet.address); 33 | 34 | const { 35 | expectedRate, 36 | slippageRate, 37 | } = await kyberNetworkContract.getExpectedRate( 38 | erc20.eth.address, 39 | erc20.dai.address, 40 | parseEther(`${ethToSwap}`), 41 | ); 42 | 43 | const expectedDaiWei = expectedRate.mul(bigNumberify(`${ethToSwap}`)); 44 | const expectedDai = parseFloat(fromWei(expectedDaiWei)); 45 | 46 | // do the actual swapping 47 | const minConversionRate = slippageRate; 48 | await kyberNetworkContract.swapEtherToToken( 49 | erc20.dai.address, 50 | minConversionRate, 51 | { 52 | gasLimit: 4000000, 53 | value: parseEther(`${ethToSwap}`), 54 | }, 55 | ); 56 | 57 | const ethAfterWei = await wallet.getBalance(); 58 | const daiAfterWei = await daiContract.balanceOf(wallet.address); 59 | 60 | const daiAfter = parseFloat(fromWei(daiAfterWei)); 61 | const ethLost = parseFloat(fromWei(ethBeforeWei.sub(ethAfterWei))); 62 | 63 | expect(fromWei(daiBeforeWei)).toBe("0.0"); 64 | expect(daiAfter).toBeCloseTo(expectedDai); 65 | expect(ethLost).toBeCloseTo(ethToSwap); 66 | }); 67 | }); 68 | -------------------------------------------------------------------------------- /tests/maker.test.ts: -------------------------------------------------------------------------------- 1 | jest.setTimeout(100000); 2 | 3 | import { Wallet, Contract, ethers } from "ethers"; 4 | import { fromWei } from "./utils"; 5 | 6 | // import legos 7 | import erc20 from "../src/erc20"; 8 | import maker from "../src/maker"; 9 | import dappsys from "../src/dappsys"; 10 | 11 | describe("maker", () => { 12 | let wallet: Wallet, daiContract: Contract; 13 | 14 | beforeAll(async () => { 15 | ethers.errors.setLogLevel("error"); 16 | 17 | // @ts-ignore 18 | wallet = global.wallet; 19 | daiContract = new ethers.Contract(erc20.dai.address, erc20.abi, wallet); 20 | }); 21 | 22 | test("create a proxy on Maker", async () => { 23 | const proxyRegistry = new ethers.Contract( 24 | maker.proxyRegistry.address, 25 | maker.proxyRegistry.abi, 26 | wallet, 27 | ); 28 | 29 | const before = await proxyRegistry.proxies(wallet.address); 30 | 31 | await proxyRegistry.build({ gasLimit: 1500000 }); 32 | 33 | const after = await proxyRegistry.proxies(wallet.address); 34 | 35 | expect(before).toBe("0x0000000000000000000000000000000000000000"); 36 | expect(after).not.toBe("0x0000000000000000000000000000000000000000"); 37 | }); 38 | 39 | test("open Vault on Maker", async () => { 40 | const proxyRegistry = new ethers.Contract( 41 | maker.proxyRegistry.address, 42 | maker.proxyRegistry.abi, 43 | wallet, 44 | ); 45 | 46 | // Build proxy if we don't have one 47 | let proxyAddress = await proxyRegistry.proxies(wallet.address); 48 | if (proxyAddress === "0x0000000000000000000000000000000000000000") { 49 | await proxyRegistry.build({ gasLimit: 1500000 }); 50 | proxyAddress = await proxyRegistry.proxies(wallet.address); 51 | } 52 | 53 | // Note: MakerDAO uses dappsys's DSProxy 54 | const proxyContract = new ethers.Contract( 55 | proxyAddress, 56 | dappsys.dsProxy.abi, 57 | wallet, 58 | ); 59 | 60 | // Prepare data for delegate call 61 | const IDssProxyActions = new ethers.utils.Interface( 62 | maker.dssProxyActions.abi, 63 | ); 64 | 65 | const _data = IDssProxyActions.functions.openLockETHAndDraw.encode([ 66 | maker.dssCdpManager.address, 67 | maker.jug.address, 68 | maker.ethAJoin.address, 69 | maker.daiJoin.address, 70 | ethers.utils.formatBytes32String(maker.ethA.symbol), 71 | ethers.utils.parseUnits("20", erc20.dai.decimals), 72 | ]); 73 | 74 | const ethBefore = await await wallet.getBalance(); 75 | const daiBefore = await daiContract.balanceOf(wallet.address); 76 | 77 | // Open vault through proxy 78 | await proxyContract.execute(maker.dssProxyActions.address, _data, { 79 | gasLimit: 2500000, 80 | value: ethers.utils.parseEther("1"), 81 | }); 82 | 83 | const ethAfter = await await wallet.getBalance(); 84 | const daiAfter = await daiContract.balanceOf(wallet.address); 85 | 86 | const ethSpent = parseFloat(fromWei(ethBefore.sub(ethAfter))); 87 | const daiGained = parseFloat(fromWei(daiAfter.sub(daiBefore))); 88 | 89 | expect(ethSpent).toBeCloseTo(1, 1); 90 | expect(daiGained).toBeCloseTo(20); 91 | }); 92 | }); 93 | -------------------------------------------------------------------------------- /tests/medianizer.test.ts: -------------------------------------------------------------------------------- 1 | jest.setTimeout(100000); 2 | 3 | import { Wallet, ethers } from "ethers"; 4 | 5 | // import legos 6 | import maker from "../src/maker"; 7 | import { fromWei } from "./utils"; 8 | 9 | describe("maker medianizer", () => { 10 | let wallet: Wallet; 11 | 12 | beforeAll(async () => { 13 | ethers.errors.setLogLevel("error"); 14 | 15 | // @ts-ignore 16 | wallet = global.wallet; 17 | }); 18 | 19 | test("read ETH price from medianizer", async () => { 20 | const makerMedianizer = new ethers.Contract( 21 | maker.ethUsdPriceFeed.address, 22 | maker.ethUsdPriceFeed.abi, 23 | wallet, 24 | ); 25 | 26 | const ethPriceUsdWei = await makerMedianizer.read(); 27 | const ethPriceUsd = parseFloat(fromWei(ethPriceUsdWei)); 28 | 29 | expect(ethPriceUsd).toBeGreaterThan(0); 30 | expect(ethPriceUsd).toBeLessThan(1000); 31 | }); 32 | }); 33 | -------------------------------------------------------------------------------- /tests/test-environment.js: -------------------------------------------------------------------------------- 1 | const dotenv = require("dotenv"); 2 | dotenv.config(); 3 | 4 | const { ethers } = require("ethers"); 5 | const Ganache = require("ganache-core"); 6 | const NodeEnvironment = require("jest-environment-node"); 7 | 8 | const startChain = async () => { 9 | if (!process.env.PRIV_KEY || !process.env.MAINNET_NODE_URL) { 10 | throw Error("PRIV_KEY and MAINNET_NODE_URL not found in .env"); 11 | } 12 | const ganache = Ganache.provider({ 13 | fork: process.env.MAINNET_NODE_URL, 14 | network_id: 1, 15 | accounts: [ 16 | { 17 | secretKey: process.env.PRIV_KEY, 18 | balance: ethers.utils.hexlify(ethers.utils.parseEther("1000")), 19 | }, 20 | ], 21 | }); 22 | 23 | const provider = new ethers.providers.Web3Provider(ganache); 24 | const wallet = new ethers.Wallet(process.env.PRIV_KEY, provider); 25 | 26 | return { wallet, provider }; 27 | }; 28 | 29 | class CustomEnvironment extends NodeEnvironment { 30 | testPath; 31 | docblockPragmas; 32 | 33 | // Our own vars 34 | wallet; 35 | provider; 36 | 37 | constructor(config, context) { 38 | super(config); 39 | this.testPath = context.testPath; 40 | this.docblockPragmas = context.docblockPragmas; 41 | } 42 | 43 | async setup() { 44 | await super.setup(); 45 | const { wallet, provider } = await startChain(); 46 | this.wallet = wallet; 47 | this.provider = provider; 48 | this.global.wallet = wallet; 49 | this.global.provider = provider; 50 | } 51 | 52 | async teardown() { 53 | await super.teardown(); 54 | } 55 | 56 | //@ts-ignore 57 | runScript(script) { 58 | return super.runScript(script); 59 | } 60 | } 61 | 62 | module.exports = CustomEnvironment; 63 | -------------------------------------------------------------------------------- /tests/uniswap.test.ts: -------------------------------------------------------------------------------- 1 | jest.setTimeout(100000); 2 | 3 | import { Wallet, Contract, ethers } from "ethers"; 4 | import { fromWei } from "./utils"; 5 | 6 | // import legos 7 | import erc20 from "../src/erc20"; 8 | import uniswap from "../src/uniswap"; 9 | 10 | describe("uniswap", () => { 11 | let wallet: Wallet, daiContract: Contract; 12 | 13 | beforeAll(async () => { 14 | ethers.errors.setLogLevel("error"); 15 | 16 | // @ts-ignore 17 | wallet = global.wallet; 18 | daiContract = new ethers.Contract(erc20.dai.address, erc20.abi, wallet); 19 | }); 20 | 21 | test("buy DAI from Uniswap", async () => { 22 | const uniswapFactoryContract = new ethers.Contract( 23 | uniswap.factory.address, 24 | uniswap.factory.abi, 25 | wallet, 26 | ); 27 | 28 | const daiExchangeAddress = await uniswapFactoryContract.getExchange( 29 | erc20.dai.address, 30 | ); 31 | 32 | const daiExchangeContract = new ethers.Contract( 33 | daiExchangeAddress, 34 | uniswap.exchange.abi, 35 | wallet, 36 | ); 37 | 38 | const ethBefore = await wallet.getBalance(); 39 | const daiBefore = await daiContract.balanceOf(wallet.address); 40 | 41 | const expectedDai = await daiExchangeContract.getEthToTokenInputPrice( 42 | ethers.utils.parseEther("5"), 43 | ); 44 | 45 | // do the actual swapping 46 | await daiExchangeContract.ethToTokenSwapInput( 47 | 1, // min amount of token retrieved 48 | 2525644800, // random timestamp in the future (year 2050) 49 | { 50 | gasLimit: 4000000, 51 | value: ethers.utils.parseEther("5"), 52 | }, 53 | ); 54 | 55 | const ethAfter = await wallet.getBalance(); 56 | const daiAfter = await daiContract.balanceOf(wallet.address); 57 | 58 | const ethLost = parseFloat(fromWei(ethBefore.sub(ethAfter))); 59 | 60 | expect(fromWei(daiBefore)).toBe("0.0"); 61 | expect(fromWei(daiAfter)).toBe(fromWei(expectedDai)); 62 | expect(ethLost).toBeCloseTo(5); 63 | }); 64 | }); 65 | -------------------------------------------------------------------------------- /tests/uniswapV2.test.ts: -------------------------------------------------------------------------------- 1 | jest.setTimeout(100000); 2 | 3 | import { Wallet, Contract, ethers } from "ethers"; 4 | import { fromWei } from "./utils"; 5 | 6 | const { parseEther } = ethers.utils; 7 | 8 | // import legos 9 | import erc20 from "../src/erc20"; 10 | import uniswapV2 from "../src/uniswapV2"; 11 | 12 | describe("uniswapV2", () => { 13 | let wallet: Wallet; 14 | let dai: Contract; 15 | 16 | beforeAll(async () => { 17 | ethers.errors.setLogLevel("error"); 18 | 19 | // @ts-ignore 20 | wallet = global.wallet; 21 | dai = new ethers.Contract(erc20.dai.address, erc20.abi, wallet); 22 | }); 23 | 24 | test("buy DAI from UniswapV2", async () => { 25 | const uniswapRouter02 = new ethers.Contract( 26 | uniswapV2.router02.address, 27 | uniswapV2.router02.abi, 28 | wallet, 29 | ); 30 | const path = [erc20.weth.address, erc20.dai.address]; 31 | 32 | const ethBefore = await wallet.getBalance(); 33 | const daiBefore = await dai.balanceOf(wallet.address); 34 | 35 | const amountIn = parseEther("5"); 36 | const [, expectedDai] = await uniswapRouter02.getAmountsOut(amountIn, path); 37 | 38 | // do the actual swapping 39 | await uniswapRouter02.swapExactETHForTokens( 40 | 1, // amountOutMin 41 | path, 42 | wallet.address, // to 43 | ethers.constants.MaxUint256, // deadline 44 | { 45 | gasLimit: 4000000, 46 | value: amountIn, 47 | }, 48 | ); 49 | 50 | const ethAfter = await wallet.getBalance(); 51 | const daiAfter = await dai.balanceOf(wallet.address); 52 | 53 | const ethLost = parseFloat(fromWei(ethBefore.sub(ethAfter))); 54 | 55 | expect(fromWei(daiBefore)).toBe("0.0"); 56 | expect(fromWei(daiAfter)).toBe(fromWei(expectedDai)); 57 | expect(ethLost).toBeCloseTo(5); 58 | }); 59 | }); 60 | -------------------------------------------------------------------------------- /tests/utils.ts: -------------------------------------------------------------------------------- 1 | import { ethers } from "ethers"; 2 | import { BigNumber } from "ethers/utils"; 3 | 4 | export const fromWei = (x: BigNumber, u = 18) => ethers.utils.formatUnits(x, u); 5 | 6 | export const mineBlock = async (provider: any, timestamp: number) => 7 | await provider.send("evm_mine", [timestamp]); 8 | 9 | export const increaseTime = async (provider: any, secsToIncrease: number) => { 10 | const blockNumber = await provider.getBlockNumber(); 11 | const { timestamp: currentTimestamp } = await provider.getBlock(blockNumber); 12 | const newTime = Number(currentTimestamp) + Number(secsToIncrease); 13 | await mineBlock(provider, newTime); 14 | }; 15 | --------------------------------------------------------------------------------