├── .eslintrc.json ├── .github └── workflows │ ├── lint.yml │ └── publish.yml ├── .gitignore ├── .npmignore ├── LICENSE ├── README.md ├── package-lock.json ├── package.json ├── src ├── constants │ ├── abis │ │ ├── DeleverageZap.json │ │ ├── ERC20.json │ │ ├── Factory.json │ │ ├── HealthCalculatorZap.json │ │ ├── LeverageZap.json │ │ ├── MonetaryPolicy.json │ │ ├── MonetaryPolicy2.json │ │ ├── PegKeeper.json │ │ ├── controller.json │ │ ├── controller_v2.json │ │ └── llamma.json │ ├── coins.ts │ ├── llammas.ts │ └── utils.ts ├── crvusd.ts ├── external-api.ts ├── index.ts ├── interfaces.ts ├── llammas │ ├── LlammaTemplate.ts │ ├── index.ts │ └── llammaConstructor.ts └── utils.ts ├── test ├── general.test.ts ├── readme.test.ts ├── selfLiquidate.test.ts └── swap.test.ts ├── tsconfig.build.json └── tsconfig.json /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "es6": true 5 | }, 6 | "extends": "eslint:recommended", 7 | "parser": "vue-eslint-parser", 8 | "parserOptions": { 9 | "parser": "babel-eslint", 10 | "sourceType": "module", 11 | "allowImportExportEverywhere": false 12 | }, 13 | "rules": { 14 | "func-names": 0, 15 | "no-nested-ternary": 0, 16 | "max-len": 0, 17 | "arrow-parens": ["error", "always"], 18 | "no-underscore-dangle": 0, 19 | "comma-dangle": ["error", { 20 | "arrays": "always-multiline", 21 | "objects": "always-multiline", 22 | "imports": "always-multiline", 23 | "exports": "always-multiline", 24 | "functions": "never" 25 | }], 26 | "no-use-before-define": ["error", "nofunc"], 27 | "no-empty": ["error", { "allowEmptyCatch": true }], 28 | "no-mixed-operators": ["error", { "allowSamePrecedence": true }], 29 | "indent": ["error", 4, { "flatTernaryExpressions": true, "SwitchCase": 1 }] 30 | }, 31 | "overrides": [{ 32 | "files": ["**/*.ts"], 33 | "parser": "@typescript-eslint/parser", 34 | "plugins": ["@typescript-eslint"], 35 | "extends": ["plugin:@typescript-eslint/eslint-recommended", "plugin:@typescript-eslint/recommended"], 36 | "rules": { 37 | "@typescript-eslint/ban-ts-comment": "off" 38 | } 39 | }] 40 | } -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: Lint 2 | on: 3 | push: 4 | 5 | jobs: 6 | test: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v2 10 | - uses: actions/setup-node@v2 11 | with: 12 | node-version: '22' 13 | cache: npm 14 | - run: npm ci 15 | - run: npm run build 16 | - run: npm run lint 17 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Release & Publish 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | release: 10 | name: Release 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: Checkout code 14 | uses: actions/checkout@v4 15 | - name: get-npm-version 16 | id: package-version 17 | uses: martinbeentjes/npm-get-version-action@main 18 | - name: Generate changelog 19 | id: changelog 20 | uses: TriPSs/conventional-changelog-action@v3 21 | with: 22 | github-token: ${{ secrets.GITHUB_TOKEN }} 23 | git-push: false 24 | output-file: false 25 | skip-version-file: true 26 | skip-commit: true 27 | - name: Create Release 28 | id: create_release 29 | uses: actions/create-release@v1 30 | env: 31 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 32 | with: 33 | tag_name: v${{ steps.package-version.outputs.current-version }} 34 | release_name: v${{ steps.package-version.outputs.current-version }} 35 | body: ${{ steps.changelog.outputs.clean_changelog }} 36 | draft: false 37 | prerelease: false 38 | 39 | publish: 40 | runs-on: ubuntu-latest 41 | permissions: 42 | contents: read 43 | id-token: write 44 | steps: 45 | - uses: actions/checkout@v4 46 | - name: Setup node version 47 | uses: actions/setup-node@v4 48 | with: 49 | node-version: '22' 50 | registry-url: 'https://registry.npmjs.org' 51 | - name: Install modules 52 | run: npm ci 53 | - name: Build 54 | run: npm run build 55 | - name: Publish to npm 56 | run: npm publish --access public 57 | env: 58 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} 59 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | node_modules 3 | dist/**/* 4 | lib/**/* 5 | pnpm-lock.yaml 6 | yarn.lock 7 | test/temp.test.ts -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .idea 2 | node_modules 3 | src 4 | test 5 | dist 6 | .github 7 | .eslintrc.json 8 | package-lock.json 9 | tsconfig* 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Curve Finance 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. -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@curvefi/stablecoin-api", 3 | "version": "1.6.0", 4 | "description": "JavaScript library for Curve Stablecoin", 5 | "main": "lib/index.js", 6 | "author": "Macket", 7 | "license": "MIT", 8 | "private": false, 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/curvefi/curve-stablecoin-js.git" 12 | }, 13 | "bugs": { 14 | "url": "https://github.com/curvefi/curve-stablecoin-js/issues" 15 | }, 16 | "scripts": { 17 | "build": "rm -rf lib && tsc -p tsconfig.build.json", 18 | "lint": "eslint src" 19 | }, 20 | "devDependencies": { 21 | "@types/chai": "^4.2.18", 22 | "@types/memoizee": "^0.4.7", 23 | "@types/mocha": "^8.2.2", 24 | "@types/node": "^22.10.7", 25 | "@typescript-eslint/eslint-plugin": "^4.33.0", 26 | "@typescript-eslint/parser": "^4.20.0", 27 | "babel-eslint": "^10.1.0", 28 | "chai": "^4.3.4", 29 | "eslint": "^7.32.0", 30 | "mocha": "^8.4.0", 31 | "typescript": "^4.5.2", 32 | "vue-eslint-parser": "^7.6.0" 33 | }, 34 | "dependencies": { 35 | "@ethersproject/networks": "^5.5.0", 36 | "bignumber.js": "^9.0.1", 37 | "ethcall": "^4.2.5", 38 | "ethers": "^5.4.6", 39 | "memoizee": "^0.4.15" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/constants/abis/DeleverageZap.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "stateMutability": "nonpayable", 4 | "type": "constructor", 5 | "inputs": [ 6 | { 7 | "name": "_controller", 8 | "type": "address" 9 | }, 10 | { 11 | "name": "_collateral", 12 | "type": "address" 13 | }, 14 | { 15 | "name": "_router", 16 | "type": "address" 17 | }, 18 | { 19 | "name": "_routes", 20 | "type": "address[11][]" 21 | }, 22 | { 23 | "name": "_route_params", 24 | "type": "uint256[5][5][]" 25 | }, 26 | { 27 | "name": "_route_pools", 28 | "type": "address[5][]" 29 | }, 30 | { 31 | "name": "_route_names", 32 | "type": "string[]" 33 | } 34 | ], 35 | "outputs": [] 36 | }, 37 | { 38 | "stateMutability": "view", 39 | "type": "function", 40 | "name": "get_stablecoins", 41 | "inputs": [ 42 | { 43 | "name": "collateral", 44 | "type": "uint256" 45 | }, 46 | { 47 | "name": "route_idx", 48 | "type": "uint256" 49 | } 50 | ], 51 | "outputs": [ 52 | { 53 | "name": "", 54 | "type": "uint256" 55 | } 56 | ] 57 | }, 58 | { 59 | "stateMutability": "view", 60 | "type": "function", 61 | "name": "calculate_debt_n1", 62 | "inputs": [ 63 | { 64 | "name": "collateral", 65 | "type": "uint256" 66 | }, 67 | { 68 | "name": "route_idx", 69 | "type": "uint256" 70 | }, 71 | { 72 | "name": "user", 73 | "type": "address" 74 | } 75 | ], 76 | "outputs": [ 77 | { 78 | "name": "", 79 | "type": "int256" 80 | } 81 | ] 82 | }, 83 | { 84 | "stateMutability": "nonpayable", 85 | "type": "function", 86 | "name": "callback_repay", 87 | "inputs": [ 88 | { 89 | "name": "user", 90 | "type": "address" 91 | }, 92 | { 93 | "name": "stablecoins", 94 | "type": "uint256" 95 | }, 96 | { 97 | "name": "collateral", 98 | "type": "uint256" 99 | }, 100 | { 101 | "name": "debt", 102 | "type": "uint256" 103 | }, 104 | { 105 | "name": "callback_args", 106 | "type": "uint256[]" 107 | } 108 | ], 109 | "outputs": [ 110 | { 111 | "name": "", 112 | "type": "uint256[2]" 113 | } 114 | ] 115 | }, 116 | { 117 | "stateMutability": "view", 118 | "type": "function", 119 | "name": "CONTROLLER", 120 | "inputs": [], 121 | "outputs": [ 122 | { 123 | "name": "", 124 | "type": "address" 125 | } 126 | ] 127 | }, 128 | { 129 | "stateMutability": "view", 130 | "type": "function", 131 | "name": "COLLATERAL", 132 | "inputs": [], 133 | "outputs": [ 134 | { 135 | "name": "", 136 | "type": "address" 137 | } 138 | ] 139 | }, 140 | { 141 | "stateMutability": "view", 142 | "type": "function", 143 | "name": "ROUTER", 144 | "inputs": [], 145 | "outputs": [ 146 | { 147 | "name": "", 148 | "type": "address" 149 | } 150 | ] 151 | }, 152 | { 153 | "stateMutability": "view", 154 | "type": "function", 155 | "name": "routes", 156 | "inputs": [ 157 | { 158 | "name": "arg0", 159 | "type": "uint256" 160 | }, 161 | { 162 | "name": "arg1", 163 | "type": "uint256" 164 | } 165 | ], 166 | "outputs": [ 167 | { 168 | "name": "", 169 | "type": "address" 170 | } 171 | ] 172 | }, 173 | { 174 | "stateMutability": "view", 175 | "type": "function", 176 | "name": "route_params", 177 | "inputs": [ 178 | { 179 | "name": "arg0", 180 | "type": "uint256" 181 | }, 182 | { 183 | "name": "arg1", 184 | "type": "uint256" 185 | }, 186 | { 187 | "name": "arg2", 188 | "type": "uint256" 189 | } 190 | ], 191 | "outputs": [ 192 | { 193 | "name": "", 194 | "type": "uint256" 195 | } 196 | ] 197 | }, 198 | { 199 | "stateMutability": "view", 200 | "type": "function", 201 | "name": "route_pools", 202 | "inputs": [ 203 | { 204 | "name": "arg0", 205 | "type": "uint256" 206 | }, 207 | { 208 | "name": "arg1", 209 | "type": "uint256" 210 | } 211 | ], 212 | "outputs": [ 213 | { 214 | "name": "", 215 | "type": "address" 216 | } 217 | ] 218 | }, 219 | { 220 | "stateMutability": "view", 221 | "type": "function", 222 | "name": "route_names", 223 | "inputs": [ 224 | { 225 | "name": "arg0", 226 | "type": "uint256" 227 | } 228 | ], 229 | "outputs": [ 230 | { 231 | "name": "", 232 | "type": "string" 233 | } 234 | ] 235 | }, 236 | { 237 | "stateMutability": "view", 238 | "type": "function", 239 | "name": "routes_count", 240 | "inputs": [], 241 | "outputs": [ 242 | { 243 | "name": "", 244 | "type": "uint256" 245 | } 246 | ] 247 | } 248 | ] -------------------------------------------------------------------------------- /src/constants/abis/ERC20.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "constant": true, 4 | "inputs": [], 5 | "name": "name", 6 | "outputs": [ 7 | { 8 | "name": "", 9 | "type": "string" 10 | } 11 | ], 12 | "payable": false, 13 | "stateMutability": "view", 14 | "type": "function" 15 | }, 16 | { 17 | "constant": false, 18 | "inputs": [ 19 | { 20 | "name": "_spender", 21 | "type": "address" 22 | }, 23 | { 24 | "name": "_value", 25 | "type": "uint256" 26 | } 27 | ], 28 | "name": "approve", 29 | "outputs": [ 30 | { 31 | "name": "", 32 | "type": "bool" 33 | } 34 | ], 35 | "payable": false, 36 | "stateMutability": "nonpayable", 37 | "type": "function" 38 | }, 39 | { 40 | "constant": true, 41 | "inputs": [], 42 | "name": "totalSupply", 43 | "outputs": [ 44 | { 45 | "name": "", 46 | "type": "uint256" 47 | } 48 | ], 49 | "payable": false, 50 | "stateMutability": "view", 51 | "type": "function" 52 | }, 53 | { 54 | "constant": false, 55 | "inputs": [ 56 | { 57 | "name": "_from", 58 | "type": "address" 59 | }, 60 | { 61 | "name": "_to", 62 | "type": "address" 63 | }, 64 | { 65 | "name": "_value", 66 | "type": "uint256" 67 | } 68 | ], 69 | "name": "transferFrom", 70 | "outputs": [ 71 | { 72 | "name": "", 73 | "type": "bool" 74 | } 75 | ], 76 | "payable": false, 77 | "stateMutability": "nonpayable", 78 | "type": "function" 79 | }, 80 | { 81 | "constant": true, 82 | "inputs": [], 83 | "name": "decimals", 84 | "outputs": [ 85 | { 86 | "name": "", 87 | "type": "uint8" 88 | } 89 | ], 90 | "payable": false, 91 | "stateMutability": "view", 92 | "type": "function" 93 | }, 94 | { 95 | "constant": true, 96 | "inputs": [ 97 | { 98 | "name": "_owner", 99 | "type": "address" 100 | } 101 | ], 102 | "name": "balanceOf", 103 | "outputs": [ 104 | { 105 | "name": "balance", 106 | "type": "uint256" 107 | } 108 | ], 109 | "payable": false, 110 | "stateMutability": "view", 111 | "type": "function" 112 | }, 113 | { 114 | "constant": true, 115 | "inputs": [], 116 | "name": "symbol", 117 | "outputs": [ 118 | { 119 | "name": "", 120 | "type": "string" 121 | } 122 | ], 123 | "payable": false, 124 | "stateMutability": "view", 125 | "type": "function" 126 | }, 127 | { 128 | "constant": false, 129 | "inputs": [ 130 | { 131 | "name": "_to", 132 | "type": "address" 133 | }, 134 | { 135 | "name": "_value", 136 | "type": "uint256" 137 | } 138 | ], 139 | "name": "transfer", 140 | "outputs": [ 141 | { 142 | "name": "", 143 | "type": "bool" 144 | } 145 | ], 146 | "payable": false, 147 | "stateMutability": "nonpayable", 148 | "type": "function" 149 | }, 150 | { 151 | "constant": true, 152 | "inputs": [ 153 | { 154 | "name": "_owner", 155 | "type": "address" 156 | }, 157 | { 158 | "name": "_spender", 159 | "type": "address" 160 | } 161 | ], 162 | "name": "allowance", 163 | "outputs": [ 164 | { 165 | "name": "", 166 | "type": "uint256" 167 | } 168 | ], 169 | "payable": false, 170 | "stateMutability": "view", 171 | "type": "function" 172 | }, 173 | { 174 | "payable": true, 175 | "stateMutability": "payable", 176 | "type": "fallback" 177 | }, 178 | { 179 | "anonymous": false, 180 | "inputs": [ 181 | { 182 | "indexed": true, 183 | "name": "owner", 184 | "type": "address" 185 | }, 186 | { 187 | "indexed": true, 188 | "name": "spender", 189 | "type": "address" 190 | }, 191 | { 192 | "indexed": false, 193 | "name": "value", 194 | "type": "uint256" 195 | } 196 | ], 197 | "name": "Approval", 198 | "type": "event" 199 | }, 200 | { 201 | "anonymous": false, 202 | "inputs": [ 203 | { 204 | "indexed": true, 205 | "name": "from", 206 | "type": "address" 207 | }, 208 | { 209 | "indexed": true, 210 | "name": "to", 211 | "type": "address" 212 | }, 213 | { 214 | "indexed": false, 215 | "name": "value", 216 | "type": "uint256" 217 | } 218 | ], 219 | "name": "Transfer", 220 | "type": "event" 221 | } 222 | ] 223 | -------------------------------------------------------------------------------- /src/constants/abis/Factory.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "AddMarket", 4 | "inputs": [ 5 | { 6 | "name": "collateral", 7 | "type": "address", 8 | "indexed": true 9 | }, 10 | { 11 | "name": "controller", 12 | "type": "address", 13 | "indexed": false 14 | }, 15 | { 16 | "name": "amm", 17 | "type": "address", 18 | "indexed": false 19 | }, 20 | { 21 | "name": "monetary_policy", 22 | "type": "address", 23 | "indexed": false 24 | }, 25 | { 26 | "name": "ix", 27 | "type": "uint256", 28 | "indexed": false 29 | } 30 | ], 31 | "anonymous": false, 32 | "type": "event" 33 | }, 34 | { 35 | "name": "SetDebtCeiling", 36 | "inputs": [ 37 | { 38 | "name": "addr", 39 | "type": "address", 40 | "indexed": true 41 | }, 42 | { 43 | "name": "debt_ceiling", 44 | "type": "uint256", 45 | "indexed": false 46 | } 47 | ], 48 | "anonymous": false, 49 | "type": "event" 50 | }, 51 | { 52 | "name": "MintForMarket", 53 | "inputs": [ 54 | { 55 | "name": "addr", 56 | "type": "address", 57 | "indexed": true 58 | }, 59 | { 60 | "name": "amount", 61 | "type": "uint256", 62 | "indexed": false 63 | } 64 | ], 65 | "anonymous": false, 66 | "type": "event" 67 | }, 68 | { 69 | "name": "RemoveFromMarket", 70 | "inputs": [ 71 | { 72 | "name": "addr", 73 | "type": "address", 74 | "indexed": true 75 | }, 76 | { 77 | "name": "amount", 78 | "type": "uint256", 79 | "indexed": false 80 | } 81 | ], 82 | "anonymous": false, 83 | "type": "event" 84 | }, 85 | { 86 | "name": "SetImplementations", 87 | "inputs": [ 88 | { 89 | "name": "amm", 90 | "type": "address", 91 | "indexed": false 92 | }, 93 | { 94 | "name": "controller", 95 | "type": "address", 96 | "indexed": false 97 | } 98 | ], 99 | "anonymous": false, 100 | "type": "event" 101 | }, 102 | { 103 | "name": "SetAdmin", 104 | "inputs": [ 105 | { 106 | "name": "admin", 107 | "type": "address", 108 | "indexed": false 109 | } 110 | ], 111 | "anonymous": false, 112 | "type": "event" 113 | }, 114 | { 115 | "name": "SetFeeReceiver", 116 | "inputs": [ 117 | { 118 | "name": "fee_receiver", 119 | "type": "address", 120 | "indexed": false 121 | } 122 | ], 123 | "anonymous": false, 124 | "type": "event" 125 | }, 126 | { 127 | "stateMutability": "nonpayable", 128 | "type": "constructor", 129 | "inputs": [ 130 | { 131 | "name": "stablecoin", 132 | "type": "address" 133 | }, 134 | { 135 | "name": "admin", 136 | "type": "address" 137 | }, 138 | { 139 | "name": "fee_receiver", 140 | "type": "address" 141 | }, 142 | { 143 | "name": "weth", 144 | "type": "address" 145 | } 146 | ], 147 | "outputs": [] 148 | }, 149 | { 150 | "stateMutability": "view", 151 | "type": "function", 152 | "name": "stablecoin", 153 | "inputs": [], 154 | "outputs": [ 155 | { 156 | "name": "", 157 | "type": "address" 158 | } 159 | ] 160 | }, 161 | { 162 | "stateMutability": "nonpayable", 163 | "type": "function", 164 | "name": "add_market", 165 | "inputs": [ 166 | { 167 | "name": "token", 168 | "type": "address" 169 | }, 170 | { 171 | "name": "A", 172 | "type": "uint256" 173 | }, 174 | { 175 | "name": "fee", 176 | "type": "uint256" 177 | }, 178 | { 179 | "name": "admin_fee", 180 | "type": "uint256" 181 | }, 182 | { 183 | "name": "_price_oracle_contract", 184 | "type": "address" 185 | }, 186 | { 187 | "name": "monetary_policy", 188 | "type": "address" 189 | }, 190 | { 191 | "name": "loan_discount", 192 | "type": "uint256" 193 | }, 194 | { 195 | "name": "liquidation_discount", 196 | "type": "uint256" 197 | }, 198 | { 199 | "name": "debt_ceiling", 200 | "type": "uint256" 201 | } 202 | ], 203 | "outputs": [ 204 | { 205 | "name": "", 206 | "type": "address[2]" 207 | } 208 | ] 209 | }, 210 | { 211 | "stateMutability": "view", 212 | "type": "function", 213 | "name": "total_debt", 214 | "inputs": [], 215 | "outputs": [ 216 | { 217 | "name": "", 218 | "type": "uint256" 219 | } 220 | ] 221 | }, 222 | { 223 | "stateMutability": "view", 224 | "type": "function", 225 | "name": "get_controller", 226 | "inputs": [ 227 | { 228 | "name": "collateral", 229 | "type": "address" 230 | } 231 | ], 232 | "outputs": [ 233 | { 234 | "name": "", 235 | "type": "address" 236 | } 237 | ] 238 | }, 239 | { 240 | "stateMutability": "view", 241 | "type": "function", 242 | "name": "get_amm", 243 | "inputs": [ 244 | { 245 | "name": "collateral", 246 | "type": "address" 247 | } 248 | ], 249 | "outputs": [ 250 | { 251 | "name": "", 252 | "type": "address" 253 | } 254 | ] 255 | }, 256 | { 257 | "stateMutability": "nonpayable", 258 | "type": "function", 259 | "name": "set_implementations", 260 | "inputs": [ 261 | { 262 | "name": "controller", 263 | "type": "address" 264 | }, 265 | { 266 | "name": "amm", 267 | "type": "address" 268 | } 269 | ], 270 | "outputs": [] 271 | }, 272 | { 273 | "stateMutability": "nonpayable", 274 | "type": "function", 275 | "name": "set_admin", 276 | "inputs": [ 277 | { 278 | "name": "admin", 279 | "type": "address" 280 | } 281 | ], 282 | "outputs": [] 283 | }, 284 | { 285 | "stateMutability": "nonpayable", 286 | "type": "function", 287 | "name": "set_fee_receiver", 288 | "inputs": [ 289 | { 290 | "name": "fee_receiver", 291 | "type": "address" 292 | } 293 | ], 294 | "outputs": [] 295 | }, 296 | { 297 | "stateMutability": "nonpayable", 298 | "type": "function", 299 | "name": "set_debt_ceiling", 300 | "inputs": [ 301 | { 302 | "name": "_to", 303 | "type": "address" 304 | }, 305 | { 306 | "name": "debt_ceiling", 307 | "type": "uint256" 308 | } 309 | ], 310 | "outputs": [] 311 | }, 312 | { 313 | "stateMutability": "nonpayable", 314 | "type": "function", 315 | "name": "rug_debt_ceiling", 316 | "inputs": [ 317 | { 318 | "name": "_to", 319 | "type": "address" 320 | } 321 | ], 322 | "outputs": [] 323 | }, 324 | { 325 | "stateMutability": "nonpayable", 326 | "type": "function", 327 | "name": "collect_fees_above_ceiling", 328 | "inputs": [ 329 | { 330 | "name": "_to", 331 | "type": "address" 332 | } 333 | ], 334 | "outputs": [] 335 | }, 336 | { 337 | "stateMutability": "view", 338 | "type": "function", 339 | "name": "controllers", 340 | "inputs": [ 341 | { 342 | "name": "arg0", 343 | "type": "uint256" 344 | } 345 | ], 346 | "outputs": [ 347 | { 348 | "name": "", 349 | "type": "address" 350 | } 351 | ] 352 | }, 353 | { 354 | "stateMutability": "view", 355 | "type": "function", 356 | "name": "amms", 357 | "inputs": [ 358 | { 359 | "name": "arg0", 360 | "type": "uint256" 361 | } 362 | ], 363 | "outputs": [ 364 | { 365 | "name": "", 366 | "type": "address" 367 | } 368 | ] 369 | }, 370 | { 371 | "stateMutability": "view", 372 | "type": "function", 373 | "name": "admin", 374 | "inputs": [], 375 | "outputs": [ 376 | { 377 | "name": "", 378 | "type": "address" 379 | } 380 | ] 381 | }, 382 | { 383 | "stateMutability": "view", 384 | "type": "function", 385 | "name": "fee_receiver", 386 | "inputs": [], 387 | "outputs": [ 388 | { 389 | "name": "", 390 | "type": "address" 391 | } 392 | ] 393 | }, 394 | { 395 | "stateMutability": "view", 396 | "type": "function", 397 | "name": "controller_implementation", 398 | "inputs": [], 399 | "outputs": [ 400 | { 401 | "name": "", 402 | "type": "address" 403 | } 404 | ] 405 | }, 406 | { 407 | "stateMutability": "view", 408 | "type": "function", 409 | "name": "amm_implementation", 410 | "inputs": [], 411 | "outputs": [ 412 | { 413 | "name": "", 414 | "type": "address" 415 | } 416 | ] 417 | }, 418 | { 419 | "stateMutability": "view", 420 | "type": "function", 421 | "name": "n_collaterals", 422 | "inputs": [], 423 | "outputs": [ 424 | { 425 | "name": "", 426 | "type": "uint256" 427 | } 428 | ] 429 | }, 430 | { 431 | "stateMutability": "view", 432 | "type": "function", 433 | "name": "collaterals", 434 | "inputs": [ 435 | { 436 | "name": "arg0", 437 | "type": "uint256" 438 | } 439 | ], 440 | "outputs": [ 441 | { 442 | "name": "", 443 | "type": "address" 444 | } 445 | ] 446 | }, 447 | { 448 | "stateMutability": "view", 449 | "type": "function", 450 | "name": "collaterals_index", 451 | "inputs": [ 452 | { 453 | "name": "arg0", 454 | "type": "address" 455 | }, 456 | { 457 | "name": "arg1", 458 | "type": "uint256" 459 | } 460 | ], 461 | "outputs": [ 462 | { 463 | "name": "", 464 | "type": "uint256" 465 | } 466 | ] 467 | }, 468 | { 469 | "stateMutability": "view", 470 | "type": "function", 471 | "name": "debt_ceiling", 472 | "inputs": [ 473 | { 474 | "name": "arg0", 475 | "type": "address" 476 | } 477 | ], 478 | "outputs": [ 479 | { 480 | "name": "", 481 | "type": "uint256" 482 | } 483 | ] 484 | }, 485 | { 486 | "stateMutability": "view", 487 | "type": "function", 488 | "name": "debt_ceiling_residual", 489 | "inputs": [ 490 | { 491 | "name": "arg0", 492 | "type": "address" 493 | } 494 | ], 495 | "outputs": [ 496 | { 497 | "name": "", 498 | "type": "uint256" 499 | } 500 | ] 501 | }, 502 | { 503 | "stateMutability": "view", 504 | "type": "function", 505 | "name": "WETH", 506 | "inputs": [], 507 | "outputs": [ 508 | { 509 | "name": "", 510 | "type": "address" 511 | } 512 | ] 513 | } 514 | ] -------------------------------------------------------------------------------- /src/constants/abis/HealthCalculatorZap.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "stateMutability": "nonpayable", 4 | "type": "constructor", 5 | "inputs": [ 6 | { 7 | "name": "amm", 8 | "type": "address" 9 | }, 10 | { 11 | "name": "controller", 12 | "type": "address" 13 | }, 14 | { 15 | "name": "collateral_token", 16 | "type": "address" 17 | } 18 | ], 19 | "outputs": [] 20 | }, 21 | { 22 | "stateMutability": "view", 23 | "type": "function", 24 | "name": "health_calculator", 25 | "inputs": [ 26 | { 27 | "name": "user", 28 | "type": "address" 29 | }, 30 | { 31 | "name": "d_collateral", 32 | "type": "int256" 33 | }, 34 | { 35 | "name": "d_debt", 36 | "type": "int256" 37 | }, 38 | { 39 | "name": "full", 40 | "type": "bool" 41 | }, 42 | { 43 | "name": "N", 44 | "type": "uint256" 45 | } 46 | ], 47 | "outputs": [ 48 | { 49 | "name": "", 50 | "type": "int256" 51 | } 52 | ] 53 | } 54 | ] -------------------------------------------------------------------------------- /src/constants/abis/LeverageZap.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "stateMutability": "nonpayable", 4 | "type": "constructor", 5 | "inputs": [ 6 | { 7 | "name": "_controller", 8 | "type": "address" 9 | }, 10 | { 11 | "name": "_collateral", 12 | "type": "address" 13 | }, 14 | { 15 | "name": "_router", 16 | "type": "address" 17 | }, 18 | { 19 | "name": "_routes", 20 | "type": "address[9][]" 21 | }, 22 | { 23 | "name": "_route_params", 24 | "type": "uint256[3][4][]" 25 | }, 26 | { 27 | "name": "_route_pools", 28 | "type": "address[4][]" 29 | }, 30 | { 31 | "name": "_route_names", 32 | "type": "string[]" 33 | } 34 | ], 35 | "outputs": [] 36 | }, 37 | { 38 | "stateMutability": "view", 39 | "type": "function", 40 | "name": "get_collateral", 41 | "inputs": [ 42 | { 43 | "name": "stablecoin", 44 | "type": "uint256" 45 | }, 46 | { 47 | "name": "route_idx", 48 | "type": "uint256" 49 | } 50 | ], 51 | "outputs": [ 52 | { 53 | "name": "", 54 | "type": "uint256" 55 | } 56 | ] 57 | }, 58 | { 59 | "stateMutability": "view", 60 | "type": "function", 61 | "name": "get_collateral_underlying", 62 | "inputs": [ 63 | { 64 | "name": "stablecoin", 65 | "type": "uint256" 66 | }, 67 | { 68 | "name": "route_idx", 69 | "type": "uint256" 70 | } 71 | ], 72 | "outputs": [ 73 | { 74 | "name": "", 75 | "type": "uint256" 76 | } 77 | ] 78 | }, 79 | { 80 | "stateMutability": "view", 81 | "type": "function", 82 | "name": "calculate_debt_n1", 83 | "inputs": [ 84 | { 85 | "name": "collateral", 86 | "type": "uint256" 87 | }, 88 | { 89 | "name": "debt", 90 | "type": "uint256" 91 | }, 92 | { 93 | "name": "N", 94 | "type": "uint256" 95 | }, 96 | { 97 | "name": "route_idx", 98 | "type": "uint256" 99 | } 100 | ], 101 | "outputs": [ 102 | { 103 | "name": "", 104 | "type": "int256" 105 | } 106 | ] 107 | }, 108 | { 109 | "stateMutability": "view", 110 | "type": "function", 111 | "name": "max_borrowable", 112 | "inputs": [ 113 | { 114 | "name": "collateral", 115 | "type": "uint256" 116 | }, 117 | { 118 | "name": "N", 119 | "type": "uint256" 120 | }, 121 | { 122 | "name": "route_idx", 123 | "type": "uint256" 124 | } 125 | ], 126 | "outputs": [ 127 | { 128 | "name": "", 129 | "type": "uint256" 130 | } 131 | ] 132 | }, 133 | { 134 | "stateMutability": "view", 135 | "type": "function", 136 | "name": "max_collateral", 137 | "inputs": [ 138 | { 139 | "name": "collateral", 140 | "type": "uint256" 141 | }, 142 | { 143 | "name": "N", 144 | "type": "uint256" 145 | }, 146 | { 147 | "name": "route_idx", 148 | "type": "uint256" 149 | } 150 | ], 151 | "outputs": [ 152 | { 153 | "name": "", 154 | "type": "uint256" 155 | } 156 | ] 157 | }, 158 | { 159 | "stateMutability": "view", 160 | "type": "function", 161 | "name": "max_borrowable_and_collateral", 162 | "inputs": [ 163 | { 164 | "name": "collateral", 165 | "type": "uint256" 166 | }, 167 | { 168 | "name": "N", 169 | "type": "uint256" 170 | }, 171 | { 172 | "name": "route_idx", 173 | "type": "uint256" 174 | } 175 | ], 176 | "outputs": [ 177 | { 178 | "name": "", 179 | "type": "uint256[2]" 180 | } 181 | ] 182 | }, 183 | { 184 | "stateMutability": "nonpayable", 185 | "type": "function", 186 | "name": "callback_deposit", 187 | "inputs": [ 188 | { 189 | "name": "user", 190 | "type": "address" 191 | }, 192 | { 193 | "name": "stablecoins", 194 | "type": "uint256" 195 | }, 196 | { 197 | "name": "collateral", 198 | "type": "uint256" 199 | }, 200 | { 201 | "name": "debt", 202 | "type": "uint256" 203 | }, 204 | { 205 | "name": "callback_args", 206 | "type": "uint256[]" 207 | } 208 | ], 209 | "outputs": [ 210 | { 211 | "name": "", 212 | "type": "uint256[2]" 213 | } 214 | ] 215 | }, 216 | { 217 | "stateMutability": "view", 218 | "type": "function", 219 | "name": "routes", 220 | "inputs": [ 221 | { 222 | "name": "arg0", 223 | "type": "uint256" 224 | }, 225 | { 226 | "name": "arg1", 227 | "type": "uint256" 228 | } 229 | ], 230 | "outputs": [ 231 | { 232 | "name": "", 233 | "type": "address" 234 | } 235 | ] 236 | }, 237 | { 238 | "stateMutability": "view", 239 | "type": "function", 240 | "name": "route_params", 241 | "inputs": [ 242 | { 243 | "name": "arg0", 244 | "type": "uint256" 245 | }, 246 | { 247 | "name": "arg1", 248 | "type": "uint256" 249 | }, 250 | { 251 | "name": "arg2", 252 | "type": "uint256" 253 | } 254 | ], 255 | "outputs": [ 256 | { 257 | "name": "", 258 | "type": "uint256" 259 | } 260 | ] 261 | }, 262 | { 263 | "stateMutability": "view", 264 | "type": "function", 265 | "name": "route_pools", 266 | "inputs": [ 267 | { 268 | "name": "arg0", 269 | "type": "uint256" 270 | }, 271 | { 272 | "name": "arg1", 273 | "type": "uint256" 274 | } 275 | ], 276 | "outputs": [ 277 | { 278 | "name": "", 279 | "type": "address" 280 | } 281 | ] 282 | }, 283 | { 284 | "stateMutability": "view", 285 | "type": "function", 286 | "name": "route_names", 287 | "inputs": [ 288 | { 289 | "name": "arg0", 290 | "type": "uint256" 291 | } 292 | ], 293 | "outputs": [ 294 | { 295 | "name": "", 296 | "type": "string" 297 | } 298 | ] 299 | }, 300 | { 301 | "stateMutability": "view", 302 | "type": "function", 303 | "name": "routes_count", 304 | "inputs": [], 305 | "outputs": [ 306 | { 307 | "name": "", 308 | "type": "uint256" 309 | } 310 | ] 311 | } 312 | ] -------------------------------------------------------------------------------- /src/constants/abis/MonetaryPolicy.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "SetAdmin", 4 | "inputs": [ 5 | { 6 | "name": "admin", 7 | "type": "address", 8 | "indexed": false 9 | } 10 | ], 11 | "anonymous": false, 12 | "type": "event" 13 | }, 14 | { 15 | "name": "AddPegKeeper", 16 | "inputs": [ 17 | { 18 | "name": "peg_keeper", 19 | "type": "address", 20 | "indexed": true 21 | } 22 | ], 23 | "anonymous": false, 24 | "type": "event" 25 | }, 26 | { 27 | "name": "RemovePegKeeper", 28 | "inputs": [ 29 | { 30 | "name": "peg_keeper", 31 | "type": "address", 32 | "indexed": true 33 | } 34 | ], 35 | "anonymous": false, 36 | "type": "event" 37 | }, 38 | { 39 | "name": "SetRate", 40 | "inputs": [ 41 | { 42 | "name": "rate", 43 | "type": "uint256", 44 | "indexed": false 45 | } 46 | ], 47 | "anonymous": false, 48 | "type": "event" 49 | }, 50 | { 51 | "name": "SetSigma", 52 | "inputs": [ 53 | { 54 | "name": "sigma", 55 | "type": "uint256", 56 | "indexed": false 57 | } 58 | ], 59 | "anonymous": false, 60 | "type": "event" 61 | }, 62 | { 63 | "name": "SetTargetDebtFraction", 64 | "inputs": [ 65 | { 66 | "name": "target_debt_fraction", 67 | "type": "uint256", 68 | "indexed": false 69 | } 70 | ], 71 | "anonymous": false, 72 | "type": "event" 73 | }, 74 | { 75 | "stateMutability": "nonpayable", 76 | "type": "constructor", 77 | "inputs": [ 78 | { 79 | "name": "admin", 80 | "type": "address" 81 | }, 82 | { 83 | "name": "price_oracle", 84 | "type": "address" 85 | }, 86 | { 87 | "name": "controller_factory", 88 | "type": "address" 89 | }, 90 | { 91 | "name": "peg_keepers", 92 | "type": "address[5]" 93 | }, 94 | { 95 | "name": "rate", 96 | "type": "uint256" 97 | }, 98 | { 99 | "name": "sigma", 100 | "type": "uint256" 101 | }, 102 | { 103 | "name": "target_debt_fraction", 104 | "type": "uint256" 105 | } 106 | ], 107 | "outputs": [] 108 | }, 109 | { 110 | "stateMutability": "nonpayable", 111 | "type": "function", 112 | "name": "set_admin", 113 | "inputs": [ 114 | { 115 | "name": "admin", 116 | "type": "address" 117 | } 118 | ], 119 | "outputs": [] 120 | }, 121 | { 122 | "stateMutability": "nonpayable", 123 | "type": "function", 124 | "name": "add_peg_keeper", 125 | "inputs": [ 126 | { 127 | "name": "pk", 128 | "type": "address" 129 | } 130 | ], 131 | "outputs": [] 132 | }, 133 | { 134 | "stateMutability": "nonpayable", 135 | "type": "function", 136 | "name": "remove_peg_keeper", 137 | "inputs": [ 138 | { 139 | "name": "pk", 140 | "type": "address" 141 | } 142 | ], 143 | "outputs": [] 144 | }, 145 | { 146 | "stateMutability": "view", 147 | "type": "function", 148 | "name": "rate", 149 | "inputs": [], 150 | "outputs": [ 151 | { 152 | "name": "", 153 | "type": "uint256" 154 | } 155 | ] 156 | }, 157 | { 158 | "stateMutability": "nonpayable", 159 | "type": "function", 160 | "name": "rate_write", 161 | "inputs": [], 162 | "outputs": [ 163 | { 164 | "name": "", 165 | "type": "uint256" 166 | } 167 | ] 168 | }, 169 | { 170 | "stateMutability": "nonpayable", 171 | "type": "function", 172 | "name": "set_rate", 173 | "inputs": [ 174 | { 175 | "name": "rate", 176 | "type": "uint256" 177 | } 178 | ], 179 | "outputs": [] 180 | }, 181 | { 182 | "stateMutability": "nonpayable", 183 | "type": "function", 184 | "name": "set_sigma", 185 | "inputs": [ 186 | { 187 | "name": "sigma", 188 | "type": "uint256" 189 | } 190 | ], 191 | "outputs": [] 192 | }, 193 | { 194 | "stateMutability": "nonpayable", 195 | "type": "function", 196 | "name": "set_target_debt_fraction", 197 | "inputs": [ 198 | { 199 | "name": "target_debt_fraction", 200 | "type": "uint256" 201 | } 202 | ], 203 | "outputs": [] 204 | }, 205 | { 206 | "stateMutability": "view", 207 | "type": "function", 208 | "name": "admin", 209 | "inputs": [], 210 | "outputs": [ 211 | { 212 | "name": "", 213 | "type": "address" 214 | } 215 | ] 216 | }, 217 | { 218 | "stateMutability": "view", 219 | "type": "function", 220 | "name": "rate0", 221 | "inputs": [], 222 | "outputs": [ 223 | { 224 | "name": "", 225 | "type": "uint256" 226 | } 227 | ] 228 | }, 229 | { 230 | "stateMutability": "view", 231 | "type": "function", 232 | "name": "sigma", 233 | "inputs": [], 234 | "outputs": [ 235 | { 236 | "name": "", 237 | "type": "int256" 238 | } 239 | ] 240 | }, 241 | { 242 | "stateMutability": "view", 243 | "type": "function", 244 | "name": "target_debt_fraction", 245 | "inputs": [], 246 | "outputs": [ 247 | { 248 | "name": "", 249 | "type": "uint256" 250 | } 251 | ] 252 | }, 253 | { 254 | "stateMutability": "view", 255 | "type": "function", 256 | "name": "peg_keepers", 257 | "inputs": [ 258 | { 259 | "name": "arg0", 260 | "type": "uint256" 261 | } 262 | ], 263 | "outputs": [ 264 | { 265 | "name": "", 266 | "type": "address" 267 | } 268 | ] 269 | }, 270 | { 271 | "stateMutability": "view", 272 | "type": "function", 273 | "name": "PRICE_ORACLE", 274 | "inputs": [], 275 | "outputs": [ 276 | { 277 | "name": "", 278 | "type": "address" 279 | } 280 | ] 281 | }, 282 | { 283 | "stateMutability": "view", 284 | "type": "function", 285 | "name": "CONTROLLER_FACTORY", 286 | "inputs": [], 287 | "outputs": [ 288 | { 289 | "name": "", 290 | "type": "address" 291 | } 292 | ] 293 | } 294 | ] -------------------------------------------------------------------------------- /src/constants/abis/MonetaryPolicy2.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "SetAdmin", 4 | "inputs": [ 5 | { 6 | "name": "admin", 7 | "type": "address", 8 | "indexed": false 9 | } 10 | ], 11 | "anonymous": false, 12 | "type": "event" 13 | }, 14 | { 15 | "name": "AddPegKeeper", 16 | "inputs": [ 17 | { 18 | "name": "peg_keeper", 19 | "type": "address", 20 | "indexed": true 21 | } 22 | ], 23 | "anonymous": false, 24 | "type": "event" 25 | }, 26 | { 27 | "name": "RemovePegKeeper", 28 | "inputs": [ 29 | { 30 | "name": "peg_keeper", 31 | "type": "address", 32 | "indexed": true 33 | } 34 | ], 35 | "anonymous": false, 36 | "type": "event" 37 | }, 38 | { 39 | "name": "SetRate", 40 | "inputs": [ 41 | { 42 | "name": "rate", 43 | "type": "uint256", 44 | "indexed": false 45 | } 46 | ], 47 | "anonymous": false, 48 | "type": "event" 49 | }, 50 | { 51 | "name": "SetSigma", 52 | "inputs": [ 53 | { 54 | "name": "sigma", 55 | "type": "uint256", 56 | "indexed": false 57 | } 58 | ], 59 | "anonymous": false, 60 | "type": "event" 61 | }, 62 | { 63 | "name": "SetTargetDebtFraction", 64 | "inputs": [ 65 | { 66 | "name": "target_debt_fraction", 67 | "type": "uint256", 68 | "indexed": false 69 | } 70 | ], 71 | "anonymous": false, 72 | "type": "event" 73 | }, 74 | { 75 | "stateMutability": "nonpayable", 76 | "type": "constructor", 77 | "inputs": [ 78 | { 79 | "name": "admin", 80 | "type": "address" 81 | }, 82 | { 83 | "name": "price_oracle", 84 | "type": "address" 85 | }, 86 | { 87 | "name": "controller_factory", 88 | "type": "address" 89 | }, 90 | { 91 | "name": "peg_keepers", 92 | "type": "address[5]" 93 | }, 94 | { 95 | "name": "rate", 96 | "type": "uint256" 97 | }, 98 | { 99 | "name": "sigma", 100 | "type": "uint256" 101 | }, 102 | { 103 | "name": "target_debt_fraction", 104 | "type": "uint256" 105 | } 106 | ], 107 | "outputs": [] 108 | }, 109 | { 110 | "stateMutability": "nonpayable", 111 | "type": "function", 112 | "name": "set_admin", 113 | "inputs": [ 114 | { 115 | "name": "admin", 116 | "type": "address" 117 | } 118 | ], 119 | "outputs": [] 120 | }, 121 | { 122 | "stateMutability": "nonpayable", 123 | "type": "function", 124 | "name": "add_peg_keeper", 125 | "inputs": [ 126 | { 127 | "name": "pk", 128 | "type": "address" 129 | } 130 | ], 131 | "outputs": [] 132 | }, 133 | { 134 | "stateMutability": "nonpayable", 135 | "type": "function", 136 | "name": "remove_peg_keeper", 137 | "inputs": [ 138 | { 139 | "name": "pk", 140 | "type": "address" 141 | } 142 | ], 143 | "outputs": [] 144 | }, 145 | { 146 | "stateMutability": "view", 147 | "type": "function", 148 | "name": "rate", 149 | "inputs": [ 150 | { 151 | "name": "_for", 152 | "type": "address" 153 | } 154 | ], 155 | "outputs": [ 156 | { 157 | "name": "", 158 | "type": "uint256" 159 | } 160 | ] 161 | }, 162 | { 163 | "stateMutability": "nonpayable", 164 | "type": "function", 165 | "name": "rate_write", 166 | "inputs": [], 167 | "outputs": [ 168 | { 169 | "name": "", 170 | "type": "uint256" 171 | } 172 | ] 173 | }, 174 | { 175 | "stateMutability": "nonpayable", 176 | "type": "function", 177 | "name": "set_rate", 178 | "inputs": [ 179 | { 180 | "name": "rate", 181 | "type": "uint256" 182 | } 183 | ], 184 | "outputs": [] 185 | }, 186 | { 187 | "stateMutability": "nonpayable", 188 | "type": "function", 189 | "name": "set_sigma", 190 | "inputs": [ 191 | { 192 | "name": "sigma", 193 | "type": "uint256" 194 | } 195 | ], 196 | "outputs": [] 197 | }, 198 | { 199 | "stateMutability": "nonpayable", 200 | "type": "function", 201 | "name": "set_target_debt_fraction", 202 | "inputs": [ 203 | { 204 | "name": "target_debt_fraction", 205 | "type": "uint256" 206 | } 207 | ], 208 | "outputs": [] 209 | }, 210 | { 211 | "stateMutability": "view", 212 | "type": "function", 213 | "name": "admin", 214 | "inputs": [], 215 | "outputs": [ 216 | { 217 | "name": "", 218 | "type": "address" 219 | } 220 | ] 221 | }, 222 | { 223 | "stateMutability": "view", 224 | "type": "function", 225 | "name": "rate0", 226 | "inputs": [], 227 | "outputs": [ 228 | { 229 | "name": "", 230 | "type": "uint256" 231 | } 232 | ] 233 | }, 234 | { 235 | "stateMutability": "view", 236 | "type": "function", 237 | "name": "sigma", 238 | "inputs": [], 239 | "outputs": [ 240 | { 241 | "name": "", 242 | "type": "int256" 243 | } 244 | ] 245 | }, 246 | { 247 | "stateMutability": "view", 248 | "type": "function", 249 | "name": "target_debt_fraction", 250 | "inputs": [], 251 | "outputs": [ 252 | { 253 | "name": "", 254 | "type": "uint256" 255 | } 256 | ] 257 | }, 258 | { 259 | "stateMutability": "view", 260 | "type": "function", 261 | "name": "peg_keepers", 262 | "inputs": [ 263 | { 264 | "name": "arg0", 265 | "type": "uint256" 266 | } 267 | ], 268 | "outputs": [ 269 | { 270 | "name": "", 271 | "type": "address" 272 | } 273 | ] 274 | }, 275 | { 276 | "stateMutability": "view", 277 | "type": "function", 278 | "name": "PRICE_ORACLE", 279 | "inputs": [], 280 | "outputs": [ 281 | { 282 | "name": "", 283 | "type": "address" 284 | } 285 | ] 286 | }, 287 | { 288 | "stateMutability": "view", 289 | "type": "function", 290 | "name": "CONTROLLER_FACTORY", 291 | "inputs": [], 292 | "outputs": [ 293 | { 294 | "name": "", 295 | "type": "address" 296 | } 297 | ] 298 | } 299 | ] -------------------------------------------------------------------------------- /src/constants/abis/PegKeeper.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "Provide", 4 | "inputs": [ 5 | { 6 | "name": "amount", 7 | "type": "uint256", 8 | "indexed": false 9 | } 10 | ], 11 | "anonymous": false, 12 | "type": "event" 13 | }, 14 | { 15 | "name": "Withdraw", 16 | "inputs": [ 17 | { 18 | "name": "amount", 19 | "type": "uint256", 20 | "indexed": false 21 | } 22 | ], 23 | "anonymous": false, 24 | "type": "event" 25 | }, 26 | { 27 | "name": "Profit", 28 | "inputs": [ 29 | { 30 | "name": "lp_amount", 31 | "type": "uint256", 32 | "indexed": false 33 | } 34 | ], 35 | "anonymous": false, 36 | "type": "event" 37 | }, 38 | { 39 | "name": "CommitNewReceiver", 40 | "inputs": [ 41 | { 42 | "name": "receiver", 43 | "type": "address", 44 | "indexed": false 45 | } 46 | ], 47 | "anonymous": false, 48 | "type": "event" 49 | }, 50 | { 51 | "name": "ApplyNewReceiver", 52 | "inputs": [ 53 | { 54 | "name": "receiver", 55 | "type": "address", 56 | "indexed": false 57 | } 58 | ], 59 | "anonymous": false, 60 | "type": "event" 61 | }, 62 | { 63 | "name": "CommitNewAdmin", 64 | "inputs": [ 65 | { 66 | "name": "admin", 67 | "type": "address", 68 | "indexed": false 69 | } 70 | ], 71 | "anonymous": false, 72 | "type": "event" 73 | }, 74 | { 75 | "name": "ApplyNewAdmin", 76 | "inputs": [ 77 | { 78 | "name": "admin", 79 | "type": "address", 80 | "indexed": false 81 | } 82 | ], 83 | "anonymous": false, 84 | "type": "event" 85 | }, 86 | { 87 | "name": "SetNewCallerShare", 88 | "inputs": [ 89 | { 90 | "name": "caller_share", 91 | "type": "uint256", 92 | "indexed": false 93 | } 94 | ], 95 | "anonymous": false, 96 | "type": "event" 97 | }, 98 | { 99 | "stateMutability": "nonpayable", 100 | "type": "constructor", 101 | "inputs": [ 102 | { 103 | "name": "_pool", 104 | "type": "address" 105 | }, 106 | { 107 | "name": "_index", 108 | "type": "uint256" 109 | }, 110 | { 111 | "name": "_receiver", 112 | "type": "address" 113 | }, 114 | { 115 | "name": "_caller_share", 116 | "type": "uint256" 117 | }, 118 | { 119 | "name": "_factory", 120 | "type": "address" 121 | }, 122 | { 123 | "name": "_aggregator", 124 | "type": "address" 125 | }, 126 | { 127 | "name": "_admin", 128 | "type": "address" 129 | } 130 | ], 131 | "outputs": [] 132 | }, 133 | { 134 | "stateMutability": "pure", 135 | "type": "function", 136 | "name": "factory", 137 | "inputs": [], 138 | "outputs": [ 139 | { 140 | "name": "", 141 | "type": "address" 142 | } 143 | ] 144 | }, 145 | { 146 | "stateMutability": "pure", 147 | "type": "function", 148 | "name": "pegged", 149 | "inputs": [], 150 | "outputs": [ 151 | { 152 | "name": "", 153 | "type": "address" 154 | } 155 | ] 156 | }, 157 | { 158 | "stateMutability": "pure", 159 | "type": "function", 160 | "name": "pool", 161 | "inputs": [], 162 | "outputs": [ 163 | { 164 | "name": "", 165 | "type": "address" 166 | } 167 | ] 168 | }, 169 | { 170 | "stateMutability": "pure", 171 | "type": "function", 172 | "name": "aggregator", 173 | "inputs": [], 174 | "outputs": [ 175 | { 176 | "name": "", 177 | "type": "address" 178 | } 179 | ] 180 | }, 181 | { 182 | "stateMutability": "view", 183 | "type": "function", 184 | "name": "calc_profit", 185 | "inputs": [], 186 | "outputs": [ 187 | { 188 | "name": "", 189 | "type": "uint256" 190 | } 191 | ] 192 | }, 193 | { 194 | "stateMutability": "view", 195 | "type": "function", 196 | "name": "estimate_caller_profit", 197 | "inputs": [], 198 | "outputs": [ 199 | { 200 | "name": "", 201 | "type": "uint256" 202 | } 203 | ] 204 | }, 205 | { 206 | "stateMutability": "nonpayable", 207 | "type": "function", 208 | "name": "update", 209 | "inputs": [], 210 | "outputs": [ 211 | { 212 | "name": "", 213 | "type": "uint256" 214 | } 215 | ] 216 | }, 217 | { 218 | "stateMutability": "nonpayable", 219 | "type": "function", 220 | "name": "update", 221 | "inputs": [ 222 | { 223 | "name": "_beneficiary", 224 | "type": "address" 225 | } 226 | ], 227 | "outputs": [ 228 | { 229 | "name": "", 230 | "type": "uint256" 231 | } 232 | ] 233 | }, 234 | { 235 | "stateMutability": "nonpayable", 236 | "type": "function", 237 | "name": "set_new_caller_share", 238 | "inputs": [ 239 | { 240 | "name": "_new_caller_share", 241 | "type": "uint256" 242 | } 243 | ], 244 | "outputs": [] 245 | }, 246 | { 247 | "stateMutability": "nonpayable", 248 | "type": "function", 249 | "name": "withdraw_profit", 250 | "inputs": [], 251 | "outputs": [ 252 | { 253 | "name": "", 254 | "type": "uint256" 255 | } 256 | ] 257 | }, 258 | { 259 | "stateMutability": "nonpayable", 260 | "type": "function", 261 | "name": "commit_new_admin", 262 | "inputs": [ 263 | { 264 | "name": "_new_admin", 265 | "type": "address" 266 | } 267 | ], 268 | "outputs": [] 269 | }, 270 | { 271 | "stateMutability": "nonpayable", 272 | "type": "function", 273 | "name": "apply_new_admin", 274 | "inputs": [], 275 | "outputs": [] 276 | }, 277 | { 278 | "stateMutability": "nonpayable", 279 | "type": "function", 280 | "name": "commit_new_receiver", 281 | "inputs": [ 282 | { 283 | "name": "_new_receiver", 284 | "type": "address" 285 | } 286 | ], 287 | "outputs": [] 288 | }, 289 | { 290 | "stateMutability": "nonpayable", 291 | "type": "function", 292 | "name": "apply_new_receiver", 293 | "inputs": [], 294 | "outputs": [] 295 | }, 296 | { 297 | "stateMutability": "nonpayable", 298 | "type": "function", 299 | "name": "revert_new_options", 300 | "inputs": [], 301 | "outputs": [] 302 | }, 303 | { 304 | "stateMutability": "view", 305 | "type": "function", 306 | "name": "last_change", 307 | "inputs": [], 308 | "outputs": [ 309 | { 310 | "name": "", 311 | "type": "uint256" 312 | } 313 | ] 314 | }, 315 | { 316 | "stateMutability": "view", 317 | "type": "function", 318 | "name": "debt", 319 | "inputs": [], 320 | "outputs": [ 321 | { 322 | "name": "", 323 | "type": "uint256" 324 | } 325 | ] 326 | }, 327 | { 328 | "stateMutability": "view", 329 | "type": "function", 330 | "name": "caller_share", 331 | "inputs": [], 332 | "outputs": [ 333 | { 334 | "name": "", 335 | "type": "uint256" 336 | } 337 | ] 338 | }, 339 | { 340 | "stateMutability": "view", 341 | "type": "function", 342 | "name": "admin", 343 | "inputs": [], 344 | "outputs": [ 345 | { 346 | "name": "", 347 | "type": "address" 348 | } 349 | ] 350 | }, 351 | { 352 | "stateMutability": "view", 353 | "type": "function", 354 | "name": "future_admin", 355 | "inputs": [], 356 | "outputs": [ 357 | { 358 | "name": "", 359 | "type": "address" 360 | } 361 | ] 362 | }, 363 | { 364 | "stateMutability": "view", 365 | "type": "function", 366 | "name": "receiver", 367 | "inputs": [], 368 | "outputs": [ 369 | { 370 | "name": "", 371 | "type": "address" 372 | } 373 | ] 374 | }, 375 | { 376 | "stateMutability": "view", 377 | "type": "function", 378 | "name": "future_receiver", 379 | "inputs": [], 380 | "outputs": [ 381 | { 382 | "name": "", 383 | "type": "address" 384 | } 385 | ] 386 | }, 387 | { 388 | "stateMutability": "view", 389 | "type": "function", 390 | "name": "new_admin_deadline", 391 | "inputs": [], 392 | "outputs": [ 393 | { 394 | "name": "", 395 | "type": "uint256" 396 | } 397 | ] 398 | }, 399 | { 400 | "stateMutability": "view", 401 | "type": "function", 402 | "name": "new_receiver_deadline", 403 | "inputs": [], 404 | "outputs": [ 405 | { 406 | "name": "", 407 | "type": "uint256" 408 | } 409 | ] 410 | } 411 | ] -------------------------------------------------------------------------------- /src/constants/abis/controller.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "anonymous": false, 4 | "inputs": [ 5 | { 6 | "indexed": true, 7 | "name": "user", 8 | "type": "address" 9 | }, 10 | { 11 | "indexed": false, 12 | "name": "collateral", 13 | "type": "uint256" 14 | }, 15 | { 16 | "indexed": false, 17 | "name": "debt", 18 | "type": "uint256" 19 | }, 20 | { 21 | "indexed": false, 22 | "name": "n1", 23 | "type": "int256" 24 | }, 25 | { 26 | "indexed": false, 27 | "name": "n2", 28 | "type": "int256" 29 | }, 30 | { 31 | "indexed": false, 32 | "name": "liquidation_discount", 33 | "type": "uint256" 34 | } 35 | ], 36 | "name": "UserState", 37 | "type": "event" 38 | }, 39 | { 40 | "anonymous": false, 41 | "inputs": [ 42 | { 43 | "indexed": true, 44 | "name": "user", 45 | "type": "address" 46 | }, 47 | { 48 | "indexed": false, 49 | "name": "collateral_increase", 50 | "type": "uint256" 51 | }, 52 | { 53 | "indexed": false, 54 | "name": "loan_increase", 55 | "type": "uint256" 56 | } 57 | ], 58 | "name": "Borrow", 59 | "type": "event" 60 | }, 61 | { 62 | "anonymous": false, 63 | "inputs": [ 64 | { 65 | "indexed": true, 66 | "name": "user", 67 | "type": "address" 68 | }, 69 | { 70 | "indexed": false, 71 | "name": "collateral_decrease", 72 | "type": "uint256" 73 | }, 74 | { 75 | "indexed": false, 76 | "name": "loan_decrease", 77 | "type": "uint256" 78 | } 79 | ], 80 | "name": "Repay", 81 | "type": "event" 82 | }, 83 | { 84 | "anonymous": false, 85 | "inputs": [ 86 | { 87 | "indexed": true, 88 | "name": "user", 89 | "type": "address" 90 | }, 91 | { 92 | "indexed": false, 93 | "name": "collateral_decrease", 94 | "type": "uint256" 95 | } 96 | ], 97 | "name": "RemoveCollateral", 98 | "type": "event" 99 | }, 100 | { 101 | "anonymous": false, 102 | "inputs": [ 103 | { 104 | "indexed": true, 105 | "name": "liquidator", 106 | "type": "address" 107 | }, 108 | { 109 | "indexed": true, 110 | "name": "user", 111 | "type": "address" 112 | }, 113 | { 114 | "indexed": false, 115 | "name": "collateral_received", 116 | "type": "uint256" 117 | }, 118 | { 119 | "indexed": false, 120 | "name": "stablecoin_received", 121 | "type": "uint256" 122 | }, 123 | { 124 | "indexed": false, 125 | "name": "debt", 126 | "type": "uint256" 127 | } 128 | ], 129 | "name": "Liquidate", 130 | "type": "event" 131 | }, 132 | { 133 | "anonymous": false, 134 | "inputs": [ 135 | { 136 | "indexed": false, 137 | "name": "monetary_policy", 138 | "type": "address" 139 | } 140 | ], 141 | "name": "SetMonetaryPolicy", 142 | "type": "event" 143 | }, 144 | { 145 | "anonymous": false, 146 | "inputs": [ 147 | { 148 | "indexed": false, 149 | "name": "loan_discount", 150 | "type": "uint256" 151 | }, 152 | { 153 | "indexed": false, 154 | "name": "liquidation_discount", 155 | "type": "uint256" 156 | } 157 | ], 158 | "name": "SetBorrowingDiscounts", 159 | "type": "event" 160 | }, 161 | { 162 | "anonymous": false, 163 | "inputs": [ 164 | { 165 | "indexed": false, 166 | "name": "amount", 167 | "type": "uint256" 168 | }, 169 | { 170 | "indexed": false, 171 | "name": "new_supply", 172 | "type": "uint256" 173 | } 174 | ], 175 | "name": "CollectFees", 176 | "type": "event" 177 | }, 178 | { 179 | "inputs": [ 180 | { 181 | "name": "collateral_token", 182 | "type": "address" 183 | }, 184 | { 185 | "name": "monetary_policy", 186 | "type": "address" 187 | }, 188 | { 189 | "name": "loan_discount", 190 | "type": "uint256" 191 | }, 192 | { 193 | "name": "liquidation_discount", 194 | "type": "uint256" 195 | }, 196 | { 197 | "name": "amm", 198 | "type": "address" 199 | } 200 | ], 201 | "name": "constructor", 202 | "outputs": [], 203 | "stateMutability": "nonpayable", 204 | "type": "constructor" 205 | }, 206 | { 207 | "stateMutability": "payable", 208 | "type": "fallback" 209 | }, 210 | { 211 | "inputs": [], 212 | "name": "factory", 213 | "outputs": [ 214 | { 215 | "name": "", 216 | "type": "address" 217 | } 218 | ], 219 | "stateMutability": "view", 220 | "type": "function" 221 | }, 222 | { 223 | "inputs": [], 224 | "name": "amm", 225 | "outputs": [ 226 | { 227 | "name": "", 228 | "type": "address" 229 | } 230 | ], 231 | "stateMutability": "view", 232 | "type": "function" 233 | }, 234 | { 235 | "inputs": [], 236 | "name": "collateral_token", 237 | "outputs": [ 238 | { 239 | "name": "", 240 | "type": "address" 241 | } 242 | ], 243 | "stateMutability": "view", 244 | "type": "function" 245 | }, 246 | { 247 | "inputs": [ 248 | { 249 | "name": "user", 250 | "type": "address" 251 | } 252 | ], 253 | "name": "debt", 254 | "outputs": [ 255 | { 256 | "name": "", 257 | "type": "uint256" 258 | } 259 | ], 260 | "stateMutability": "view", 261 | "type": "function" 262 | }, 263 | { 264 | "inputs": [ 265 | { 266 | "name": "user", 267 | "type": "address" 268 | } 269 | ], 270 | "name": "loan_exists", 271 | "outputs": [ 272 | { 273 | "name": "", 274 | "type": "bool" 275 | } 276 | ], 277 | "stateMutability": "view", 278 | "type": "function" 279 | }, 280 | { 281 | "inputs": [], 282 | "name": "total_debt", 283 | "outputs": [ 284 | { 285 | "name": "", 286 | "type": "uint256" 287 | } 288 | ], 289 | "stateMutability": "view", 290 | "type": "function" 291 | }, 292 | { 293 | "inputs": [ 294 | { 295 | "name": "collateral", 296 | "type": "uint256" 297 | }, 298 | { 299 | "name": "N", 300 | "type": "uint256" 301 | } 302 | ], 303 | "name": "max_borrowable", 304 | "outputs": [ 305 | { 306 | "name": "", 307 | "type": "uint256" 308 | } 309 | ], 310 | "stateMutability": "view", 311 | "type": "function" 312 | }, 313 | { 314 | "inputs": [ 315 | { 316 | "name": "debt", 317 | "type": "uint256" 318 | }, 319 | { 320 | "name": "N", 321 | "type": "uint256" 322 | } 323 | ], 324 | "name": "min_collateral", 325 | "outputs": [ 326 | { 327 | "name": "", 328 | "type": "uint256" 329 | } 330 | ], 331 | "stateMutability": "view", 332 | "type": "function" 333 | }, 334 | { 335 | "inputs": [ 336 | { 337 | "name": "collateral", 338 | "type": "uint256" 339 | }, 340 | { 341 | "name": "debt", 342 | "type": "uint256" 343 | }, 344 | { 345 | "name": "N", 346 | "type": "uint256" 347 | } 348 | ], 349 | "name": "calculate_debt_n1", 350 | "outputs": [ 351 | { 352 | "name": "", 353 | "type": "int256" 354 | } 355 | ], 356 | "stateMutability": "view", 357 | "type": "function" 358 | }, 359 | { 360 | "inputs": [ 361 | { 362 | "name": "collateral", 363 | "type": "uint256" 364 | }, 365 | { 366 | "name": "debt", 367 | "type": "uint256" 368 | }, 369 | { 370 | "name": "N", 371 | "type": "uint256" 372 | } 373 | ], 374 | "name": "create_loan", 375 | "outputs": [], 376 | "stateMutability": "payable", 377 | "type": "function" 378 | }, 379 | { 380 | "inputs": [ 381 | { 382 | "name": "collateral", 383 | "type": "uint256" 384 | }, 385 | { 386 | "name": "debt", 387 | "type": "uint256" 388 | }, 389 | { 390 | "name": "N", 391 | "type": "uint256" 392 | }, 393 | { 394 | "name": "callbacker", 395 | "type": "address" 396 | }, 397 | { 398 | "name": "callback_args", 399 | "type": "uint256[]" 400 | } 401 | ], 402 | "name": "create_loan_extended", 403 | "outputs": [], 404 | "stateMutability": "payable", 405 | "type": "function" 406 | }, 407 | { 408 | "inputs": [ 409 | { 410 | "name": "collateral", 411 | "type": "uint256" 412 | }, 413 | { 414 | "name": "_for", 415 | "type": "address" 416 | } 417 | ], 418 | "name": "add_collateral", 419 | "outputs": [], 420 | "stateMutability": "payable", 421 | "type": "function" 422 | }, 423 | { 424 | "inputs": [ 425 | { 426 | "name": "collateral", 427 | "type": "uint256" 428 | }, 429 | { 430 | "name": "use_eth", 431 | "type": "bool" 432 | } 433 | ], 434 | "name": "remove_collateral", 435 | "outputs": [], 436 | "stateMutability": "nonpayable", 437 | "type": "function" 438 | }, 439 | { 440 | "inputs": [ 441 | { 442 | "name": "collateral", 443 | "type": "uint256" 444 | }, 445 | { 446 | "name": "debt", 447 | "type": "uint256" 448 | } 449 | ], 450 | "name": "borrow_more", 451 | "outputs": [], 452 | "stateMutability": "payable", 453 | "type": "function" 454 | }, 455 | { 456 | "inputs": [ 457 | { 458 | "name": "_d_debt", 459 | "type": "uint256" 460 | }, 461 | { 462 | "name": "_for", 463 | "type": "address" 464 | }, 465 | { 466 | "name": "max_active_band", 467 | "type": "int256" 468 | }, 469 | { 470 | "name": "use_eth", 471 | "type": "bool" 472 | } 473 | ], 474 | "name": "repay", 475 | "outputs": [], 476 | "stateMutability": "payable", 477 | "type": "function" 478 | }, 479 | { 480 | "inputs": [ 481 | { 482 | "name": "callbacker", 483 | "type": "address" 484 | }, 485 | { 486 | "name": "callback_args", 487 | "type": "uint256[]" 488 | } 489 | ], 490 | "name": "repay_extended", 491 | "outputs": [], 492 | "stateMutability": "nonpayable", 493 | "type": "function" 494 | }, 495 | { 496 | "inputs": [ 497 | { 498 | "name": "user", 499 | "type": "address" 500 | }, 501 | { 502 | "name": "d_collateral", 503 | "type": "int256" 504 | }, 505 | { 506 | "name": "d_debt", 507 | "type": "int256" 508 | }, 509 | { 510 | "name": "full", 511 | "type": "bool" 512 | }, 513 | { 514 | "name": "N", 515 | "type": "uint256" 516 | } 517 | ], 518 | "name": "health_calculator", 519 | "outputs": [ 520 | { 521 | "name": "", 522 | "type": "int256" 523 | } 524 | ], 525 | "stateMutability": "view", 526 | "type": "function" 527 | }, 528 | { 529 | "inputs": [ 530 | { 531 | "name": "user", 532 | "type": "address" 533 | }, 534 | { 535 | "name": "min_x", 536 | "type": "uint256" 537 | }, 538 | { 539 | "name": "use_eth", 540 | "type": "bool" 541 | } 542 | ], 543 | "name": "liquidate", 544 | "outputs": [], 545 | "stateMutability": "nonpayable", 546 | "type": "function" 547 | }, 548 | { 549 | "inputs": [ 550 | { 551 | "name": "user", 552 | "type": "address" 553 | }, 554 | { 555 | "name": "min_x", 556 | "type": "uint256" 557 | }, 558 | { 559 | "name": "frac", 560 | "type": "uint256" 561 | }, 562 | { 563 | "name": "use_eth", 564 | "type": "bool" 565 | }, 566 | { 567 | "name": "callbacker", 568 | "type": "address" 569 | }, 570 | { 571 | "name": "callback_args", 572 | "type": "uint256[]" 573 | } 574 | ], 575 | "name": "liquidate_extended", 576 | "outputs": [], 577 | "stateMutability": "nonpayable", 578 | "type": "function" 579 | }, 580 | { 581 | "inputs": [ 582 | { 583 | "name": "user", 584 | "type": "address" 585 | } 586 | ], 587 | "name": "tokens_to_liquidate", 588 | "outputs": [ 589 | { 590 | "name": "", 591 | "type": "uint256" 592 | } 593 | ], 594 | "stateMutability": "view", 595 | "type": "function" 596 | }, 597 | { 598 | "inputs": [ 599 | { 600 | "name": "user", 601 | "type": "address" 602 | }, 603 | { 604 | "name": "full", 605 | "type": "bool" 606 | } 607 | ], 608 | "name": "health", 609 | "outputs": [ 610 | { 611 | "name": "", 612 | "type": "int256" 613 | } 614 | ], 615 | "stateMutability": "view", 616 | "type": "function" 617 | }, 618 | { 619 | "inputs": [], 620 | "name": "users_to_liquidate", 621 | "outputs": [ 622 | { 623 | "components": [ 624 | { 625 | "name": "user", 626 | "type": "address" 627 | }, 628 | { 629 | "name": "x", 630 | "type": "uint256" 631 | }, 632 | { 633 | "name": "y", 634 | "type": "uint256" 635 | }, 636 | { 637 | "name": "debt", 638 | "type": "uint256" 639 | }, 640 | { 641 | "name": "health", 642 | "type": "int256" 643 | } 644 | ], 645 | "name": "", 646 | "type": "tuple[]" 647 | } 648 | ], 649 | "stateMutability": "view", 650 | "type": "function" 651 | }, 652 | { 653 | "inputs": [ 654 | { 655 | "name": "_from", 656 | "type": "uint256" 657 | } 658 | ], 659 | "name": "users_to_liquidate", 660 | "outputs": [ 661 | { 662 | "components": [ 663 | { 664 | "name": "user", 665 | "type": "address" 666 | }, 667 | { 668 | "name": "x", 669 | "type": "uint256" 670 | }, 671 | { 672 | "name": "y", 673 | "type": "uint256" 674 | }, 675 | { 676 | "name": "debt", 677 | "type": "uint256" 678 | }, 679 | { 680 | "name": "health", 681 | "type": "int256" 682 | } 683 | ], 684 | "name": "", 685 | "type": "tuple[]" 686 | } 687 | ], 688 | "stateMutability": "view", 689 | "type": "function" 690 | }, 691 | { 692 | "inputs": [ 693 | { 694 | "name": "_from", 695 | "type": "uint256" 696 | }, 697 | { 698 | "name": "_limit", 699 | "type": "uint256" 700 | } 701 | ], 702 | "name": "users_to_liquidate", 703 | "outputs": [ 704 | { 705 | "components": [ 706 | { 707 | "name": "user", 708 | "type": "address" 709 | }, 710 | { 711 | "name": "x", 712 | "type": "uint256" 713 | }, 714 | { 715 | "name": "y", 716 | "type": "uint256" 717 | }, 718 | { 719 | "name": "debt", 720 | "type": "uint256" 721 | }, 722 | { 723 | "name": "health", 724 | "type": "int256" 725 | } 726 | ], 727 | "name": "", 728 | "type": "tuple[]" 729 | } 730 | ], 731 | "stateMutability": "view", 732 | "type": "function" 733 | }, 734 | { 735 | "inputs": [], 736 | "name": "amm_price", 737 | "outputs": [ 738 | { 739 | "name": "", 740 | "type": "uint256" 741 | } 742 | ], 743 | "stateMutability": "view", 744 | "type": "function" 745 | }, 746 | { 747 | "inputs": [ 748 | { 749 | "name": "user", 750 | "type": "address" 751 | } 752 | ], 753 | "name": "user_prices", 754 | "outputs": [ 755 | { 756 | "name": "", 757 | "type": "uint256[2]" 758 | } 759 | ], 760 | "stateMutability": "view", 761 | "type": "function" 762 | }, 763 | { 764 | "inputs": [ 765 | { 766 | "name": "user", 767 | "type": "address" 768 | } 769 | ], 770 | "name": "user_state", 771 | "outputs": [ 772 | { 773 | "name": "", 774 | "type": "uint256[4]" 775 | } 776 | ], 777 | "stateMutability": "view", 778 | "type": "function" 779 | }, 780 | { 781 | "inputs": [ 782 | { 783 | "name": "fee", 784 | "type": "uint256" 785 | } 786 | ], 787 | "name": "set_amm_fee", 788 | "outputs": [], 789 | "stateMutability": "nonpayable", 790 | "type": "function" 791 | }, 792 | { 793 | "inputs": [ 794 | { 795 | "name": "fee", 796 | "type": "uint256" 797 | } 798 | ], 799 | "name": "set_amm_admin_fee", 800 | "outputs": [], 801 | "stateMutability": "nonpayable", 802 | "type": "function" 803 | }, 804 | { 805 | "inputs": [ 806 | { 807 | "name": "monetary_policy", 808 | "type": "address" 809 | } 810 | ], 811 | "name": "set_monetary_policy", 812 | "outputs": [], 813 | "stateMutability": "nonpayable", 814 | "type": "function" 815 | }, 816 | { 817 | "inputs": [ 818 | { 819 | "name": "loan_discount", 820 | "type": "uint256" 821 | }, 822 | { 823 | "name": "liquidation_discount", 824 | "type": "uint256" 825 | } 826 | ], 827 | "name": "set_borrowing_discounts", 828 | "outputs": [], 829 | "stateMutability": "nonpayable", 830 | "type": "function" 831 | }, 832 | { 833 | "inputs": [ 834 | { 835 | "name": "cb", 836 | "type": "address" 837 | } 838 | ], 839 | "name": "set_callback", 840 | "outputs": [], 841 | "stateMutability": "nonpayable", 842 | "type": "function" 843 | }, 844 | { 845 | "inputs": [], 846 | "name": "admin_fees", 847 | "outputs": [ 848 | { 849 | "name": "", 850 | "type": "uint256" 851 | } 852 | ], 853 | "stateMutability": "view", 854 | "type": "function" 855 | }, 856 | { 857 | "inputs": [], 858 | "name": "collect_fees", 859 | "outputs": [ 860 | { 861 | "name": "", 862 | "type": "uint256" 863 | } 864 | ], 865 | "stateMutability": "nonpayable", 866 | "type": "function" 867 | }, 868 | { 869 | "inputs": [ 870 | { 871 | "name": "arg0", 872 | "type": "address" 873 | } 874 | ], 875 | "name": "liquidation_discounts", 876 | "outputs": [ 877 | { 878 | "name": "", 879 | "type": "uint256" 880 | } 881 | ], 882 | "stateMutability": "view", 883 | "type": "function" 884 | }, 885 | { 886 | "inputs": [ 887 | { 888 | "name": "arg0", 889 | "type": "uint256" 890 | } 891 | ], 892 | "name": "loans", 893 | "outputs": [ 894 | { 895 | "name": "", 896 | "type": "address" 897 | } 898 | ], 899 | "stateMutability": "view", 900 | "type": "function" 901 | }, 902 | { 903 | "inputs": [ 904 | { 905 | "name": "arg0", 906 | "type": "address" 907 | } 908 | ], 909 | "name": "loan_ix", 910 | "outputs": [ 911 | { 912 | "name": "", 913 | "type": "uint256" 914 | } 915 | ], 916 | "stateMutability": "view", 917 | "type": "function" 918 | }, 919 | { 920 | "inputs": [], 921 | "name": "n_loans", 922 | "outputs": [ 923 | { 924 | "name": "", 925 | "type": "uint256" 926 | } 927 | ], 928 | "stateMutability": "view", 929 | "type": "function" 930 | }, 931 | { 932 | "inputs": [], 933 | "name": "minted", 934 | "outputs": [ 935 | { 936 | "name": "", 937 | "type": "uint256" 938 | } 939 | ], 940 | "stateMutability": "view", 941 | "type": "function" 942 | }, 943 | { 944 | "inputs": [], 945 | "name": "redeemed", 946 | "outputs": [ 947 | { 948 | "name": "", 949 | "type": "uint256" 950 | } 951 | ], 952 | "stateMutability": "view", 953 | "type": "function" 954 | }, 955 | { 956 | "inputs": [], 957 | "name": "monetary_policy", 958 | "outputs": [ 959 | { 960 | "name": "", 961 | "type": "address" 962 | } 963 | ], 964 | "stateMutability": "view", 965 | "type": "function" 966 | }, 967 | { 968 | "inputs": [], 969 | "name": "liquidation_discount", 970 | "outputs": [ 971 | { 972 | "name": "", 973 | "type": "uint256" 974 | } 975 | ], 976 | "stateMutability": "view", 977 | "type": "function" 978 | }, 979 | { 980 | "inputs": [], 981 | "name": "loan_discount", 982 | "outputs": [ 983 | { 984 | "name": "", 985 | "type": "uint256" 986 | } 987 | ], 988 | "stateMutability": "view", 989 | "type": "function" 990 | } 991 | ] 992 | -------------------------------------------------------------------------------- /src/constants/abis/controller_v2.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "anonymous": false, 4 | "inputs": [ 5 | { 6 | "indexed": true, 7 | "name": "user", 8 | "type": "address" 9 | }, 10 | { 11 | "indexed": false, 12 | "name": "collateral", 13 | "type": "uint256" 14 | }, 15 | { 16 | "indexed": false, 17 | "name": "debt", 18 | "type": "uint256" 19 | }, 20 | { 21 | "indexed": false, 22 | "name": "n1", 23 | "type": "int256" 24 | }, 25 | { 26 | "indexed": false, 27 | "name": "n2", 28 | "type": "int256" 29 | }, 30 | { 31 | "indexed": false, 32 | "name": "liquidation_discount", 33 | "type": "uint256" 34 | } 35 | ], 36 | "name": "UserState", 37 | "type": "event" 38 | }, 39 | { 40 | "anonymous": false, 41 | "inputs": [ 42 | { 43 | "indexed": true, 44 | "name": "user", 45 | "type": "address" 46 | }, 47 | { 48 | "indexed": false, 49 | "name": "collateral_increase", 50 | "type": "uint256" 51 | }, 52 | { 53 | "indexed": false, 54 | "name": "loan_increase", 55 | "type": "uint256" 56 | } 57 | ], 58 | "name": "Borrow", 59 | "type": "event" 60 | }, 61 | { 62 | "anonymous": false, 63 | "inputs": [ 64 | { 65 | "indexed": true, 66 | "name": "user", 67 | "type": "address" 68 | }, 69 | { 70 | "indexed": false, 71 | "name": "collateral_decrease", 72 | "type": "uint256" 73 | }, 74 | { 75 | "indexed": false, 76 | "name": "loan_decrease", 77 | "type": "uint256" 78 | } 79 | ], 80 | "name": "Repay", 81 | "type": "event" 82 | }, 83 | { 84 | "anonymous": false, 85 | "inputs": [ 86 | { 87 | "indexed": true, 88 | "name": "user", 89 | "type": "address" 90 | }, 91 | { 92 | "indexed": false, 93 | "name": "collateral_decrease", 94 | "type": "uint256" 95 | } 96 | ], 97 | "name": "RemoveCollateral", 98 | "type": "event" 99 | }, 100 | { 101 | "anonymous": false, 102 | "inputs": [ 103 | { 104 | "indexed": true, 105 | "name": "liquidator", 106 | "type": "address" 107 | }, 108 | { 109 | "indexed": true, 110 | "name": "user", 111 | "type": "address" 112 | }, 113 | { 114 | "indexed": false, 115 | "name": "collateral_received", 116 | "type": "uint256" 117 | }, 118 | { 119 | "indexed": false, 120 | "name": "stablecoin_received", 121 | "type": "uint256" 122 | }, 123 | { 124 | "indexed": false, 125 | "name": "debt", 126 | "type": "uint256" 127 | } 128 | ], 129 | "name": "Liquidate", 130 | "type": "event" 131 | }, 132 | { 133 | "anonymous": false, 134 | "inputs": [ 135 | { 136 | "indexed": false, 137 | "name": "monetary_policy", 138 | "type": "address" 139 | } 140 | ], 141 | "name": "SetMonetaryPolicy", 142 | "type": "event" 143 | }, 144 | { 145 | "anonymous": false, 146 | "inputs": [ 147 | { 148 | "indexed": false, 149 | "name": "loan_discount", 150 | "type": "uint256" 151 | }, 152 | { 153 | "indexed": false, 154 | "name": "liquidation_discount", 155 | "type": "uint256" 156 | } 157 | ], 158 | "name": "SetBorrowingDiscounts", 159 | "type": "event" 160 | }, 161 | { 162 | "anonymous": false, 163 | "inputs": [ 164 | { 165 | "indexed": false, 166 | "name": "amount", 167 | "type": "uint256" 168 | }, 169 | { 170 | "indexed": false, 171 | "name": "new_supply", 172 | "type": "uint256" 173 | } 174 | ], 175 | "name": "CollectFees", 176 | "type": "event" 177 | }, 178 | { 179 | "inputs": [ 180 | { 181 | "name": "collateral_token", 182 | "type": "address" 183 | }, 184 | { 185 | "name": "monetary_policy", 186 | "type": "address" 187 | }, 188 | { 189 | "name": "loan_discount", 190 | "type": "uint256" 191 | }, 192 | { 193 | "name": "liquidation_discount", 194 | "type": "uint256" 195 | }, 196 | { 197 | "name": "amm", 198 | "type": "address" 199 | } 200 | ], 201 | "name": "constructor", 202 | "outputs": [], 203 | "stateMutability": "nonpayable", 204 | "type": "constructor" 205 | }, 206 | { 207 | "stateMutability": "payable", 208 | "type": "fallback" 209 | }, 210 | { 211 | "inputs": [], 212 | "name": "factory", 213 | "outputs": [ 214 | { 215 | "name": "", 216 | "type": "address" 217 | } 218 | ], 219 | "stateMutability": "view", 220 | "type": "function" 221 | }, 222 | { 223 | "inputs": [], 224 | "name": "amm", 225 | "outputs": [ 226 | { 227 | "name": "", 228 | "type": "address" 229 | } 230 | ], 231 | "stateMutability": "view", 232 | "type": "function" 233 | }, 234 | { 235 | "inputs": [], 236 | "name": "collateral_token", 237 | "outputs": [ 238 | { 239 | "name": "", 240 | "type": "address" 241 | } 242 | ], 243 | "stateMutability": "view", 244 | "type": "function" 245 | }, 246 | { 247 | "inputs": [ 248 | { 249 | "name": "user", 250 | "type": "address" 251 | } 252 | ], 253 | "name": "debt", 254 | "outputs": [ 255 | { 256 | "name": "", 257 | "type": "uint256" 258 | } 259 | ], 260 | "stateMutability": "view", 261 | "type": "function" 262 | }, 263 | { 264 | "inputs": [ 265 | { 266 | "name": "user", 267 | "type": "address" 268 | } 269 | ], 270 | "name": "loan_exists", 271 | "outputs": [ 272 | { 273 | "name": "", 274 | "type": "bool" 275 | } 276 | ], 277 | "stateMutability": "view", 278 | "type": "function" 279 | }, 280 | { 281 | "inputs": [], 282 | "name": "total_debt", 283 | "outputs": [ 284 | { 285 | "name": "", 286 | "type": "uint256" 287 | } 288 | ], 289 | "stateMutability": "view", 290 | "type": "function" 291 | }, 292 | { 293 | "inputs": [ 294 | { 295 | "name": "collateral", 296 | "type": "uint256" 297 | }, 298 | { 299 | "name": "N", 300 | "type": "uint256" 301 | } 302 | ], 303 | "name": "max_borrowable", 304 | "outputs": [ 305 | { 306 | "name": "", 307 | "type": "uint256" 308 | } 309 | ], 310 | "stateMutability": "view", 311 | "type": "function" 312 | }, 313 | { 314 | "inputs": [ 315 | { 316 | "name": "debt", 317 | "type": "uint256" 318 | }, 319 | { 320 | "name": "N", 321 | "type": "uint256" 322 | } 323 | ], 324 | "name": "min_collateral", 325 | "outputs": [ 326 | { 327 | "name": "", 328 | "type": "uint256" 329 | } 330 | ], 331 | "stateMutability": "view", 332 | "type": "function" 333 | }, 334 | { 335 | "inputs": [ 336 | { 337 | "name": "collateral", 338 | "type": "uint256" 339 | }, 340 | { 341 | "name": "debt", 342 | "type": "uint256" 343 | }, 344 | { 345 | "name": "N", 346 | "type": "uint256" 347 | } 348 | ], 349 | "name": "calculate_debt_n1", 350 | "outputs": [ 351 | { 352 | "name": "", 353 | "type": "int256" 354 | } 355 | ], 356 | "stateMutability": "view", 357 | "type": "function" 358 | }, 359 | { 360 | "inputs": [ 361 | { 362 | "name": "collateral", 363 | "type": "uint256" 364 | }, 365 | { 366 | "name": "debt", 367 | "type": "uint256" 368 | }, 369 | { 370 | "name": "N", 371 | "type": "uint256" 372 | } 373 | ], 374 | "name": "create_loan", 375 | "outputs": [], 376 | "stateMutability": "payable", 377 | "type": "function" 378 | }, 379 | { 380 | "inputs": [ 381 | { 382 | "name": "collateral", 383 | "type": "uint256" 384 | }, 385 | { 386 | "name": "debt", 387 | "type": "uint256" 388 | }, 389 | { 390 | "name": "N", 391 | "type": "uint256" 392 | }, 393 | { 394 | "name": "callbacker", 395 | "type": "address" 396 | }, 397 | { 398 | "name": "callback_args", 399 | "type": "uint256[]" 400 | } 401 | ], 402 | "name": "create_loan_extended", 403 | "outputs": [], 404 | "stateMutability": "payable", 405 | "type": "function" 406 | }, 407 | { 408 | "inputs": [ 409 | { 410 | "name": "collateral", 411 | "type": "uint256" 412 | }, 413 | { 414 | "name": "_for", 415 | "type": "address" 416 | } 417 | ], 418 | "name": "add_collateral", 419 | "outputs": [], 420 | "stateMutability": "payable", 421 | "type": "function" 422 | }, 423 | { 424 | "inputs": [ 425 | { 426 | "name": "collateral", 427 | "type": "uint256" 428 | } 429 | ], 430 | "name": "remove_collateral", 431 | "outputs": [], 432 | "stateMutability": "nonpayable", 433 | "type": "function" 434 | }, 435 | { 436 | "inputs": [ 437 | { 438 | "name": "collateral", 439 | "type": "uint256" 440 | }, 441 | { 442 | "name": "debt", 443 | "type": "uint256" 444 | } 445 | ], 446 | "name": "borrow_more", 447 | "outputs": [], 448 | "stateMutability": "payable", 449 | "type": "function" 450 | }, 451 | { 452 | "inputs": [ 453 | { 454 | "name": "_d_debt", 455 | "type": "uint256" 456 | }, 457 | { 458 | "name": "_for", 459 | "type": "address" 460 | }, 461 | { 462 | "name": "max_active_band", 463 | "type": "int256" 464 | } 465 | ], 466 | "name": "repay", 467 | "outputs": [], 468 | "stateMutability": "payable", 469 | "type": "function" 470 | }, 471 | { 472 | "inputs": [ 473 | { 474 | "name": "callbacker", 475 | "type": "address" 476 | }, 477 | { 478 | "name": "callback_args", 479 | "type": "uint256[]" 480 | } 481 | ], 482 | "name": "repay_extended", 483 | "outputs": [], 484 | "stateMutability": "nonpayable", 485 | "type": "function" 486 | }, 487 | { 488 | "inputs": [ 489 | { 490 | "name": "user", 491 | "type": "address" 492 | }, 493 | { 494 | "name": "d_collateral", 495 | "type": "int256" 496 | }, 497 | { 498 | "name": "d_debt", 499 | "type": "int256" 500 | }, 501 | { 502 | "name": "full", 503 | "type": "bool" 504 | }, 505 | { 506 | "name": "N", 507 | "type": "uint256" 508 | } 509 | ], 510 | "name": "health_calculator", 511 | "outputs": [ 512 | { 513 | "name": "", 514 | "type": "int256" 515 | } 516 | ], 517 | "stateMutability": "view", 518 | "type": "function" 519 | }, 520 | { 521 | "inputs": [ 522 | { 523 | "name": "user", 524 | "type": "address" 525 | }, 526 | { 527 | "name": "min_x", 528 | "type": "uint256" 529 | } 530 | ], 531 | "name": "liquidate", 532 | "outputs": [], 533 | "stateMutability": "nonpayable", 534 | "type": "function" 535 | }, 536 | { 537 | "inputs": [ 538 | { 539 | "name": "user", 540 | "type": "address" 541 | }, 542 | { 543 | "name": "min_x", 544 | "type": "uint256" 545 | }, 546 | { 547 | "name": "frac", 548 | "type": "uint256" 549 | }, 550 | { 551 | "name": "use_eth", 552 | "type": "bool" 553 | }, 554 | { 555 | "name": "callbacker", 556 | "type": "address" 557 | }, 558 | { 559 | "name": "callback_args", 560 | "type": "uint256[]" 561 | } 562 | ], 563 | "name": "liquidate_extended", 564 | "outputs": [], 565 | "stateMutability": "nonpayable", 566 | "type": "function" 567 | }, 568 | { 569 | "inputs": [ 570 | { 571 | "name": "user", 572 | "type": "address" 573 | } 574 | ], 575 | "name": "tokens_to_liquidate", 576 | "outputs": [ 577 | { 578 | "name": "", 579 | "type": "uint256" 580 | } 581 | ], 582 | "stateMutability": "view", 583 | "type": "function" 584 | }, 585 | { 586 | "inputs": [ 587 | { 588 | "name": "user", 589 | "type": "address" 590 | }, 591 | { 592 | "name": "full", 593 | "type": "bool" 594 | } 595 | ], 596 | "name": "health", 597 | "outputs": [ 598 | { 599 | "name": "", 600 | "type": "int256" 601 | } 602 | ], 603 | "stateMutability": "view", 604 | "type": "function" 605 | }, 606 | { 607 | "inputs": [], 608 | "name": "users_to_liquidate", 609 | "outputs": [ 610 | { 611 | "components": [ 612 | { 613 | "name": "user", 614 | "type": "address" 615 | }, 616 | { 617 | "name": "x", 618 | "type": "uint256" 619 | }, 620 | { 621 | "name": "y", 622 | "type": "uint256" 623 | }, 624 | { 625 | "name": "debt", 626 | "type": "uint256" 627 | }, 628 | { 629 | "name": "health", 630 | "type": "int256" 631 | } 632 | ], 633 | "name": "", 634 | "type": "tuple[]" 635 | } 636 | ], 637 | "stateMutability": "view", 638 | "type": "function" 639 | }, 640 | { 641 | "inputs": [ 642 | { 643 | "name": "_from", 644 | "type": "uint256" 645 | } 646 | ], 647 | "name": "users_to_liquidate", 648 | "outputs": [ 649 | { 650 | "components": [ 651 | { 652 | "name": "user", 653 | "type": "address" 654 | }, 655 | { 656 | "name": "x", 657 | "type": "uint256" 658 | }, 659 | { 660 | "name": "y", 661 | "type": "uint256" 662 | }, 663 | { 664 | "name": "debt", 665 | "type": "uint256" 666 | }, 667 | { 668 | "name": "health", 669 | "type": "int256" 670 | } 671 | ], 672 | "name": "", 673 | "type": "tuple[]" 674 | } 675 | ], 676 | "stateMutability": "view", 677 | "type": "function" 678 | }, 679 | { 680 | "inputs": [ 681 | { 682 | "name": "_from", 683 | "type": "uint256" 684 | }, 685 | { 686 | "name": "_limit", 687 | "type": "uint256" 688 | } 689 | ], 690 | "name": "users_to_liquidate", 691 | "outputs": [ 692 | { 693 | "components": [ 694 | { 695 | "name": "user", 696 | "type": "address" 697 | }, 698 | { 699 | "name": "x", 700 | "type": "uint256" 701 | }, 702 | { 703 | "name": "y", 704 | "type": "uint256" 705 | }, 706 | { 707 | "name": "debt", 708 | "type": "uint256" 709 | }, 710 | { 711 | "name": "health", 712 | "type": "int256" 713 | } 714 | ], 715 | "name": "", 716 | "type": "tuple[]" 717 | } 718 | ], 719 | "stateMutability": "view", 720 | "type": "function" 721 | }, 722 | { 723 | "inputs": [], 724 | "name": "amm_price", 725 | "outputs": [ 726 | { 727 | "name": "", 728 | "type": "uint256" 729 | } 730 | ], 731 | "stateMutability": "view", 732 | "type": "function" 733 | }, 734 | { 735 | "inputs": [ 736 | { 737 | "name": "user", 738 | "type": "address" 739 | } 740 | ], 741 | "name": "user_prices", 742 | "outputs": [ 743 | { 744 | "name": "", 745 | "type": "uint256[2]" 746 | } 747 | ], 748 | "stateMutability": "view", 749 | "type": "function" 750 | }, 751 | { 752 | "inputs": [ 753 | { 754 | "name": "user", 755 | "type": "address" 756 | } 757 | ], 758 | "name": "user_state", 759 | "outputs": [ 760 | { 761 | "name": "", 762 | "type": "uint256[4]" 763 | } 764 | ], 765 | "stateMutability": "view", 766 | "type": "function" 767 | }, 768 | { 769 | "inputs": [ 770 | { 771 | "name": "fee", 772 | "type": "uint256" 773 | } 774 | ], 775 | "name": "set_amm_fee", 776 | "outputs": [], 777 | "stateMutability": "nonpayable", 778 | "type": "function" 779 | }, 780 | { 781 | "inputs": [ 782 | { 783 | "name": "fee", 784 | "type": "uint256" 785 | } 786 | ], 787 | "name": "set_amm_admin_fee", 788 | "outputs": [], 789 | "stateMutability": "nonpayable", 790 | "type": "function" 791 | }, 792 | { 793 | "inputs": [ 794 | { 795 | "name": "monetary_policy", 796 | "type": "address" 797 | } 798 | ], 799 | "name": "set_monetary_policy", 800 | "outputs": [], 801 | "stateMutability": "nonpayable", 802 | "type": "function" 803 | }, 804 | { 805 | "inputs": [ 806 | { 807 | "name": "loan_discount", 808 | "type": "uint256" 809 | }, 810 | { 811 | "name": "liquidation_discount", 812 | "type": "uint256" 813 | } 814 | ], 815 | "name": "set_borrowing_discounts", 816 | "outputs": [], 817 | "stateMutability": "nonpayable", 818 | "type": "function" 819 | }, 820 | { 821 | "inputs": [ 822 | { 823 | "name": "cb", 824 | "type": "address" 825 | } 826 | ], 827 | "name": "set_callback", 828 | "outputs": [], 829 | "stateMutability": "nonpayable", 830 | "type": "function" 831 | }, 832 | { 833 | "inputs": [], 834 | "name": "admin_fees", 835 | "outputs": [ 836 | { 837 | "name": "", 838 | "type": "uint256" 839 | } 840 | ], 841 | "stateMutability": "view", 842 | "type": "function" 843 | }, 844 | { 845 | "inputs": [], 846 | "name": "collect_fees", 847 | "outputs": [ 848 | { 849 | "name": "", 850 | "type": "uint256" 851 | } 852 | ], 853 | "stateMutability": "nonpayable", 854 | "type": "function" 855 | }, 856 | { 857 | "inputs": [ 858 | { 859 | "name": "arg0", 860 | "type": "address" 861 | } 862 | ], 863 | "name": "liquidation_discounts", 864 | "outputs": [ 865 | { 866 | "name": "", 867 | "type": "uint256" 868 | } 869 | ], 870 | "stateMutability": "view", 871 | "type": "function" 872 | }, 873 | { 874 | "inputs": [ 875 | { 876 | "name": "arg0", 877 | "type": "uint256" 878 | } 879 | ], 880 | "name": "loans", 881 | "outputs": [ 882 | { 883 | "name": "", 884 | "type": "address" 885 | } 886 | ], 887 | "stateMutability": "view", 888 | "type": "function" 889 | }, 890 | { 891 | "inputs": [ 892 | { 893 | "name": "arg0", 894 | "type": "address" 895 | } 896 | ], 897 | "name": "loan_ix", 898 | "outputs": [ 899 | { 900 | "name": "", 901 | "type": "uint256" 902 | } 903 | ], 904 | "stateMutability": "view", 905 | "type": "function" 906 | }, 907 | { 908 | "inputs": [], 909 | "name": "n_loans", 910 | "outputs": [ 911 | { 912 | "name": "", 913 | "type": "uint256" 914 | } 915 | ], 916 | "stateMutability": "view", 917 | "type": "function" 918 | }, 919 | { 920 | "inputs": [], 921 | "name": "minted", 922 | "outputs": [ 923 | { 924 | "name": "", 925 | "type": "uint256" 926 | } 927 | ], 928 | "stateMutability": "view", 929 | "type": "function" 930 | }, 931 | { 932 | "inputs": [], 933 | "name": "redeemed", 934 | "outputs": [ 935 | { 936 | "name": "", 937 | "type": "uint256" 938 | } 939 | ], 940 | "stateMutability": "view", 941 | "type": "function" 942 | }, 943 | { 944 | "inputs": [], 945 | "name": "monetary_policy", 946 | "outputs": [ 947 | { 948 | "name": "", 949 | "type": "address" 950 | } 951 | ], 952 | "stateMutability": "view", 953 | "type": "function" 954 | }, 955 | { 956 | "inputs": [], 957 | "name": "liquidation_discount", 958 | "outputs": [ 959 | { 960 | "name": "", 961 | "type": "uint256" 962 | } 963 | ], 964 | "stateMutability": "view", 965 | "type": "function" 966 | }, 967 | { 968 | "inputs": [], 969 | "name": "loan_discount", 970 | "outputs": [ 971 | { 972 | "name": "", 973 | "type": "uint256" 974 | } 975 | ], 976 | "stateMutability": "view", 977 | "type": "function" 978 | } 979 | ] 980 | -------------------------------------------------------------------------------- /src/constants/abis/llamma.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "anonymous": false, 4 | "inputs": [ 5 | { 6 | "indexed": true, 7 | "name": "buyer", 8 | "type": "address" 9 | }, 10 | { 11 | "indexed": false, 12 | "name": "sold_id", 13 | "type": "uint256" 14 | }, 15 | { 16 | "indexed": false, 17 | "name": "tokens_sold", 18 | "type": "uint256" 19 | }, 20 | { 21 | "indexed": false, 22 | "name": "bought_id", 23 | "type": "uint256" 24 | }, 25 | { 26 | "indexed": false, 27 | "name": "tokens_bought", 28 | "type": "uint256" 29 | } 30 | ], 31 | "name": "TokenExchange", 32 | "type": "event" 33 | }, 34 | { 35 | "anonymous": false, 36 | "inputs": [ 37 | { 38 | "indexed": true, 39 | "name": "provider", 40 | "type": "address" 41 | }, 42 | { 43 | "indexed": false, 44 | "name": "amount", 45 | "type": "uint256" 46 | }, 47 | { 48 | "indexed": false, 49 | "name": "n1", 50 | "type": "int256" 51 | }, 52 | { 53 | "indexed": false, 54 | "name": "n2", 55 | "type": "int256" 56 | } 57 | ], 58 | "name": "Deposit", 59 | "type": "event" 60 | }, 61 | { 62 | "anonymous": false, 63 | "inputs": [ 64 | { 65 | "indexed": true, 66 | "name": "provider", 67 | "type": "address" 68 | }, 69 | { 70 | "indexed": false, 71 | "name": "amount_borrowed", 72 | "type": "uint256" 73 | }, 74 | { 75 | "indexed": false, 76 | "name": "amount_collateral", 77 | "type": "uint256" 78 | } 79 | ], 80 | "name": "Withdraw", 81 | "type": "event" 82 | }, 83 | { 84 | "anonymous": false, 85 | "inputs": [ 86 | { 87 | "indexed": false, 88 | "name": "rate", 89 | "type": "uint256" 90 | }, 91 | { 92 | "indexed": false, 93 | "name": "rate_mul", 94 | "type": "uint256" 95 | }, 96 | { 97 | "indexed": false, 98 | "name": "time", 99 | "type": "uint256" 100 | } 101 | ], 102 | "name": "SetRate", 103 | "type": "event" 104 | }, 105 | { 106 | "anonymous": false, 107 | "inputs": [ 108 | { 109 | "indexed": false, 110 | "name": "fee", 111 | "type": "uint256" 112 | } 113 | ], 114 | "name": "SetFee", 115 | "type": "event" 116 | }, 117 | { 118 | "anonymous": false, 119 | "inputs": [ 120 | { 121 | "indexed": false, 122 | "name": "fee", 123 | "type": "uint256" 124 | } 125 | ], 126 | "name": "SetAdminFee", 127 | "type": "event" 128 | }, 129 | { 130 | "anonymous": false, 131 | "inputs": [ 132 | { 133 | "indexed": false, 134 | "name": "price_oracle", 135 | "type": "address" 136 | } 137 | ], 138 | "name": "SetPriceOracle", 139 | "type": "event" 140 | }, 141 | { 142 | "inputs": [ 143 | { 144 | "name": "_borrowed_token", 145 | "type": "address" 146 | }, 147 | { 148 | "name": "_borrowed_precision", 149 | "type": "uint256" 150 | }, 151 | { 152 | "name": "_collateral_token", 153 | "type": "address" 154 | }, 155 | { 156 | "name": "_collateral_precision", 157 | "type": "uint256" 158 | }, 159 | { 160 | "name": "_A", 161 | "type": "uint256" 162 | }, 163 | { 164 | "name": "_sqrt_band_ratio", 165 | "type": "uint256" 166 | }, 167 | { 168 | "name": "_log_A_ratio", 169 | "type": "int256" 170 | }, 171 | { 172 | "name": "_base_price", 173 | "type": "uint256" 174 | }, 175 | { 176 | "name": "fee", 177 | "type": "uint256" 178 | }, 179 | { 180 | "name": "admin_fee", 181 | "type": "uint256" 182 | }, 183 | { 184 | "name": "_price_oracle_contract", 185 | "type": "address" 186 | } 187 | ], 188 | "name": "constructor", 189 | "outputs": [], 190 | "stateMutability": "nonpayable", 191 | "type": "constructor" 192 | }, 193 | { 194 | "inputs": [ 195 | { 196 | "name": "_admin", 197 | "type": "address" 198 | } 199 | ], 200 | "name": "set_admin", 201 | "outputs": [], 202 | "stateMutability": "nonpayable", 203 | "type": "function" 204 | }, 205 | { 206 | "inputs": [ 207 | { 208 | "name": "i", 209 | "type": "uint256" 210 | } 211 | ], 212 | "name": "coins", 213 | "outputs": [ 214 | { 215 | "name": "", 216 | "type": "address" 217 | } 218 | ], 219 | "stateMutability": "pure", 220 | "type": "function" 221 | }, 222 | { 223 | "inputs": [], 224 | "name": "price_oracle", 225 | "outputs": [ 226 | { 227 | "name": "", 228 | "type": "uint256" 229 | } 230 | ], 231 | "stateMutability": "view", 232 | "type": "function" 233 | }, 234 | { 235 | "inputs": [], 236 | "name": "dynamic_fee", 237 | "outputs": [ 238 | { 239 | "name": "", 240 | "type": "uint256" 241 | } 242 | ], 243 | "stateMutability": "view", 244 | "type": "function" 245 | }, 246 | { 247 | "inputs": [], 248 | "name": "get_rate_mul", 249 | "outputs": [ 250 | { 251 | "name": "", 252 | "type": "uint256" 253 | } 254 | ], 255 | "stateMutability": "view", 256 | "type": "function" 257 | }, 258 | { 259 | "inputs": [], 260 | "name": "get_base_price", 261 | "outputs": [ 262 | { 263 | "name": "", 264 | "type": "uint256" 265 | } 266 | ], 267 | "stateMutability": "view", 268 | "type": "function" 269 | }, 270 | { 271 | "inputs": [ 272 | { 273 | "name": "n", 274 | "type": "int256" 275 | } 276 | ], 277 | "name": "p_current_up", 278 | "outputs": [ 279 | { 280 | "name": "", 281 | "type": "uint256" 282 | } 283 | ], 284 | "stateMutability": "view", 285 | "type": "function" 286 | }, 287 | { 288 | "inputs": [ 289 | { 290 | "name": "n", 291 | "type": "int256" 292 | } 293 | ], 294 | "name": "p_current_down", 295 | "outputs": [ 296 | { 297 | "name": "", 298 | "type": "uint256" 299 | } 300 | ], 301 | "stateMutability": "view", 302 | "type": "function" 303 | }, 304 | { 305 | "inputs": [ 306 | { 307 | "name": "n", 308 | "type": "int256" 309 | } 310 | ], 311 | "name": "p_oracle_up", 312 | "outputs": [ 313 | { 314 | "name": "", 315 | "type": "uint256" 316 | } 317 | ], 318 | "stateMutability": "view", 319 | "type": "function" 320 | }, 321 | { 322 | "inputs": [ 323 | { 324 | "name": "n", 325 | "type": "int256" 326 | } 327 | ], 328 | "name": "p_oracle_down", 329 | "outputs": [ 330 | { 331 | "name": "", 332 | "type": "uint256" 333 | } 334 | ], 335 | "stateMutability": "view", 336 | "type": "function" 337 | }, 338 | { 339 | "inputs": [], 340 | "name": "get_p", 341 | "outputs": [ 342 | { 343 | "name": "", 344 | "type": "uint256" 345 | } 346 | ], 347 | "stateMutability": "view", 348 | "type": "function" 349 | }, 350 | { 351 | "inputs": [ 352 | { 353 | "name": "user", 354 | "type": "address" 355 | } 356 | ], 357 | "name": "read_user_tick_numbers", 358 | "outputs": [ 359 | { 360 | "name": "", 361 | "type": "int256[2]" 362 | } 363 | ], 364 | "stateMutability": "view", 365 | "type": "function" 366 | }, 367 | { 368 | "inputs": [ 369 | { 370 | "name": "n_end", 371 | "type": "int256" 372 | } 373 | ], 374 | "name": "can_skip_bands", 375 | "outputs": [ 376 | { 377 | "name": "", 378 | "type": "bool" 379 | } 380 | ], 381 | "stateMutability": "view", 382 | "type": "function" 383 | }, 384 | { 385 | "inputs": [], 386 | "name": "active_band_with_skip", 387 | "outputs": [ 388 | { 389 | "name": "", 390 | "type": "int256" 391 | } 392 | ], 393 | "stateMutability": "view", 394 | "type": "function" 395 | }, 396 | { 397 | "inputs": [ 398 | { 399 | "name": "user", 400 | "type": "address" 401 | } 402 | ], 403 | "name": "has_liquidity", 404 | "outputs": [ 405 | { 406 | "name": "", 407 | "type": "bool" 408 | } 409 | ], 410 | "stateMutability": "view", 411 | "type": "function" 412 | }, 413 | { 414 | "inputs": [ 415 | { 416 | "name": "user", 417 | "type": "address" 418 | }, 419 | { 420 | "name": "amount", 421 | "type": "uint256" 422 | }, 423 | { 424 | "name": "n1", 425 | "type": "int256" 426 | }, 427 | { 428 | "name": "n2", 429 | "type": "int256" 430 | } 431 | ], 432 | "name": "deposit_range", 433 | "outputs": [], 434 | "stateMutability": "nonpayable", 435 | "type": "function" 436 | }, 437 | { 438 | "inputs": [ 439 | { 440 | "name": "user", 441 | "type": "address" 442 | }, 443 | { 444 | "name": "frac", 445 | "type": "uint256" 446 | } 447 | ], 448 | "name": "withdraw", 449 | "outputs": [ 450 | { 451 | "name": "", 452 | "type": "uint256[2]" 453 | } 454 | ], 455 | "stateMutability": "nonpayable", 456 | "type": "function" 457 | }, 458 | { 459 | "inputs": [ 460 | { 461 | "name": "i", 462 | "type": "uint256" 463 | }, 464 | { 465 | "name": "j", 466 | "type": "uint256" 467 | }, 468 | { 469 | "name": "in_amount", 470 | "type": "uint256" 471 | } 472 | ], 473 | "name": "get_dy", 474 | "outputs": [ 475 | { 476 | "name": "", 477 | "type": "uint256" 478 | } 479 | ], 480 | "stateMutability": "view", 481 | "type": "function" 482 | }, 483 | { 484 | "inputs": [ 485 | { 486 | "name": "i", 487 | "type": "uint256" 488 | }, 489 | { 490 | "name": "j", 491 | "type": "uint256" 492 | }, 493 | { 494 | "name": "in_amount", 495 | "type": "uint256" 496 | } 497 | ], 498 | "name": "get_dxdy", 499 | "outputs": [ 500 | { 501 | "name": "", 502 | "type": "uint256" 503 | }, 504 | { 505 | "name": "", 506 | "type": "uint256" 507 | } 508 | ], 509 | "stateMutability": "view", 510 | "type": "function" 511 | }, 512 | { 513 | "inputs": [ 514 | { 515 | "name": "i", 516 | "type": "uint256" 517 | }, 518 | { 519 | "name": "j", 520 | "type": "uint256" 521 | }, 522 | { 523 | "name": "out_amount", 524 | "type": "uint256" 525 | } 526 | ], 527 | "name": "get_dx", 528 | "outputs": [ 529 | { 530 | "name": "", 531 | "type": "uint256" 532 | } 533 | ], 534 | "stateMutability": "view", 535 | "type": "function" 536 | }, 537 | { 538 | "inputs": [ 539 | { 540 | "name": "i", 541 | "type": "uint256" 542 | }, 543 | { 544 | "name": "j", 545 | "type": "uint256" 546 | }, 547 | { 548 | "name": "out_amount", 549 | "type": "uint256" 550 | } 551 | ], 552 | "name": "get_dydx", 553 | "outputs": [ 554 | { 555 | "name": "", 556 | "type": "uint256" 557 | }, 558 | { 559 | "name": "", 560 | "type": "uint256" 561 | } 562 | ], 563 | "stateMutability": "view", 564 | "type": "function" 565 | }, 566 | { 567 | "inputs": [ 568 | { 569 | "name": "i", 570 | "type": "uint256" 571 | }, 572 | { 573 | "name": "j", 574 | "type": "uint256" 575 | }, 576 | { 577 | "name": "in_amount", 578 | "type": "uint256" 579 | }, 580 | { 581 | "name": "min_amount", 582 | "type": "uint256" 583 | } 584 | ], 585 | "name": "exchange", 586 | "outputs": [ 587 | { 588 | "name": "", 589 | "type": "uint256[2]" 590 | } 591 | ], 592 | "stateMutability": "nonpayable", 593 | "type": "function" 594 | }, 595 | { 596 | "inputs": [ 597 | { 598 | "name": "i", 599 | "type": "uint256" 600 | }, 601 | { 602 | "name": "j", 603 | "type": "uint256" 604 | }, 605 | { 606 | "name": "out_amount", 607 | "type": "uint256" 608 | }, 609 | { 610 | "name": "max_amount", 611 | "type": "uint256" 612 | } 613 | ], 614 | "name": "exchange_dy", 615 | "outputs": [ 616 | { 617 | "name": "", 618 | "type": "uint256[2]" 619 | } 620 | ], 621 | "stateMutability": "nonpayable", 622 | "type": "function" 623 | }, 624 | { 625 | "inputs": [ 626 | { 627 | "name": "i", 628 | "type": "uint256" 629 | }, 630 | { 631 | "name": "j", 632 | "type": "uint256" 633 | }, 634 | { 635 | "name": "out_amount", 636 | "type": "uint256" 637 | }, 638 | { 639 | "name": "max_amount", 640 | "type": "uint256" 641 | }, 642 | { 643 | "name": "_for", 644 | "type": "address" 645 | } 646 | ], 647 | "name": "exchange_dy", 648 | "outputs": [ 649 | { 650 | "name": "", 651 | "type": "uint256[2]" 652 | } 653 | ], 654 | "stateMutability": "nonpayable", 655 | "type": "function" 656 | }, 657 | { 658 | "inputs": [ 659 | { 660 | "name": "user", 661 | "type": "address" 662 | } 663 | ], 664 | "name": "get_y_up", 665 | "outputs": [ 666 | { 667 | "name": "", 668 | "type": "uint256" 669 | } 670 | ], 671 | "stateMutability": "view", 672 | "type": "function" 673 | }, 674 | { 675 | "inputs": [ 676 | { 677 | "name": "user", 678 | "type": "address" 679 | } 680 | ], 681 | "name": "get_x_down", 682 | "outputs": [ 683 | { 684 | "name": "", 685 | "type": "uint256" 686 | } 687 | ], 688 | "stateMutability": "view", 689 | "type": "function" 690 | }, 691 | { 692 | "inputs": [ 693 | { 694 | "name": "user", 695 | "type": "address" 696 | } 697 | ], 698 | "name": "get_sum_xy", 699 | "outputs": [ 700 | { 701 | "name": "", 702 | "type": "uint256[2]" 703 | } 704 | ], 705 | "stateMutability": "view", 706 | "type": "function" 707 | }, 708 | { 709 | "inputs": [ 710 | { 711 | "name": "user", 712 | "type": "address" 713 | } 714 | ], 715 | "name": "get_xy", 716 | "outputs": [ 717 | { 718 | "name": "", 719 | "type": "uint256[][2]" 720 | } 721 | ], 722 | "stateMutability": "view", 723 | "type": "function" 724 | }, 725 | { 726 | "inputs": [ 727 | { 728 | "name": "p", 729 | "type": "uint256" 730 | } 731 | ], 732 | "name": "get_amount_for_price", 733 | "outputs": [ 734 | { 735 | "name": "", 736 | "type": "uint256" 737 | }, 738 | { 739 | "name": "", 740 | "type": "bool" 741 | } 742 | ], 743 | "stateMutability": "view", 744 | "type": "function" 745 | }, 746 | { 747 | "inputs": [ 748 | { 749 | "name": "rate", 750 | "type": "uint256" 751 | } 752 | ], 753 | "name": "set_rate", 754 | "outputs": [ 755 | { 756 | "name": "", 757 | "type": "uint256" 758 | } 759 | ], 760 | "stateMutability": "nonpayable", 761 | "type": "function" 762 | }, 763 | { 764 | "inputs": [ 765 | { 766 | "name": "fee", 767 | "type": "uint256" 768 | } 769 | ], 770 | "name": "set_fee", 771 | "outputs": [], 772 | "stateMutability": "nonpayable", 773 | "type": "function" 774 | }, 775 | { 776 | "inputs": [ 777 | { 778 | "name": "fee", 779 | "type": "uint256" 780 | } 781 | ], 782 | "name": "set_admin_fee", 783 | "outputs": [], 784 | "stateMutability": "nonpayable", 785 | "type": "function" 786 | }, 787 | { 788 | "inputs": [], 789 | "name": "reset_admin_fees", 790 | "outputs": [], 791 | "stateMutability": "nonpayable", 792 | "type": "function" 793 | }, 794 | { 795 | "inputs": [ 796 | { 797 | "name": "liquidity_mining_callback", 798 | "type": "address" 799 | } 800 | ], 801 | "name": "set_callback", 802 | "outputs": [], 803 | "stateMutability": "nonpayable", 804 | "type": "function" 805 | }, 806 | { 807 | "inputs": [], 808 | "name": "admin", 809 | "outputs": [ 810 | { 811 | "name": "", 812 | "type": "address" 813 | } 814 | ], 815 | "stateMutability": "view", 816 | "type": "function" 817 | }, 818 | { 819 | "inputs": [], 820 | "name": "A", 821 | "outputs": [ 822 | { 823 | "name": "", 824 | "type": "uint256" 825 | } 826 | ], 827 | "stateMutability": "view", 828 | "type": "function" 829 | }, 830 | { 831 | "inputs": [], 832 | "name": "fee", 833 | "outputs": [ 834 | { 835 | "name": "", 836 | "type": "uint256" 837 | } 838 | ], 839 | "stateMutability": "view", 840 | "type": "function" 841 | }, 842 | { 843 | "inputs": [], 844 | "name": "admin_fee", 845 | "outputs": [ 846 | { 847 | "name": "", 848 | "type": "uint256" 849 | } 850 | ], 851 | "stateMutability": "view", 852 | "type": "function" 853 | }, 854 | { 855 | "inputs": [], 856 | "name": "rate", 857 | "outputs": [ 858 | { 859 | "name": "", 860 | "type": "uint256" 861 | } 862 | ], 863 | "stateMutability": "view", 864 | "type": "function" 865 | }, 866 | { 867 | "inputs": [], 868 | "name": "active_band", 869 | "outputs": [ 870 | { 871 | "name": "", 872 | "type": "int256" 873 | } 874 | ], 875 | "stateMutability": "view", 876 | "type": "function" 877 | }, 878 | { 879 | "inputs": [], 880 | "name": "min_band", 881 | "outputs": [ 882 | { 883 | "name": "", 884 | "type": "int256" 885 | } 886 | ], 887 | "stateMutability": "view", 888 | "type": "function" 889 | }, 890 | { 891 | "inputs": [], 892 | "name": "max_band", 893 | "outputs": [ 894 | { 895 | "name": "", 896 | "type": "int256" 897 | } 898 | ], 899 | "stateMutability": "view", 900 | "type": "function" 901 | }, 902 | { 903 | "inputs": [], 904 | "name": "admin_fees_x", 905 | "outputs": [ 906 | { 907 | "name": "", 908 | "type": "uint256" 909 | } 910 | ], 911 | "stateMutability": "view", 912 | "type": "function" 913 | }, 914 | { 915 | "inputs": [], 916 | "name": "admin_fees_y", 917 | "outputs": [ 918 | { 919 | "name": "", 920 | "type": "uint256" 921 | } 922 | ], 923 | "stateMutability": "view", 924 | "type": "function" 925 | }, 926 | { 927 | "inputs": [], 928 | "name": "price_oracle_contract", 929 | "outputs": [ 930 | { 931 | "name": "", 932 | "type": "address" 933 | } 934 | ], 935 | "stateMutability": "view", 936 | "type": "function" 937 | }, 938 | { 939 | "inputs": [ 940 | { 941 | "name": "arg0", 942 | "type": "int256" 943 | } 944 | ], 945 | "name": "bands_x", 946 | "outputs": [ 947 | { 948 | "name": "", 949 | "type": "uint256" 950 | } 951 | ], 952 | "stateMutability": "view", 953 | "type": "function" 954 | }, 955 | { 956 | "inputs": [ 957 | { 958 | "name": "arg0", 959 | "type": "int256" 960 | } 961 | ], 962 | "name": "bands_y", 963 | "outputs": [ 964 | { 965 | "name": "", 966 | "type": "uint256" 967 | } 968 | ], 969 | "stateMutability": "view", 970 | "type": "function" 971 | }, 972 | { 973 | "inputs": [], 974 | "name": "liquidity_mining_callback", 975 | "outputs": [ 976 | { 977 | "name": "", 978 | "type": "address" 979 | } 980 | ], 981 | "stateMutability": "view", 982 | "type": "function" 983 | } 984 | ] 985 | -------------------------------------------------------------------------------- /src/constants/coins.ts: -------------------------------------------------------------------------------- 1 | import { lowerCaseValues } from "./utils"; 2 | 3 | export const COINS = lowerCaseValues({ 4 | 'eth': '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee', 5 | 'sfrxeth': '0xac3E018457B222d93114458476f3E3416Abbe38F', 6 | 'crvusd': '0xf939E0A03FB07F59A73314E73794Be0E57ac1b4E', 7 | }); -------------------------------------------------------------------------------- /src/constants/llammas.ts: -------------------------------------------------------------------------------- 1 | import { IDict, ILlamma } from "../interfaces"; 2 | import MonetaryPolicyABI from "../constants/abis/MonetaryPolicy.json"; 3 | import MonetaryPolicy2ABI from "../constants/abis/MonetaryPolicy2.json"; 4 | import { lowerCaseLlammasAddresses } from "./utils"; 5 | 6 | 7 | export const LLAMMAS: IDict = lowerCaseLlammasAddresses({ 8 | sfrxeth: { 9 | amm_address: '0x136e783846ef68C8Bd00a3369F787dF8d683a696', 10 | controller_address: '0x8472A9A7632b173c8Cf3a86D3afec50c35548e76', 11 | monetary_policy_address: '0xc684432FD6322c6D58b6bC5d28B18569aA0AD0A1', 12 | collateral_address: '0xac3E018457B222d93114458476f3E3416Abbe38F', 13 | leverage_zap: '0xb556FA4C4752321B3154f08DfBDFCF34847f2eac', 14 | deleverage_zap: '0xF113929F69FAbE165A2280CaC00c5f77196Aa34C', 15 | collateral_symbol: 'sfrxETH', 16 | collateral_decimals: 18, 17 | min_bands: 4, 18 | max_bands: 50, 19 | default_bands: 10, 20 | A: 100, 21 | monetary_policy_abi: MonetaryPolicyABI, 22 | }, 23 | wsteth: { 24 | amm_address: '0x37417b2238aa52d0dd2d6252d989e728e8f706e4', 25 | controller_address: '0x100daa78fc509db39ef7d04de0c1abd299f4c6ce', 26 | monetary_policy_address: '0x1E7d3bf98d3f8D8CE193236c3e0eC4b00e32DaaE', 27 | collateral_address: '0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0', 28 | leverage_zap: '0x293436d4e4a15FBc6cCC400c14a01735E5FC74fd', 29 | deleverage_zap: '0x600E571106C31c4Ca1bF4177bA808E37146A4A0C', 30 | collateral_symbol: 'wstETH', 31 | collateral_decimals: 18, 32 | min_bands: 4, 33 | max_bands: 50, 34 | default_bands: 10, 35 | A: 100, 36 | monetary_policy_abi: MonetaryPolicy2ABI, 37 | }, 38 | wbtc: { 39 | amm_address: '0xe0438eb3703bf871e31ce639bd351109c88666ea', 40 | controller_address: '0x4e59541306910ad6dc1dac0ac9dfb29bd9f15c67', 41 | monetary_policy_address: '0x1E7d3bf98d3f8D8CE193236c3e0eC4b00e32DaaE', 42 | collateral_address: '0x2260fac5e5542a773aa44fbcfedf7c193bc2c599', 43 | leverage_zap: '0xA2518b71ee64E910741f5Cf480b19E8e402de4d7', 44 | deleverage_zap: '0xb911D7e59BA82FDF477a2Ab22Ff25125072C9282', 45 | health_calculator_zap: "0xCF61Ee62b136e3553fB545bd8fEc11fb7f830d6A", 46 | collateral_symbol: 'WBTC', 47 | collateral_decimals: 8, 48 | min_bands: 4, 49 | max_bands: 50, 50 | default_bands: 10, 51 | A: 100, 52 | monetary_policy_abi: MonetaryPolicy2ABI, 53 | }, 54 | eth: { 55 | amm_address: '0x1681195c176239ac5e72d9aebacf5b2492e0c4ee', 56 | controller_address: '0xa920de414ea4ab66b97da1bfe9e6eca7d4219635', 57 | monetary_policy_address: '0x1E7d3bf98d3f8D8CE193236c3e0eC4b00e32DaaE', 58 | collateral_address: '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee', 59 | leverage_zap: '0xd3e576B5DcDe3580420A5Ef78F3639BA9cd1B967', 60 | deleverage_zap: '0x9bE82CdDB5c266E010C97e4B1B5B2DF53C16384d', 61 | collateral_symbol: 'ETH', 62 | collateral_decimals: 18, 63 | min_bands: 4, 64 | max_bands: 50, 65 | default_bands: 10, 66 | A: 100, 67 | monetary_policy_abi: MonetaryPolicy2ABI, 68 | }, 69 | sfrxeth2: { 70 | amm_address: '0xfa96ad0a9e64261db86950e2da362f5572c5c6fd', 71 | controller_address: '0xec0820efafc41d8943ee8de495fc9ba8495b15cf', 72 | monetary_policy_address: '0x1e7d3bf98d3f8d8ce193236c3e0ec4b00e32daae', 73 | collateral_address: '0xac3e018457b222d93114458476f3e3416abbe38f', 74 | leverage_zap: '0x43eCFfe6c6C1b9F24AeB5C180E659c2a6FCe11Bc', 75 | deleverage_zap: '0x2bc706B83aB08d0437b8A397242C3284B5f81D74', 76 | collateral_symbol: 'sfrxETH', 77 | collateral_decimals: 18, 78 | min_bands: 4, 79 | max_bands: 50, 80 | default_bands: 10, 81 | A: 100, 82 | monetary_policy_abi: MonetaryPolicy2ABI, 83 | }, 84 | tbtc: { 85 | amm_address: '0xf9bd9da2427a50908c4c6d1599d8e62837c2bcb0', 86 | controller_address: '0x1c91da0223c763d2e0173243eadaa0a2ea47e704', 87 | monetary_policy_address: '0xb8687d7dc9d8fa32fabde63e19b2dbc9bb8b2138', 88 | collateral_address: '0x18084fba666a33d37592fa2633fd49a74dd93a88', 89 | leverage_zap: '0xD79964C70Cb06224FdA4c48387B53E9819bcB71c', 90 | deleverage_zap: '0xAA25a6Fa9e4dADaE0d3EE59bEA19fbcf0284830C', 91 | collateral_symbol: 'tBTC', 92 | collateral_decimals: 18, 93 | min_bands: 4, 94 | max_bands: 50, 95 | default_bands: 10, 96 | A: 100, 97 | monetary_policy_abi: MonetaryPolicy2ABI, 98 | }, 99 | }); 100 | -------------------------------------------------------------------------------- /src/constants/utils.ts: -------------------------------------------------------------------------------- 1 | import {IDict, ILlamma} from "../interfaces"; 2 | 3 | export const lowerCaseLlammasAddresses = (llammas: IDict): IDict => { 4 | for (const llammaId in llammas) { 5 | if (!Object.prototype.hasOwnProperty.call(llammas, llammaId)) continue; 6 | const llamma = llammas[llammaId]; 7 | llamma.amm_address = llamma.amm_address.toLowerCase(); 8 | llamma.controller_address = llamma.controller_address.toLowerCase(); 9 | llamma.collateral_address = llamma.collateral_address.toLowerCase(); 10 | llamma.monetary_policy_address = llamma.monetary_policy_address.toLowerCase(); 11 | llamma.leverage_zap = llamma.leverage_zap.toLowerCase(); 12 | } 13 | 14 | return llammas 15 | } 16 | 17 | export const extractDecimals = (llammas: IDict): IDict => { 18 | const DECIMALS: IDict = {}; 19 | for (const llammaId in llammas) { 20 | if (!Object.prototype.hasOwnProperty.call(llammas, llammaId)) continue; 21 | const llamma = llammas[llammaId]; 22 | 23 | // Collateral 24 | DECIMALS[llamma.collateral_address] = llamma.collateral_decimals; 25 | } 26 | 27 | return DECIMALS 28 | } 29 | 30 | export const lowerCaseValues = (dict: IDict): IDict => { 31 | // @ts-ignore 32 | return Object.fromEntries(Object.entries(dict).map((entry) => [entry[0], entry[1].toLowerCase()])) 33 | } 34 | -------------------------------------------------------------------------------- /src/crvusd.ts: -------------------------------------------------------------------------------- 1 | import { ethers, Contract } from "ethers"; 2 | import { Networkish } from "@ethersproject/networks"; 3 | import { Provider as MulticallProvider, Contract as MulticallContract } from 'ethcall'; 4 | import { Icrvusd, IDict, ILlamma } from "./interfaces"; 5 | import ERC20ABI from "./constants/abis/ERC20.json"; 6 | import MonetaryPolicy2ABI from "./constants/abis/MonetaryPolicy2.json"; 7 | import FactoryABI from "./constants/abis/Factory.json"; 8 | import controllerABI from "./constants/abis/controller.json"; 9 | import controllerV2ABI from "./constants/abis/controller_v2.json"; 10 | import llammaABI from "./constants/abis/llamma.json"; 11 | import HealthCalculatorZapABI from "./constants/abis/HealthCalculatorZap.json"; 12 | import LeverageZapABI from "./constants/abis/LeverageZap.json"; 13 | import DeleverageZapABI from "./constants/abis/DeleverageZap.json"; 14 | import PegKeeper from "./constants/abis/PegKeeper.json"; 15 | import { LLAMMAS } from "./constants/llammas"; 16 | import { COINS } from "./constants/coins"; 17 | import { extractDecimals } from "./constants/utils"; 18 | 19 | 20 | class Crvusd implements Icrvusd { 21 | address: string; 22 | provider: ethers.providers.Web3Provider | ethers.providers.JsonRpcProvider; 23 | multicallProvider: MulticallProvider; 24 | signer: ethers.Signer | null; 25 | signerAddress: string; 26 | chainId: number; 27 | contracts: { [index: string]: { contract: Contract, multicallContract: MulticallContract } }; 28 | feeData: { gasPrice?: number, maxFeePerGas?: number, maxPriorityFeePerGas?: number }; 29 | constantOptions: { gasLimit: number }; 30 | options: { gasPrice?: number | ethers.BigNumber, maxFeePerGas?: number | ethers.BigNumber, maxPriorityFeePerGas?: number | ethers.BigNumber }; 31 | constants: { 32 | LLAMMAS: IDict, 33 | COINS: IDict, 34 | DECIMALS: IDict, 35 | NETWORK_NAME: "ethereum", 36 | FACTORY: string, 37 | PEG_KEEPERS: string[], 38 | WETH: string, 39 | }; 40 | 41 | constructor() { 42 | this.address = COINS.crvusd.toLowerCase(); 43 | // @ts-ignore 44 | this.provider = null; 45 | // @ts-ignore 46 | this.signer = null; 47 | this.signerAddress = ""; 48 | this.chainId = 0; 49 | // @ts-ignore 50 | this.multicallProvider = null; 51 | this.contracts = {}; 52 | this.feeData = {} 53 | this.constantOptions = { gasLimit: 35000000 } 54 | this.options = {}; 55 | this.constants = { 56 | LLAMMAS: {}, 57 | COINS: {}, 58 | DECIMALS: {}, 59 | NETWORK_NAME: "ethereum", 60 | FACTORY: "0xC9332fdCB1C491Dcc683bAe86Fe3cb70360738BC".toLowerCase(), 61 | PEG_KEEPERS: [ 62 | '0x9201da0d97caaaff53f01b2fb56767c7072de340'.toLowerCase(), 63 | '0xfb726f57d251ab5c731e5c64ed4f5f94351ef9f3'.toLowerCase(), 64 | '0x3fa20eaa107de08b38a8734063d605d5842fe09c'.toLowerCase(), 65 | '0x0a05ff644878b908ef8eb29542aa88c07d9797d3'.toLowerCase(), 66 | '0x503E1Bf274e7a6c64152395aE8eB57ec391F91F8'.toLowerCase(), 67 | ], 68 | WETH: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2".toLowerCase(), 69 | }; 70 | } 71 | 72 | async init( 73 | providerType: 'JsonRpc' | 'Web3' | 'Infura' | 'Alchemy', 74 | providerSettings: { url?: string, privateKey?: string } | { externalProvider: ethers.providers.ExternalProvider } | { network?: Networkish, apiKey?: string }, 75 | options: { gasPrice?: number, maxFeePerGas?: number, maxPriorityFeePerGas?: number, chainId?: number } = {} // gasPrice in Gwei 76 | ): Promise { 77 | // @ts-ignore 78 | this.provider = null; 79 | // @ts-ignore 80 | this.signer = null; 81 | this.signerAddress = ""; 82 | this.chainId = 0; 83 | // @ts-ignore 84 | this.multicallProvider = null; 85 | this.contracts = {}; 86 | this.feeData = {} 87 | this.constantOptions = { gasLimit: 12000000 } 88 | this.options = {}; 89 | this.constants.LLAMMAS = {...LLAMMAS} 90 | 91 | // JsonRpc provider 92 | if (providerType.toLowerCase() === 'JsonRpc'.toLowerCase()) { 93 | providerSettings = providerSettings as { url: string, privateKey: string }; 94 | 95 | if (providerSettings.url) { 96 | this.provider = this.provider = new ethers.providers.JsonRpcProvider(providerSettings.url); 97 | } else { 98 | this.provider = new ethers.providers.JsonRpcProvider('http://localhost:8545/'); 99 | } 100 | 101 | if (providerSettings.privateKey) { 102 | this.signer = new ethers.Wallet(providerSettings.privateKey, this.provider); 103 | } else { 104 | this.signer = this.provider.getSigner(); 105 | } 106 | // Web3 provider 107 | } else if (providerType.toLowerCase() === 'Web3'.toLowerCase()) { 108 | providerSettings = providerSettings as { externalProvider: ethers.providers.ExternalProvider }; 109 | this.provider = new ethers.providers.Web3Provider(providerSettings.externalProvider); 110 | this.signer = this.provider.getSigner(); 111 | // Infura provider 112 | } else if (providerType.toLowerCase() === 'Infura'.toLowerCase()) { 113 | providerSettings = providerSettings as { network?: Networkish, apiKey?: string }; 114 | this.provider = new ethers.providers.InfuraProvider(providerSettings.network, providerSettings.apiKey); 115 | this.signer = null; 116 | // Alchemy provider 117 | } else if (providerType.toLowerCase() === 'Alchemy'.toLowerCase()) { 118 | providerSettings = providerSettings as { network?: Networkish, apiKey?: string }; 119 | this.provider = new ethers.providers.AlchemyProvider(providerSettings.network, providerSettings.apiKey); 120 | this.signer = null; 121 | } else { 122 | throw Error('Wrong providerType'); 123 | } 124 | 125 | this.multicallProvider = new MulticallProvider(); 126 | await this.multicallProvider.init(this.provider); 127 | 128 | if (this.signer) { 129 | try { 130 | this.signerAddress = await this.signer.getAddress(); 131 | } catch (err) { 132 | this.signer = null; 133 | } 134 | } else { 135 | this.signerAddress = ''; 136 | } 137 | 138 | this.feeData = { gasPrice: options.gasPrice, maxFeePerGas: options.maxFeePerGas, maxPriorityFeePerGas: options.maxPriorityFeePerGas }; 139 | await this.updateFeeData(); 140 | 141 | this.setContract(this.address, ERC20ABI); 142 | for (const llamma of Object.values(this.constants.LLAMMAS)) { 143 | this.setContract(llamma.amm_address, llammaABI); 144 | this.setContract(llamma.controller_address, controllerABI); 145 | const monetary_policy_address = await this.contracts[llamma.controller_address].contract.monetary_policy(this.constantOptions); 146 | llamma.monetary_policy_address = monetary_policy_address.toLowerCase(); 147 | this.setContract(llamma.monetary_policy_address, llamma.monetary_policy_abi); 148 | if (llamma.collateral_address === "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee") { 149 | this.setContract(this.constants.WETH, ERC20ABI); 150 | } else { 151 | this.setContract(llamma.collateral_address, ERC20ABI); 152 | } 153 | this.setContract(llamma.leverage_zap, LeverageZapABI); 154 | this.setContract(llamma.deleverage_zap, DeleverageZapABI); 155 | if (llamma.health_calculator_zap) this.setContract(llamma.health_calculator_zap, HealthCalculatorZapABI); 156 | } 157 | for (const pegKeeper of this.constants.PEG_KEEPERS) { 158 | this.setContract(pegKeeper, PegKeeper); 159 | } 160 | 161 | // Fetch new llammas 162 | 163 | this.setContract(this.constants.FACTORY, FactoryABI); 164 | const factoryContract = this.contracts[this.constants.FACTORY].contract; 165 | const factoryMulticallContract = this.contracts[this.constants.FACTORY].multicallContract; 166 | 167 | const N1 = Object.keys(this.constants.LLAMMAS).length; 168 | const N2 = await factoryContract.n_collaterals(this.constantOptions); 169 | let calls = []; 170 | for (let i = N1; i < N2; i++) { 171 | calls.push( 172 | factoryMulticallContract.collaterals(i), 173 | factoryMulticallContract.amms(i), 174 | factoryMulticallContract.controllers(i) 175 | ); 176 | } 177 | const res: string[] = (await this.multicallProvider.all(calls) as string[]).map((c) => c.toLowerCase()); 178 | const collaterals = res.filter((a, i) => i % 3 == 0) as string[]; 179 | const amms = res.filter((a, i) => i % 3 == 1) as string[]; 180 | const controllers = res.filter((a, i) => i % 3 == 2) as string[]; 181 | 182 | if (collaterals.length > 0) { 183 | for (const collateral of collaterals) this.setContract(collateral, ERC20ABI); 184 | 185 | calls = []; 186 | for (const collateral of collaterals) { 187 | calls.push( 188 | this.contracts[collateral].multicallContract.symbol(), 189 | this.contracts[collateral].multicallContract.decimals() 190 | ) 191 | } 192 | const res = (await this.multicallProvider.all(calls)).map((x) => { 193 | if (typeof x === "string") return x.toLowerCase(); 194 | return x; 195 | }); 196 | 197 | calls = []; 198 | 199 | for(const amm of amms) { 200 | this.setContract(amm, llammaABI); 201 | calls.push( 202 | this.contracts[amm].multicallContract.A() 203 | ) 204 | } 205 | 206 | const AParams = (await this.multicallProvider.all(calls)).map((x) => { 207 | return (x as ethers.BigNumber).toNumber(); 208 | }); 209 | 210 | for (let i = 0; i < collaterals.length; i++) { 211 | const is_eth = collaterals[i] === this.constants.WETH; 212 | const [collateral_symbol, collateral_decimals] = res.splice(0, 2) as [string, number]; 213 | // TODO Should be refactor later 214 | if (i >= collaterals.length - 3) { 215 | console.log('new market',collateral_symbol) 216 | this.setContract(controllers[i], controllerV2ABI); 217 | } else { 218 | console.log('old market',collateral_symbol) 219 | this.setContract(controllers[i], controllerABI); 220 | } 221 | 222 | const monetary_policy_address = (await this.contracts[controllers[i]].contract.monetary_policy(this.constantOptions)).toLowerCase(); 223 | this.setContract(monetary_policy_address, MonetaryPolicy2ABI); 224 | const _llammaId: string = is_eth ? "eth" : collateral_symbol.toLowerCase(); 225 | let llammaId = _llammaId; 226 | let j = 2; 227 | while (llammaId in this.constants.LLAMMAS) llammaId = _llammaId + j++; 228 | this.constants.LLAMMAS[llammaId] = { 229 | amm_address: amms[i], 230 | controller_address: controllers[i], 231 | monetary_policy_address, 232 | collateral_address: is_eth ? "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" : collaterals[i], 233 | leverage_zap: "0x0000000000000000000000000000000000000000", 234 | deleverage_zap: "0x0000000000000000000000000000000000000000", 235 | collateral_symbol: is_eth ? "ETH" : collateral_symbol, 236 | collateral_decimals, 237 | min_bands: 4, 238 | max_bands: 50, 239 | default_bands: 10, 240 | A: AParams[i], 241 | monetary_policy_abi: MonetaryPolicy2ABI, 242 | isNewMarket: i >= collaterals.length - 3, 243 | } 244 | } 245 | } 246 | 247 | this.constants.DECIMALS = extractDecimals(this.constants.LLAMMAS); 248 | this.constants.DECIMALS[this.address] = 18; 249 | this.constants.COINS = COINS; 250 | } 251 | 252 | setContract(address: string, abi: any): void { 253 | this.contracts[address] = { 254 | contract: new Contract(address, abi, this.signer || this.provider), 255 | multicallContract: new MulticallContract(address, abi), 256 | } 257 | } 258 | 259 | setCustomFeeData(customFeeData: { gasPrice?: number, maxFeePerGas?: number, maxPriorityFeePerGas?: number }): void { 260 | this.feeData = { ...this.feeData, ...customFeeData }; 261 | } 262 | 263 | getLlammaList = () => Object.keys(this.constants.LLAMMAS); 264 | 265 | formatUnits(value: ethers.BigNumberish, unit?: string | ethers.BigNumberish): string { 266 | return ethers.utils.formatUnits(value, unit); 267 | } 268 | 269 | parseUnits(value: string, unit?: string | ethers.BigNumberish): ethers.BigNumber { 270 | return ethers.utils.parseUnits(value, unit); 271 | } 272 | 273 | async updateFeeData(): Promise { 274 | const feeData = await this.provider.getFeeData(); 275 | if (feeData.maxFeePerGas === null || feeData.maxPriorityFeePerGas === null) { 276 | delete this.options.maxFeePerGas; 277 | delete this.options.maxPriorityFeePerGas; 278 | 279 | this.options.gasPrice = this.feeData.gasPrice !== undefined ? 280 | ethers.utils.parseUnits(this.feeData.gasPrice.toString(), "gwei") : 281 | (feeData.gasPrice || await this.provider.getGasPrice()); 282 | } else { 283 | delete this.options.gasPrice; 284 | 285 | this.options.maxFeePerGas = this.feeData.maxFeePerGas !== undefined ? 286 | ethers.utils.parseUnits(this.feeData.maxFeePerGas.toString(), "gwei") : 287 | feeData.maxFeePerGas; 288 | this.options.maxPriorityFeePerGas = this.feeData.maxPriorityFeePerGas !== undefined ? 289 | ethers.utils.parseUnits(this.feeData.maxPriorityFeePerGas.toString(), "gwei") : 290 | feeData.maxPriorityFeePerGas; 291 | } 292 | } 293 | } 294 | 295 | export const crvusd = new Crvusd(); 296 | -------------------------------------------------------------------------------- /src/external-api.ts: -------------------------------------------------------------------------------- 1 | import memoize from "memoizee"; 2 | import { IExtendedPoolDataFromApi, INetworkName } from "./interfaces"; 3 | 4 | export const _getPoolsFromApi = memoize( 5 | async (network: INetworkName, poolType: "main" | "crypto" | "factory" | "factory-crvusd" | "factory-crypto"): Promise => { 6 | const url = `https://api.curve.finance/api/getPools/${network}/${poolType}`; 7 | const response = await fetch(url); 8 | const {data} = await response.json() as { data: IExtendedPoolDataFromApi }; 9 | return data ?? { poolData: [], tvl: 0, tvlAll: 0 }; 10 | }, 11 | { 12 | promise: true, 13 | maxAge: 5 * 60 * 1000, // 5m 14 | } 15 | ) 16 | 17 | export const _getUserCollateral = memoize( 18 | async (network: INetworkName, controller: string, user: string): Promise => { 19 | const url = `https://prices.curve.finance/v1/crvusd/collateral_events/${network}/${controller}/${user}`; 20 | const response = await fetch(url); 21 | const {total_deposit} = await response.json() as { total_deposit: string }; 22 | return total_deposit; 23 | }, 24 | { 25 | promise: true, 26 | maxAge: 60 * 1000, // 1m 27 | } 28 | ) -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import { ethers } from "ethers"; 2 | import { Networkish } from "@ethersproject/networks"; 3 | import { LlammaTemplate, getLlamma } from "./llammas"; 4 | import { crvusd as _crvusd } from "./crvusd"; 5 | import { 6 | getBalances, 7 | getAllowance, 8 | hasAllowance, 9 | ensureAllowanceEstimateGas, 10 | ensureAllowance, 11 | getUsdRate, 12 | totalSupply, 13 | getLsdApy, 14 | } from "./utils"; 15 | 16 | 17 | async function init ( 18 | providerType: 'JsonRpc' | 'Web3' | 'Infura' | 'Alchemy', 19 | providerSettings: { url?: string, privateKey?: string } | { externalProvider: ethers.providers.ExternalProvider } | { network?: Networkish, apiKey?: string }, 20 | options: { gasPrice?: number, maxFeePerGas?: number, maxPriorityFeePerGas?: number, chainId?: number } = {} 21 | ): Promise { 22 | await _crvusd.init(providerType, providerSettings, options); 23 | // @ts-ignore 24 | this.signerAddress = _crvusd.signerAddress; 25 | // @ts-ignore 26 | this.chainId = _crvusd.chainId; 27 | } 28 | 29 | function setCustomFeeData (customFeeData: { gasPrice?: number, maxFeePerGas?: number, maxPriorityFeePerGas?: number }): void { 30 | _crvusd.setCustomFeeData(customFeeData); 31 | } 32 | 33 | const crvusd = { 34 | init, 35 | chainId: 0, 36 | signerAddress: '', 37 | LlammaTemplate, 38 | getLlamma, 39 | setCustomFeeData, 40 | getBalances, 41 | getAllowance, 42 | hasAllowance, 43 | ensureAllowance, 44 | getUsdRate, 45 | totalSupply, 46 | getLsdApy, 47 | getLlammaList: _crvusd.getLlammaList, 48 | estimateGas: { 49 | ensureAllowance: ensureAllowanceEstimateGas, 50 | }, 51 | } 52 | 53 | export default crvusd; 54 | -------------------------------------------------------------------------------- /src/interfaces.ts: -------------------------------------------------------------------------------- 1 | import { Contract, ethers } from "ethers"; 2 | import { Contract as MulticallContract, Provider as MulticallProvider } from "ethcall"; 3 | 4 | export interface IDict { 5 | [index: string]: T, 6 | } 7 | 8 | export interface ILlamma { 9 | amm_address: string, 10 | controller_address: string, 11 | monetary_policy_address: string, 12 | collateral_address: string, 13 | leverage_zap: string, 14 | deleverage_zap: string, 15 | health_calculator_zap?: string, 16 | collateral_symbol: string, 17 | collateral_decimals: number, 18 | min_bands: number, 19 | max_bands: number, 20 | default_bands: number, 21 | A: number, 22 | monetary_policy_abi: any 23 | isNewMarket?: boolean 24 | } 25 | 26 | export interface Icrvusd { 27 | provider: ethers.providers.Web3Provider | ethers.providers.JsonRpcProvider, 28 | multicallProvider: MulticallProvider, 29 | signer: ethers.Signer | null, 30 | signerAddress: string, 31 | contracts: { [index: string]: { contract: Contract, multicallContract: MulticallContract } }, 32 | feeData: { gasPrice?: number, maxFeePerGas?: number, maxPriorityFeePerGas?: number }, 33 | constantOptions: { gasLimit: number }, 34 | options: { gasPrice?: number | ethers.BigNumber, maxFeePerGas?: number | ethers.BigNumber, maxPriorityFeePerGas?: number | ethers.BigNumber }, 35 | constants: { 36 | LLAMMAS: IDict, 37 | }; 38 | } 39 | 40 | export type INetworkName = "ethereum"; 41 | 42 | export interface ICoinFromPoolDataApi { 43 | address: string, 44 | symbol: string, 45 | decimals: string, 46 | usdPrice: number | string, 47 | } 48 | 49 | export interface IReward { 50 | gaugeAddress: string, 51 | tokenAddress: string, 52 | tokenPrice?: number, 53 | name?: string, 54 | symbol: string, 55 | decimals?: number, 56 | apy: number 57 | } 58 | 59 | export interface IPoolDataFromApi { 60 | id: string, 61 | name: string, 62 | symbol: string, 63 | assetTypeName: string, 64 | address: string, 65 | lpTokenAddress?: string, 66 | gaugeAddress?: string, 67 | implementation: string, 68 | implementationAddress: string, 69 | coins: ICoinFromPoolDataApi[], 70 | gaugeRewards?: IReward[], 71 | usdTotal: number, 72 | totalSupply: number, 73 | amplificationCoefficient: string, 74 | } 75 | 76 | export interface IExtendedPoolDataFromApi { 77 | poolData: IPoolDataFromApi[], 78 | tvl?: number, 79 | tvlAll: number, 80 | } 81 | -------------------------------------------------------------------------------- /src/llammas/index.ts: -------------------------------------------------------------------------------- 1 | import { getLlamma } from "./llammaConstructor"; 2 | import { LlammaTemplate } from "./LlammaTemplate"; 3 | 4 | export { 5 | getLlamma, 6 | LlammaTemplate, 7 | }; 8 | -------------------------------------------------------------------------------- /src/llammas/llammaConstructor.ts: -------------------------------------------------------------------------------- 1 | import { LlammaTemplate} from "./LlammaTemplate"; 2 | 3 | export const getLlamma = (llammaId: string): LlammaTemplate => { 4 | return new LlammaTemplate(llammaId) 5 | } 6 | -------------------------------------------------------------------------------- /src/utils.ts: -------------------------------------------------------------------------------- 1 | import { ethers } from "ethers"; 2 | import BigNumber from 'bignumber.js'; 3 | import { IDict } from "./interfaces"; 4 | import { _getPoolsFromApi } from "./external-api"; 5 | import { crvusd } from "./crvusd"; 6 | import memoize from "memoizee"; 7 | 8 | export const MAX_ALLOWANCE = ethers.BigNumber.from(2).pow(ethers.BigNumber.from(256)).sub(ethers.BigNumber.from(1)); 9 | export const MAX_ACTIVE_BAND = ethers.BigNumber.from(2).pow(ethers.BigNumber.from(255)).sub(ethers.BigNumber.from(1)); 10 | 11 | // bignumber.js 12 | 13 | export const BN = (val: number | string): BigNumber => new BigNumber(val); 14 | 15 | export const toBN = (n: ethers.BigNumber, decimals = 18): BigNumber => { 16 | return BN(ethers.utils.formatUnits(n, decimals)); 17 | } 18 | 19 | export const toStringFromBN = (bn: BigNumber, decimals = 18): string => { 20 | return bn.toFixed(decimals); 21 | } 22 | 23 | export const fromBN = (bn: BigNumber, decimals = 18): ethers.BigNumber => { 24 | return ethers.utils.parseUnits(toStringFromBN(bn, decimals), decimals) 25 | } 26 | 27 | // Formatting numbers 28 | 29 | export const _cutZeros = (strn: string): string => { 30 | return strn.replace(/0+$/gi, '').replace(/\.$/gi, ''); 31 | } 32 | 33 | export const checkNumber = (n: number | string): number | string => { 34 | if (Number(n) !== Number(n)) throw Error(`${n} is not a number`); // NaN 35 | return n 36 | } 37 | 38 | export const formatNumber = (n: number | string, decimals = 18): string => { 39 | n = checkNumber(n); 40 | const [integer, fractional] = String(n).split("."); 41 | 42 | return !fractional ? integer : integer + "." + fractional.slice(0, decimals); 43 | } 44 | 45 | export const parseUnits = (n: number | string, decimals = 18): ethers.BigNumber => { 46 | return ethers.utils.parseUnits(formatNumber(n, decimals), decimals); 47 | } 48 | 49 | // ----------------------------------------------------------------------------------------------- 50 | 51 | 52 | export const ETH_ADDRESS = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"; 53 | export const isEth = (address: string): boolean => address.toLowerCase() === ETH_ADDRESS.toLowerCase(); 54 | export const getEthIndex = (addresses: string[]): number => addresses.map((address: string) => address.toLowerCase()).indexOf(ETH_ADDRESS.toLowerCase()); 55 | 56 | 57 | export const _getAddress = (address: string): string => { 58 | address = address || crvusd.signerAddress; 59 | if (!address) throw Error("Need to connect wallet or pass address into args"); 60 | 61 | return address 62 | } 63 | 64 | // coins can be either addresses or symbols 65 | export const _getCoinAddressesNoCheck = (coins: string[]): string[] => { 66 | return coins.map((c) => c.toLowerCase()).map((c) => crvusd.constants.COINS[c] || c); 67 | } 68 | 69 | export const _getCoinAddresses = (coins: string[]): string[] => { 70 | const coinAddresses = _getCoinAddressesNoCheck(coins); 71 | const availableAddresses = Object.keys(crvusd.constants.DECIMALS); 72 | for (const coinAddr of coinAddresses) { 73 | if (!availableAddresses.includes(coinAddr)) throw Error(`Coin with address '${coinAddr}' is not available`); 74 | } 75 | 76 | return coinAddresses 77 | } 78 | 79 | export const _getCoinDecimals = (coinAddresses: string[]): number[] => { 80 | return coinAddresses.map((coinAddr) => crvusd.constants.DECIMALS[coinAddr.toLowerCase()] ?? 18); 81 | } 82 | 83 | 84 | // --- BALANCES --- 85 | 86 | export const _getBalances = async (coinAddresses: string[], address = ""): Promise => { 87 | address = _getAddress(address); 88 | const _coinAddresses = [...coinAddresses]; 89 | const ethIndex = getEthIndex(_coinAddresses); 90 | if (ethIndex !== -1) { 91 | _coinAddresses.splice(ethIndex, 1); 92 | } 93 | 94 | const contractCalls = []; 95 | for (const coinAddr of _coinAddresses) { 96 | contractCalls.push(crvusd.contracts[coinAddr].multicallContract.balanceOf(address)); 97 | } 98 | const _balances: ethers.BigNumber[] = await crvusd.multicallProvider.all(contractCalls); 99 | 100 | if (ethIndex !== -1) { 101 | const ethBalance: ethers.BigNumber = await crvusd.provider.getBalance(address); 102 | _balances.splice(ethIndex, 0, ethBalance); 103 | } 104 | 105 | return _balances 106 | } 107 | 108 | export const getBalances = async (coins: string[], address = ""): Promise => { 109 | const coinAddresses = _getCoinAddresses(coins); 110 | const decimals = _getCoinDecimals(coinAddresses); 111 | const _balances = await _getBalances(coinAddresses, address); 112 | 113 | return _balances.map((_b, i: number ) => ethers.utils.formatUnits(_b, decimals[i])); 114 | } 115 | 116 | // --- ALLOWANCE --- 117 | 118 | export const _getAllowance = async (coins: string[], address: string, spender: string): Promise => { 119 | const _coins = [...coins] 120 | const ethIndex = getEthIndex(_coins); 121 | if (ethIndex !== -1) { 122 | _coins.splice(ethIndex, 1); 123 | 124 | } 125 | 126 | let allowance: ethers.BigNumber[]; 127 | if (_coins.length === 1) { 128 | allowance = [await crvusd.contracts[_coins[0]].contract.allowance(address, spender, crvusd.constantOptions)]; 129 | } else { 130 | const contractCalls = _coins.map((coinAddr) => crvusd.contracts[coinAddr].multicallContract.allowance(address, spender)); 131 | allowance = await crvusd.multicallProvider.all(contractCalls); 132 | } 133 | 134 | 135 | if (ethIndex !== -1) { 136 | allowance.splice(ethIndex, 0, MAX_ALLOWANCE); 137 | } 138 | 139 | return allowance; 140 | } 141 | 142 | // coins can be either addresses or symbols 143 | export const getAllowance = async (coins: string[], address: string, spender: string): Promise => { 144 | const coinAddresses = _getCoinAddresses(coins); 145 | const decimals = _getCoinDecimals(coinAddresses); 146 | const _allowance = await _getAllowance(coinAddresses, address, spender); 147 | 148 | return _allowance.map((a, i) => ethers.utils.formatUnits(a, decimals[i])) 149 | } 150 | 151 | // coins can be either addresses or symbols 152 | export const hasAllowance = async (coins: string[], amounts: (number | string)[], address: string, spender: string): Promise => { 153 | const coinAddresses = _getCoinAddresses(coins); 154 | const decimals = _getCoinDecimals(coinAddresses); 155 | const _allowance = await _getAllowance(coinAddresses, address, spender); 156 | const _amounts = amounts.map((a, i) => parseUnits(a, decimals[i])); 157 | 158 | return _allowance.map((a, i) => a.gte(_amounts[i])).reduce((a, b) => a && b); 159 | } 160 | 161 | export const _ensureAllowance = async (coins: string[], amounts: ethers.BigNumber[], spender: string): Promise => { 162 | const address = crvusd.signerAddress; 163 | const allowance: ethers.BigNumber[] = await _getAllowance(coins, address, spender); 164 | 165 | const txHashes: string[] = [] 166 | for (let i = 0; i < allowance.length; i++) { 167 | if (allowance[i].lt(amounts[i])) { 168 | const contract = crvusd.contracts[coins[i]].contract; 169 | await crvusd.updateFeeData(); 170 | if (allowance[i].gt(ethers.BigNumber.from(0))) { 171 | const gasLimit = (await contract.estimateGas.approve(spender, ethers.BigNumber.from(0), crvusd.constantOptions)).mul(130).div(100); 172 | txHashes.push((await contract.approve(spender, ethers.BigNumber.from(0), { ...crvusd.options, gasLimit })).hash); 173 | } 174 | const gasLimit = (await contract.estimateGas.approve(spender, MAX_ALLOWANCE, crvusd.constantOptions)).mul(130).div(100); 175 | txHashes.push((await contract.approve(spender, MAX_ALLOWANCE, { ...crvusd.options, gasLimit })).hash); 176 | } 177 | } 178 | 179 | return txHashes; 180 | } 181 | 182 | // coins can be either addresses or symbols 183 | export const ensureAllowanceEstimateGas = async (coins: string[], amounts: (number | string)[], spender: string): Promise => { 184 | const coinAddresses = _getCoinAddresses(coins); 185 | const decimals = _getCoinDecimals(coinAddresses); 186 | const _amounts = amounts.map((a, i) => parseUnits(a, decimals[i])); 187 | const address = crvusd.signerAddress; 188 | const allowance: ethers.BigNumber[] = await _getAllowance(coinAddresses, address, spender); 189 | 190 | let gas = 0; 191 | for (let i = 0; i < allowance.length; i++) { 192 | if (allowance[i].lt(_amounts[i])) { 193 | const contract = crvusd.contracts[coinAddresses[i]].contract; 194 | if (allowance[i].gt(ethers.BigNumber.from(0))) { 195 | gas += (await contract.estimateGas.approve(spender, ethers.BigNumber.from(0), crvusd.constantOptions)).toNumber(); 196 | } 197 | gas += (await contract.estimateGas.approve(spender, MAX_ALLOWANCE, crvusd.constantOptions)).toNumber(); 198 | } 199 | } 200 | 201 | return gas 202 | } 203 | 204 | // coins can be either addresses or symbols 205 | export const ensureAllowance = async (coins: string[], amounts: (number | string)[], spender: string): Promise => { 206 | const coinAddresses = _getCoinAddresses(coins); 207 | const decimals = _getCoinDecimals(coinAddresses); 208 | const _amounts = amounts.map((a, i) => parseUnits(a, decimals[i])); 209 | 210 | return await _ensureAllowance(coinAddresses, _amounts, spender) 211 | } 212 | 213 | export const _getUsdPricesFromApi = async (): Promise> => { 214 | const network = crvusd.constants.NETWORK_NAME; 215 | const promises = [ 216 | _getPoolsFromApi(network, "main"), 217 | _getPoolsFromApi(network, "factory"), 218 | _getPoolsFromApi(network, "factory-crvusd"), 219 | ]; 220 | const allTypesExtendedPoolData = await Promise.all(promises); 221 | const priceDict: IDict = {}; 222 | 223 | for (const extendedPoolData of allTypesExtendedPoolData) { 224 | for (const pool of extendedPoolData.poolData) { 225 | const lpTokenAddress = pool.lpTokenAddress ?? pool.address; 226 | const totalSupply = pool.totalSupply / (10 ** 18); 227 | priceDict[lpTokenAddress.toLowerCase()] = pool.usdTotal && totalSupply ? pool.usdTotal / totalSupply : 0; 228 | 229 | for (const coin of pool.coins) { 230 | if (typeof coin.usdPrice === "number") priceDict[coin.address.toLowerCase()] = coin.usdPrice; 231 | } 232 | 233 | for (const coin of pool.gaugeRewards ?? []) { 234 | if (typeof coin.tokenPrice === "number") priceDict[coin.tokenAddress.toLowerCase()] = coin.tokenPrice; 235 | } 236 | } 237 | } 238 | 239 | return priceDict 240 | } 241 | 242 | const _usdRatesCache: IDict<{ rate: number, time: number }> = {} 243 | export const getUsdRate = async (coin: string): Promise => { 244 | let [coinAddress] = _getCoinAddressesNoCheck([coin]); 245 | const pricesFromApi = await _getUsdPricesFromApi() 246 | if (coinAddress.toLowerCase() in pricesFromApi) return pricesFromApi[coinAddress.toLowerCase()]; 247 | 248 | const chainName = 'ethereum'; 249 | const nativeTokenName = 'ethereum'; 250 | coinAddress = isEth(coinAddress) ? nativeTokenName : coinAddress.toLowerCase(); 251 | 252 | 253 | if ((_usdRatesCache[coinAddress]?.time || 0) + 600000 < Date.now()) { 254 | const url = coinAddress === nativeTokenName ? 255 | `https://api.coingecko.com/api/v3/simple/price?ids=${coinAddress}&vs_currencies=usd` : 256 | `https://api.coingecko.com/api/v3/simple/token_price/${chainName}?contract_addresses=${coinAddress}&vs_currencies=usd` 257 | const response = await fetch(url); 258 | const data = await response.json() as IDict<{ usd?: number }>; 259 | try { 260 | _usdRatesCache[coinAddress] = {'rate': data[coinAddress].usd ?? 0, 'time': Date.now()}; 261 | } catch (err) { // TODO pay attention! 262 | _usdRatesCache[coinAddress] = {'rate': 0, 'time': Date.now()}; 263 | } 264 | } 265 | 266 | return _usdRatesCache[coinAddress]['rate'] 267 | } 268 | 269 | export const totalSupply = async (): Promise<{ total: string, minted: string, pegKeepersDebt: string }> => { 270 | const calls = []; 271 | for (const llammaId of crvusd.getLlammaList()) { 272 | const controllerAddress = crvusd.constants.LLAMMAS[llammaId].controller_address; 273 | const controllerContract = crvusd.contracts[controllerAddress].multicallContract; 274 | calls.push(controllerContract.minted(), controllerContract.redeemed()); 275 | } 276 | for (const pegKeeper of crvusd.constants.PEG_KEEPERS) { 277 | calls.push(crvusd.contracts[pegKeeper].multicallContract.debt()); 278 | } 279 | const res: ethers.BigNumber[] = await crvusd.multicallProvider.all(calls); 280 | 281 | let mintedBN = BN(0); 282 | for (let i = 0; i < crvusd.getLlammaList().length; i++) { 283 | const [_minted, _redeemed] = res.splice(0, 2); 284 | mintedBN = toBN(_minted).minus(toBN(_redeemed)).plus(mintedBN); 285 | } 286 | let pegKeepersBN = BN(0); 287 | for (const _pegKeeperDebt of res) { 288 | pegKeepersBN = pegKeepersBN.plus(toBN(_pegKeeperDebt)); 289 | } 290 | 291 | return { total: mintedBN.plus(pegKeepersBN).toString(), minted: mintedBN.toString(), pegKeepersDebt: pegKeepersBN.toString() }; 292 | } 293 | 294 | export const getLsdApy = memoize(async(name: 'wstETH' | 'sfrxETH'): Promise<{ 295 | apy: number, 296 | baseApy: number, 297 | apyMean30d: number, 298 | }> => { 299 | const response = await fetch('https://yields.llama.fi/pools'); 300 | const {data} = await response.json() as { data: { chain: string, project: string, symbol: string, apy: number, apyBase: number, apyMean30d: number }[] }; 301 | 302 | const params = { 303 | 'wstETH': { 304 | project: 'lido', 305 | symbol: 'STETH', 306 | }, 307 | 'sfrxETH': { 308 | project: 'frax-ether', 309 | symbol: 'SFRXETH', 310 | }, 311 | } 312 | 313 | const result = data.find(({ 314 | chain, 315 | project, 316 | symbol, 317 | }) => ( 318 | chain === 'Ethereum' && 319 | project === params[name].project && 320 | symbol === params[name].symbol 321 | )); 322 | 323 | if(result) { 324 | return { 325 | apy: result.apy, 326 | baseApy: result.apyBase, 327 | apyMean30d: result.apyMean30d, 328 | }; 329 | } 330 | 331 | throw new Error('Pool not found') 332 | }, 333 | { 334 | promise: true, 335 | maxAge: 60 * 1000, // 1m 336 | }); -------------------------------------------------------------------------------- /test/general.test.ts: -------------------------------------------------------------------------------- 1 | import { assert } from "chai"; 2 | import { crvusd } from "../src/crvusd"; 3 | import { getLlamma, LlammaTemplate } from "../src/llammas"; 4 | import { BN } from "../src/utils"; 5 | 6 | 7 | const LLAMMAS = ['sfrxeth', 'wsteth', 'wbtc', 'eth', 'sfrxeth2', 'tbtc']; 8 | 9 | const generalTest = (id: string) => { 10 | describe(`${id} llamma general test`, function () { 11 | let llamma: LlammaTemplate; 12 | 13 | before(async function () { 14 | llamma = getLlamma(id); 15 | }); 16 | 17 | it('Create loan', async function () { 18 | const initialBalances = await llamma.wallet.balances(); 19 | const initialState = await llamma.userState(); 20 | 21 | assert.equal(Number(initialState.collateral), 0); 22 | assert.equal(Number(initialState.stablecoin), 0); 23 | assert.equal(Number(initialState.debt), 0); 24 | assert.isAbove(Number(initialBalances.collateral), 0); 25 | 26 | const collateralAmount = 0.5; 27 | const N = 5; 28 | const maxRecv = await llamma.createLoanMaxRecv(collateralAmount, N); 29 | const debtAmount = (Number(maxRecv) / 2).toFixed(18); 30 | const createLoanPrices = await llamma.createLoanPrices(collateralAmount, debtAmount, N); 31 | const createLoanFullHealth = await llamma.createLoanHealth(collateralAmount, debtAmount, N); 32 | const createLoanHealth = await llamma.createLoanHealth(collateralAmount, debtAmount, N, false); 33 | 34 | await llamma.createLoan(collateralAmount, debtAmount, N); 35 | 36 | const balances = await llamma.wallet.balances(); 37 | const state = await llamma.userState(); 38 | const userPrices = await llamma.userPrices(); 39 | const fullHealth = await llamma.userHealth(); 40 | const health = await llamma.userHealth(false); 41 | 42 | assert.approximately(Number(createLoanPrices[0]), Number(userPrices[0]), 1e-2, 'price 0'); 43 | assert.approximately(Number(createLoanPrices[1]), Number(userPrices[1]), 1e-2, 'price 1'); 44 | assert.approximately(Number(createLoanFullHealth), Number(fullHealth), 0.1, 'full health'); 45 | assert.approximately(Number(createLoanHealth), Number(health), 1e-4, 'health'); 46 | assert.equal(Number(balances.collateral), Number(initialBalances.collateral) - Number(collateralAmount), 'wallet collateral'); 47 | assert.approximately(Number(balances.stablecoin), BN(initialBalances.stablecoin).plus(Number(debtAmount)).toNumber(), 1e-12, 'wallet stablecoin'); 48 | assert.equal(Number(state.collateral), Number(collateralAmount), 'state collateral'); 49 | assert.equal(Number(state.debt), Number(debtAmount), 'state debt'); 50 | }); 51 | 52 | it('Borrow more', async function () { 53 | const initialBalances = await llamma.wallet.balances(); 54 | const initialState = await llamma.userState(); 55 | const loanExists = await llamma.loanExists(); 56 | 57 | assert.isTrue(loanExists); 58 | assert.isAbove(Number(initialBalances.collateral), 0); 59 | 60 | const collateralAmount = 0.5; 61 | const maxRecv = await llamma.borrowMoreMaxRecv(collateralAmount); 62 | const debtAmount = (Number(maxRecv) / 2).toFixed(18); 63 | const borrowMorePrices = await llamma.borrowMorePrices(collateralAmount, debtAmount); 64 | const borrowMoreFullHealth = await llamma.borrowMoreHealth(collateralAmount, debtAmount); 65 | const borrowMoreHealth = await llamma.borrowMoreHealth(collateralAmount, debtAmount, false); 66 | 67 | await llamma.borrowMore(collateralAmount, debtAmount); 68 | 69 | const balances = await llamma.wallet.balances(); 70 | const state = await llamma.userState(); 71 | const userPrices = await llamma.userPrices(); 72 | const fullHealth = await llamma.userHealth(); 73 | const health = await llamma.userHealth(false); 74 | 75 | assert.approximately(Number(borrowMorePrices[0]), Number(userPrices[0]), 1e-2, 'price 0'); 76 | assert.approximately(Number(borrowMorePrices[1]), Number(userPrices[1]), 1e-2, 'price 1'); 77 | assert.approximately(Number(borrowMoreFullHealth), Number(fullHealth), 1e-2, 'full health'); 78 | assert.approximately(Number(borrowMoreHealth), Number(health), 1e-4, 'health'); 79 | assert.equal(Number(balances.collateral), Number(initialBalances.collateral) - Number(collateralAmount), 'wallet collateral'); 80 | assert.equal(balances.stablecoin, BN(initialBalances.stablecoin).plus(BN(debtAmount)).toString(), 'wallet stablecoin'); 81 | assert.equal(Number(state.collateral), Number(initialState.collateral) + Number(collateralAmount), 'state collateral'); 82 | assert.approximately(Number(state.debt), Number(initialState.debt) + Number(debtAmount), 1e-4, 'state debt'); 83 | }); 84 | 85 | it('Add collateral', async function () { 86 | const initialBalances = await llamma.wallet.balances(); 87 | const initialState = await llamma.userState(); 88 | const loanExists = await llamma.loanExists(); 89 | 90 | assert.isTrue(loanExists); 91 | assert.isAbove(Number(initialBalances.collateral), 0); 92 | 93 | const collateralAmount = 1; 94 | const addCollateralPrices = await llamma.addCollateralPrices(collateralAmount); 95 | const addCollateralFullHealth = await llamma.addCollateralHealth(collateralAmount); 96 | const addCollateralHealth = await llamma.addCollateralHealth(collateralAmount, false); 97 | 98 | await llamma.addCollateral(collateralAmount); 99 | 100 | const balances = await llamma.wallet.balances(); 101 | const state = await llamma.userState(); 102 | const userPrices = await llamma.userPrices(); 103 | const fullHealth = await llamma.userHealth(); 104 | const health = await llamma.userHealth(false); 105 | 106 | assert.approximately(Number(addCollateralPrices[0]), Number(userPrices[0]), 1e-2, 'price 0'); 107 | assert.approximately(Number(addCollateralPrices[1]), Number(userPrices[1]), 1e-2, 'price 1'); 108 | assert.approximately(Number(addCollateralFullHealth), Number(fullHealth), 1e-2, 'full health'); 109 | assert.approximately(Number(addCollateralHealth), Number(health), 1e-4, 'health'); 110 | assert.equal(Number(balances.collateral), Number(initialBalances.collateral) - Number(collateralAmount), 'wallet collateral'); 111 | assert.equal(Number(balances.stablecoin), Number(initialBalances.stablecoin), 'wallet stablecoin'); 112 | assert.equal(Number(state.collateral), Number(initialState.collateral) + Number(collateralAmount), 'state collateral'); 113 | assert.approximately(Number(initialState.debt), Number(state.debt), 1e-4, 'state debt'); 114 | }); 115 | 116 | it('Remove collateral', async function () { 117 | const initialBalances = await llamma.wallet.balances(); 118 | const initialState = await llamma.userState(); 119 | const loanExists = await llamma.loanExists(); 120 | 121 | assert.isTrue(loanExists); 122 | assert.isAbove(Number(initialState.collateral), 0); 123 | 124 | const maxRemovable = await llamma.maxRemovable(); 125 | const collateralAmount = (Number(maxRemovable) / 2).toFixed(llamma.collateralDecimals); 126 | const removeCollateralPrices = await llamma.removeCollateralPrices(collateralAmount); 127 | const removeCollateralFullHealth = await llamma.removeCollateralHealth(collateralAmount); 128 | const removeCollateralHealth = await llamma.removeCollateralHealth(collateralAmount, false); 129 | 130 | await llamma.removeCollateral(collateralAmount); 131 | 132 | const balances = await llamma.wallet.balances(); 133 | const state = await llamma.userState(); 134 | const userPrices = await llamma.userPrices(); 135 | const fullHealth = await llamma.userHealth(); 136 | const health = await llamma.userHealth(false); 137 | 138 | assert.approximately(Number(removeCollateralPrices[0]), Number(userPrices[0]), 1e-2, 'price 0'); 139 | assert.approximately(Number(removeCollateralPrices[1]), Number(userPrices[1]), 1e-2, 'price 1'); 140 | assert.approximately(Number(removeCollateralFullHealth), Number(fullHealth), 1e-2, 'full health'); 141 | assert.approximately(Number(removeCollateralHealth), Number(health), 1e-4, 'health'); 142 | assert.equal(Number(balances.collateral), Number(initialBalances.collateral) + Number(collateralAmount), 'wallet collateral'); 143 | assert.equal(Number(balances.stablecoin), Number(initialBalances.stablecoin), 'wallet stablecoin'); 144 | assert.equal(state.collateral, BN(initialState.collateral).minus(BN(collateralAmount)).toString(), 'state collateral'); 145 | assert.approximately(Number(initialState.debt), Number(state.debt), 1e-4, 'state debt'); 146 | }); 147 | 148 | it('Partial repay', async function () { 149 | const initialBalances = await llamma.wallet.balances(); 150 | const initialState = await llamma.userState(); 151 | const loanExists = await llamma.loanExists(); 152 | const debtAmount = (Number(initialState.debt) / 4).toFixed(18); 153 | 154 | assert.isTrue(loanExists); 155 | assert.isAtLeast(Number(initialBalances.stablecoin), Number(debtAmount)); 156 | 157 | const repayPrices = await llamma.repayPrices(debtAmount); 158 | const repayFullHealth = await llamma.repayHealth(debtAmount); 159 | const repayHealth = await llamma.repayHealth(debtAmount, false); 160 | 161 | await llamma.repay(debtAmount); 162 | 163 | const balances = await llamma.wallet.balances(); 164 | const state = await llamma.userState(); 165 | const userPrices = await llamma.userPrices(); 166 | const fullHealth = await llamma.userHealth(); 167 | const health = await llamma.userHealth(false); 168 | 169 | assert.approximately(Number(repayPrices[0]), Number(userPrices[0]), 1e-2, 'price 0'); 170 | assert.approximately(Number(repayPrices[1]), Number(userPrices[1]), 1e-2, 'price 1'); 171 | assert.approximately(Number(repayFullHealth), Number(fullHealth), 1e-2, 'full health'); 172 | assert.approximately(Number(repayHealth), Number(health), 1e-4, 'health'); 173 | assert.equal(Number(balances.collateral), Number(initialBalances.collateral), 'wallet collateral'); 174 | assert.equal(balances.stablecoin, BN(initialBalances.stablecoin).minus(BN(debtAmount)).toString(), 'wallet stablecoin'); 175 | assert.equal(Number(state.collateral), Number(initialState.collateral), 'state collateral'); 176 | assert.equal(Number(state.stablecoin), Number(initialState.stablecoin), 'state stablecoin'); 177 | assert.approximately(Number(state.debt), Number(initialState.debt) - Number(debtAmount), 1e-4, 'state debt'); 178 | }); 179 | 180 | it('Full repay', async function () { 181 | const initialBalances = await llamma.wallet.balances(); 182 | const initialState = await llamma.userState(); 183 | const loanExists = await llamma.loanExists(); 184 | 185 | assert.isTrue(loanExists); 186 | assert.isAtLeast(Number(initialBalances.stablecoin), Number(initialState.debt)); 187 | 188 | await llamma.fullRepay(); 189 | 190 | const balances = await llamma.wallet.balances(); 191 | const state = await llamma.userState(); 192 | 193 | 194 | assert.approximately(Number(balances.collateral), Number(initialBalances.collateral) + Number(initialState.collateral), 10**(-llamma.collateralDecimals), 'wallet collateral'); 195 | assert.approximately(Number(balances.stablecoin), Number(initialBalances.stablecoin) - Number(initialState.debt), 1e-3, 'wallet stablecoin'); 196 | assert.equal(Number(state.collateral), 0, 'state collateral'); 197 | assert.equal(Number(state.stablecoin), 0, 'state stablecoin'); 198 | assert.equal(Number(state.debt), 0, 'state debt'); 199 | }); 200 | 201 | it('Leverage', async function () { 202 | const initialBalances = await llamma.wallet.balances(); 203 | const initialState = await llamma.userState(); 204 | const loanExists = await llamma.loanExists(); 205 | 206 | assert.isFalse(loanExists); 207 | assert.isAbove(Number(initialBalances.collateral), 0); 208 | 209 | const collateralAmount = 0.5; 210 | const N = 10; 211 | const maxRecv = await llamma.leverage.createLoanMaxRecv(collateralAmount, N); 212 | const debtAmount = (Number(maxRecv.maxBorrowable) / 2).toFixed(18); 213 | const createLoanPrices = await llamma.leverage.createLoanPrices(collateralAmount, debtAmount, N); 214 | const createLoanFullHealth = await llamma.leverage.createLoanHealth(collateralAmount, debtAmount, N); 215 | const createLoanHealth = await llamma.leverage.createLoanHealth(collateralAmount, debtAmount, N, false); 216 | const { collateral } = await llamma.leverage.createLoanCollateral(collateralAmount, debtAmount); 217 | 218 | await llamma.leverage.createLoan(collateralAmount, debtAmount, N); 219 | 220 | const balances = await llamma.wallet.balances(); 221 | const state = await llamma.userState(); 222 | const userPrices = await llamma.userPrices(); 223 | const fullHealth = await llamma.userHealth(); 224 | const health = await llamma.userHealth(false); 225 | 226 | assert.approximately(Number(createLoanPrices[0]), Number(userPrices[0]), 1e-2, 'price 0'); 227 | assert.approximately(Number(createLoanPrices[1]), Number(userPrices[1]), 1e-2, 'price 1'); 228 | assert.approximately(Number(createLoanFullHealth), Number(fullHealth), 0.1, 'full health'); 229 | assert.approximately(Number(createLoanHealth), Number(health), 1e-3, 'health'); 230 | assert.equal(Number(balances.collateral), Number(initialBalances.collateral) - Number(collateralAmount), 'wallet collateral'); 231 | assert.equal(Number(balances.stablecoin), Number(initialBalances.stablecoin), 'wallet stablecoin'); 232 | assert.approximately(Number(state.collateral), Number(collateral), 1e-6, 'state collateral'); 233 | assert.equal(Number(state.debt), Number(debtAmount), 'state debt'); 234 | }); 235 | 236 | it('Deleverage', async function () { 237 | const initialBalances = await llamma.wallet.balances(); 238 | const initialState = await llamma.userState(); 239 | const loanExists = await llamma.loanExists(); 240 | const collateralAmount = Number(initialState.collateral) / 10; 241 | const deleverageIsAvailable = await llamma.deleverage.isAvailable(collateralAmount); 242 | const isFullRepayment = await llamma.deleverage.isFullRepayment(collateralAmount); 243 | 244 | assert.isTrue(loanExists); 245 | assert.isTrue(deleverageIsAvailable); 246 | assert.isFalse(isFullRepayment); 247 | 248 | const deleverageBands = await llamma.deleverage.repayBands(collateralAmount); 249 | const deleveragePrices = await llamma.deleverage.repayPrices(collateralAmount); 250 | const deleverageFullHealth = await llamma.deleverage.repayHealth(collateralAmount); 251 | const deleverageHealth = await llamma.deleverage.repayHealth(collateralAmount, false); 252 | const { stablecoins } = await llamma.deleverage.repayStablecoins(collateralAmount); 253 | 254 | await llamma.deleverage.repay(collateralAmount); 255 | 256 | const balances = await llamma.wallet.balances(); 257 | const state = await llamma.userState(); 258 | const userBands = await llamma.userBands(); 259 | const userPrices = await llamma.userPrices(); 260 | const fullHealth = await llamma.userHealth(); 261 | const health = await llamma.userHealth(false); 262 | 263 | 264 | assert.equal(deleverageBands[0], userBands[0], 'band 0'); 265 | assert.equal(deleverageBands[1], userBands[1], 'band 1'); 266 | assert.approximately(Number(deleveragePrices[0]), Number(userPrices[0]), 0.1, 'price 0'); 267 | assert.approximately(Number(deleveragePrices[1]), Number(userPrices[1]), 0.1, 'price 1'); 268 | assert.approximately(Number(deleverageFullHealth), Number(fullHealth), 0.1, 'full health'); 269 | assert.approximately(Number(deleverageHealth), Number(health), 1e-4, 'health'); 270 | assert.equal(balances.collateral, initialBalances.collateral, 'wallet collateral'); 271 | assert.equal(balances.stablecoin, initialBalances.stablecoin, 'wallet stablecoin'); 272 | assert.approximately(Number(state.collateral), Number(initialState.collateral) - collateralAmount, 1e-5, 'state collateral'); 273 | assert.approximately(Number(state.debt), Number(initialState.debt) - Number(stablecoins), 1e-2, 'state debt'); 274 | }); 275 | 276 | it('Full deleverage', async function () { 277 | const initialBalances = await llamma.wallet.balances(); 278 | const initialState = await llamma.userState(); 279 | const initialLoanExists = await llamma.loanExists(); 280 | const collateralAmount = Number(initialState.collateral) * 0.95; 281 | const deleverageIsAvailable = await llamma.deleverage.isAvailable(collateralAmount); 282 | const isFullRepayment = await llamma.deleverage.isFullRepayment(collateralAmount); 283 | 284 | assert.isTrue(initialLoanExists); 285 | assert.isTrue(deleverageIsAvailable); 286 | assert.isTrue(isFullRepayment); 287 | 288 | const { stablecoins } = await llamma.deleverage.repayStablecoins(collateralAmount); 289 | 290 | await llamma.deleverage.repay(collateralAmount); 291 | 292 | const balances = await llamma.wallet.balances(); 293 | const loanExists = await llamma.loanExists(); 294 | 295 | 296 | if (llamma.id !== "eth") { 297 | assert.approximately(Number(balances.collateral), Number(initialBalances.collateral) + Number(initialState.collateral) - collateralAmount, 298 | 1e-5, 'wallet collateral'); 299 | } 300 | assert.approximately(Number(balances.stablecoin), Number(initialBalances.stablecoin) + Number(stablecoins) - Number(initialState.debt), 301 | 1e-3, 'wallet stablecoin'); 302 | assert.isFalse(loanExists, 'loan exists'); 303 | }); 304 | }) 305 | } 306 | 307 | describe('General test', async function () { 308 | this.timeout(120000); 309 | 310 | before(async function () { 311 | await crvusd.init('JsonRpc', {},{ gasPrice: 0, maxFeePerGas: 0, maxPriorityFeePerGas: 0 }); 312 | }); 313 | 314 | for (const llammaId of LLAMMAS) { 315 | generalTest(llammaId); 316 | } 317 | }) 318 | -------------------------------------------------------------------------------- /test/readme.test.ts: -------------------------------------------------------------------------------- 1 | import crvusd from "../src"; 2 | 3 | const generalMethodsTest = async () => { 4 | await crvusd.init('JsonRpc', {}); 5 | 6 | const balances1 = await crvusd.getBalances(['crvusd', 'sfrxeth']); 7 | // OR const balances1 = await crvusd.getBalances(['0xf939E0A03FB07F59A73314E73794Be0E57ac1b4E', '0xac3E018457B222d93114458476f3E3416Abbe38F']); 8 | console.log(balances1); 9 | // [ '0.0', '1.0' ] 10 | 11 | // You can specify address 12 | const balances2 = await crvusd.getBalances(['crvusd', 'sfrxeth'], "0x0063046686E46Dc6F15918b61AE2B121458534a5"); 13 | // OR const balances2 = await crvusd.getBalances(['0xf939E0A03FB07F59A73314E73794Be0E57ac1b4E', '0xac3E018457B222d93114458476f3E3416Abbe38F'], '0x0063046686E46Dc6F15918b61AE2B121458534a5'); 14 | console.log(balances2); 15 | // [ '0.0', '0.0' ] 16 | 17 | const spender = "0x136e783846ef68C8Bd00a3369F787dF8d683a696" // sfrxeth llamma address 18 | 19 | await crvusd.getAllowance(["crvusd", "sfrxeth"], crvusd.signerAddress, spender); 20 | // [ '0.0', '0.0' ] 21 | await crvusd.hasAllowance(["crvusd", "sfrxeth"], ['1000', '1000'], crvusd.signerAddress, spender); 22 | // false 23 | await crvusd.ensureAllowance(["crvusd", "sfrxeth"], ['1000', '1000'], spender); 24 | // [ 25 | // '0xb0cada2a2983dc0ed85a26916d32b9caefe45fecde47640bd7d0e214ff22aed3', 26 | // '0x00ea7d827b3ad50ce933e96c579810cd7e70d66a034a86ec4e1e10005634d041' 27 | // ] 28 | 29 | await crvusd.getUsdRate('0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee'); 30 | // 1257.43 31 | 32 | console.log(await crvusd.totalSupply()); 33 | } 34 | 35 | const llammaFieldsTest = async () => { 36 | await crvusd.init('JsonRpc', {}); 37 | 38 | const llamma = crvusd.getLlamma('sfrxeth'); 39 | 40 | console.log(llamma.id); 41 | console.log(llamma.address); 42 | console.log(llamma.controller); 43 | console.log(llamma.monetaryPolicy); 44 | console.log(llamma.collateral); 45 | console.log(llamma.collateralSymbol); 46 | console.log(llamma.collateralDecimals); 47 | console.log(llamma.coins); 48 | console.log(llamma.coinAddresses); 49 | console.log(llamma.coinDecimals); 50 | console.log(llamma.minBands); 51 | console.log(llamma.maxBands); 52 | console.log(llamma.defaultBands); 53 | console.log(llamma.A); 54 | console.log(llamma.tickSpace); 55 | } 56 | 57 | const walletBalancesTest = async () => { 58 | await crvusd.init('JsonRpc', {}); 59 | 60 | const llamma = crvusd.getLlamma('sfrxeth'); 61 | 62 | // 1. Current address (signer) balances 63 | 64 | console.log(await llamma.wallet.balances()); 65 | // { stablecoin: '0.0', collateral: '1.0' } 66 | 67 | // 2. You can specify the address 68 | 69 | console.log(await llamma.wallet.balances("0x0063046686E46Dc6F15918b61AE2B121458534a5")); 70 | // { stablecoin: '0.0', collateral: '0.0' } 71 | } 72 | 73 | const statsTest = async () => { 74 | await crvusd.init('JsonRpc', {}); 75 | 76 | const llamma = crvusd.getLlamma('sfrxeth'); 77 | 78 | console.log(await llamma.stats.parameters()); 79 | console.log(await llamma.stats.balances()); 80 | console.log(await llamma.stats.maxMinBands()); 81 | console.log(await llamma.stats.activeBand()); 82 | const liquidatingBand = await llamma.stats.liquidatingBand(); 83 | console.log(liquidatingBand); 84 | console.log(await llamma.stats.bandBalances(liquidatingBand ?? 0)); 85 | console.log(await llamma.stats.bandsBalances()); 86 | console.log(await llamma.stats.totalSupply()); 87 | console.log(await llamma.stats.totalDebt()); 88 | console.log(await llamma.stats.totalStablecoin()); 89 | console.log(await llamma.stats.totalCollateral()); 90 | console.log(await llamma.stats.capAndAvailable()); 91 | } 92 | 93 | const generalTest = async () => { 94 | await crvusd.init('JsonRpc', {}); 95 | 96 | console.log(crvusd.getLlammaList()); 97 | 98 | const llamma = crvusd.getLlamma('sfrxeth'); 99 | 100 | 101 | console.log("\n--- CREATE LOAN ---\n"); 102 | 103 | console.log(await llamma.oraclePrice()); 104 | console.log(await llamma.price()); 105 | console.log(await llamma.basePrice()); 106 | console.log(await llamma.wallet.balances()); 107 | console.log(await llamma.createLoanMaxRecv(1, 5)); 108 | console.log(await llamma.createLoanBands(1, 1000, 5)); 109 | console.log(await llamma.createLoanPrices(1, 1000, 5)); 110 | console.log(await llamma.createLoanHealth(1, 1000, 5)); // FULL 111 | console.log(await llamma.createLoanHealth(1, 1000, 5, false)); // NOT FULL 112 | 113 | console.log(await llamma.createLoanIsApproved(1)); 114 | // false 115 | console.log(await llamma.createLoanApprove(1)); 116 | // [ 117 | // '0xc111e471715ae6f5437e12d3b94868a5b6542cd7304efca18b5782d315760ae5' 118 | // ] 119 | console.log(await llamma.createLoan(1, 1000, 5)); 120 | 121 | console.log(await llamma.userDebt()); // OR await llamma.userDebt(address); 122 | console.log(await llamma.loanExists()); 123 | console.log(await llamma.userHealth()); // FULL 124 | console.log(await llamma.userHealth(false)); // NOT FULL 125 | console.log(await llamma.userRange()); 126 | console.log(await llamma.userBands()); 127 | console.log(await llamma.userPrices()); 128 | console.log(await llamma.userState()); 129 | console.log(await llamma.userBandsBalances()); 130 | 131 | console.log("\n--- BORROW MORE ---\n"); 132 | 133 | console.log(await llamma.borrowMoreMaxRecv(0.5)); 134 | console.log(await llamma.borrowMoreBands(0.5, 500)); 135 | console.log(await llamma.borrowMorePrices(0.5, 500)); 136 | console.log(await llamma.borrowMoreHealth(0.5, 500)); // FULL 137 | console.log(await llamma.borrowMoreHealth(0.5, 500, false)); // NOT FULL 138 | 139 | console.log(await llamma.borrowMoreIsApproved(0.5)); 140 | console.log(await llamma.borrowMoreApprove(0.5)); 141 | 142 | console.log(await llamma.borrowMore(0.5, 500)); 143 | 144 | console.log(await llamma.userHealth()); // FULL 145 | console.log(await llamma.userHealth(false)); // NOT FULL 146 | console.log(await llamma.userBands()); 147 | console.log(await llamma.userPrices()); 148 | console.log(await llamma.userState()); 149 | 150 | console.log("\n--- ADD COLLATERAL ---\n"); 151 | 152 | console.log(await llamma.addCollateralBands(0.2)); 153 | console.log(await llamma.addCollateralPrices(0.2)); 154 | console.log(await llamma.addCollateralHealth(0.2)); // FULL 155 | console.log(await llamma.addCollateralHealth(0.2, false)); // NOT FULL 156 | 157 | console.log(await llamma.addCollateralIsApproved(0.2)); 158 | console.log(await llamma.addCollateralApprove(0.2)); 159 | 160 | console.log(await llamma.addCollateral(0.2)); // OR await llamma.addCollateral(0.2, forAddress); 161 | 162 | console.log(await llamma.userHealth()); // FULL 163 | console.log(await llamma.userHealth(false)); // NOT FULL 164 | console.log(await llamma.userBands()); 165 | console.log(await llamma.userPrices()); 166 | console.log(await llamma.userState()); 167 | 168 | console.log("\n--- REMOVE COLLATERAL ---\n") 169 | 170 | console.log(await llamma.maxRemovable()); 171 | console.log(await llamma.removeCollateralBands(0.1)); 172 | console.log(await llamma.removeCollateralPrices(0.1)); 173 | console.log(await llamma.removeCollateralHealth(0.1)); // FULL 174 | console.log(await llamma.removeCollateralHealth(0.1, false)); // NOT FULL 175 | 176 | console.log(await llamma.removeCollateral(0.1)); 177 | 178 | console.log(await llamma.userHealth()); // FULL 179 | console.log(await llamma.userHealth(false)); // NOT FULL 180 | console.log(await llamma.userBands()); 181 | console.log(await llamma.userPrices()); 182 | console.log(await llamma.userState()); 183 | 184 | console.log("\n--- REPAY ---\n"); 185 | 186 | console.log(await llamma.wallet.balances()); 187 | 188 | console.log(await llamma.repayBands(1000)); 189 | console.log(await llamma.repayPrices(1000)); 190 | console.log(await llamma.repayHealth(1000)); // FULL 191 | console.log(await llamma.repayHealth(1000, false)); // NOT FULL 192 | 193 | console.log(await llamma.repayIsApproved(1000)); 194 | console.log(await llamma.repayApprove(1000)); 195 | 196 | console.log(await llamma.repay(1000)); 197 | 198 | console.log(await llamma.userDebt()); 199 | console.log(await llamma.loanExists()); 200 | console.log(await llamma.userHealth()); // FULL 201 | console.log(await llamma.userHealth(false)); // NOT FULL 202 | console.log(await llamma.userBands()); 203 | console.log(await llamma.userPrices()); 204 | console.log(await llamma.userState()); 205 | 206 | console.log("\n--- FULL REPAY ---\n"); 207 | 208 | console.log(await llamma.fullRepayIsApproved()); 209 | console.log(await llamma.fullRepayApprove()); 210 | 211 | console.log(await llamma.fullRepay()); 212 | 213 | console.log(await llamma.loanExists()); 214 | console.log(await llamma.userState()); 215 | } 216 | 217 | const createLoanAllRangesTest = async () => { 218 | await crvusd.init('JsonRpc', {}); 219 | 220 | const llamma = crvusd.getLlamma('sfrxeth'); 221 | 222 | console.log(await llamma.createLoanMaxRecvAllRanges(1)); 223 | console.log(await llamma.createLoanBandsAllRanges(1, 1600)); 224 | console.log(await llamma.createLoanPricesAllRanges(1, 1600)); 225 | } 226 | 227 | const swapTest = async () => { 228 | await crvusd.init('JsonRpc', {}); 229 | 230 | const llamma = crvusd.getLlamma('sfrxeth'); 231 | 232 | console.log(await llamma.wallet.balances()); 233 | 234 | console.log(await llamma.maxSwappable(0, 1)); 235 | console.log(await llamma.swapExpected(0, 1, 100)); 236 | console.log(await llamma.swapRequired(0, 1, 100)); 237 | console.log(await llamma.swapPriceImpact(0, 1, 100)); 238 | console.log(await llamma.swapIsApproved(0, 100)); 239 | console.log(await llamma.swapApprove(0, 100)); 240 | console.log(await llamma.swap(0, 1, 100, 0.1)); 241 | 242 | console.log(await llamma.wallet.balances()); 243 | } 244 | 245 | const selfLiquidationTest = async () => { 246 | await crvusd.init('JsonRpc', {}); 247 | 248 | const llamma = crvusd.getLlamma('sfrxeth'); 249 | 250 | const maxDebt = await llamma.createLoanMaxRecv(0.3, 10); 251 | await llamma.createLoan(0.3, maxDebt, 10); 252 | await llamma.swap(0, 1, Number(maxDebt) * 10, 0.05); 253 | 254 | console.log(await llamma.wallet.balances()); 255 | console.log(await llamma.userState()); 256 | 257 | console.log(await llamma.tokensToLiquidate()); 258 | console.log(await llamma.selfLiquidateIsApproved()); 259 | console.log(await llamma.selfLiquidateApprove()); 260 | console.log(await llamma.selfLiquidate(0.1)); 261 | 262 | console.log(await llamma.wallet.balances()); 263 | console.log(await llamma.userState()); 264 | } 265 | 266 | const userLossTest = async () => { 267 | await crvusd.init('JsonRpc', {}); 268 | 269 | const llamma = crvusd.getLlamma('sfrxeth'); 270 | 271 | console.log(await llamma.userLoss("0x0063046686E46Dc6F15918b61AE2B121458534a5")); 272 | // { 273 | // deposited_collateral: '929.933909709140155529', 274 | // current_collateral_estimation: '883.035865972092328038', 275 | // loss: '46.898043737047827491', 276 | // loss_pct: '5.043158793049750311' 277 | // } 278 | } 279 | 280 | const leverageTest = async () => { 281 | await crvusd.init('JsonRpc', {}); 282 | 283 | const llamma = crvusd.getLlamma('wsteth'); 284 | 285 | console.log(await llamma.leverage.createLoanMaxRecv(1, 5)); 286 | const { collateral, leverage, routeIdx } = await llamma.leverage.createLoanCollateral(1, 1000); 287 | console.log({ collateral, leverage, routeIdx }); 288 | console.log(await llamma.leverage.getRouteName(routeIdx)); 289 | console.log(await llamma.leverage.getMaxRange(1, 1000)); 290 | console.log(await llamma.leverage.createLoanBands(1, 1000, 5)); 291 | console.log(await llamma.leverage.createLoanPrices(1, 1000, 5)); 292 | console.log(await llamma.leverage.createLoanHealth(1, 1000, 5)); // FULL 293 | console.log(await llamma.leverage.createLoanHealth(1, 1000, 5, false)); // NOT FULL 294 | console.log(await llamma.leverage.priceImpact(1, 1000)); 295 | 296 | console.log(await llamma.leverage.createLoanIsApproved(1)); 297 | // false 298 | console.log(await llamma.leverage.createLoanApprove(1)); 299 | // [ 300 | // '0xa2cb9316c58a4e383a0fcc9d9c60c3742c46a901115b23d2c84ced6b61c5be84' 301 | // ] 302 | console.log(await llamma.leverage.createLoan(1, 1000, 5, 0.5)); 303 | 304 | console.log(await llamma.userDebt()); // OR await llamma.userDebt(address); 305 | console.log(await llamma.loanExists()); 306 | console.log(await llamma.userHealth()); // FULL 307 | console.log(await llamma.userHealth(false)); // NOT FULL 308 | console.log(await llamma.userRange()); 309 | console.log(await llamma.userBands()); 310 | console.log(await llamma.userPrices()); 311 | console.log(await llamma.userState()); 312 | console.log(await llamma.userBandsBalances()); 313 | } 314 | 315 | const leverageAllRangesTest = async () => { 316 | await crvusd.init('JsonRpc', {}); 317 | 318 | const llamma = crvusd.getLlamma('wsteth'); 319 | 320 | console.log(await llamma.leverage.createLoanMaxRecvAllRanges(1)); 321 | console.log(await llamma.leverage.createLoanBandsAllRanges(1, 14000)); 322 | console.log(await llamma.leverage.createLoanPricesAllRanges(1, 14000)); 323 | } 324 | 325 | const deleverageTest = async () => { 326 | await crvusd.init('JsonRpc', {}); 327 | 328 | const llamma = crvusd.getLlamma('wsteth'); 329 | 330 | console.log(await llamma.userState()); 331 | const { stablecoins, routeIdx } = await llamma.deleverage.repayStablecoins(0.5); 332 | console.log({ stablecoins, routeIdx }); 333 | console.log(await llamma.deleverage.getRouteName(routeIdx)); 334 | console.log(await llamma.deleverage.repayBands(0.5)); 335 | console.log(await llamma.deleverage.repayPrices(0.5)); 336 | console.log(await llamma.deleverage.repayHealth(0.5)); // FULL 337 | console.log(await llamma.deleverage.repayHealth(0.5, false)); // NOT FULL 338 | console.log(await llamma.deleverage.priceImpact(0.5)); 339 | console.log(await llamma.deleverage.isAvailable(0.5)); 340 | console.log(await llamma.deleverage.isFullRepayment(0.5)); 341 | 342 | console.log(await llamma.deleverage.repay(0.5, 0.3)); 343 | 344 | console.log(await llamma.userState()); 345 | console.log(await llamma.userBands()); 346 | console.log(await llamma.userPrices()); 347 | console.log(await llamma.userHealth()); // FULL 348 | console.log(await llamma.userHealth(false)); // NOT FULL 349 | console.log(await llamma.userBandsBalances()); 350 | } 351 | 352 | (async () => { 353 | console.log("\n--- generalMethodsTest ---\n") 354 | await generalMethodsTest(); 355 | console.log("\n--- llammaFieldsTest ---\n") 356 | await llammaFieldsTest(); 357 | console.log("\n--- walletBalancesTest ---\n") 358 | await walletBalancesTest(); 359 | console.log("\n--- statsTest ---\n") 360 | await statsTest(); 361 | console.log("\n--- generalTest ---\n") 362 | await generalTest(); 363 | console.log("\n--- createLoanAllRangesTest ---\n") 364 | await createLoanAllRangesTest(); 365 | console.log("\n--- swapTest ---\n") 366 | await swapTest(); 367 | console.log("\n--- selfLiquidationTest ---\n") 368 | await selfLiquidationTest(); 369 | console.log("\n--- userLossTest ---\n") 370 | await userLossTest(); 371 | console.log("\n--- leverageTest ---\n") 372 | await leverageTest(); 373 | console.log("\n--- leverageAllRangesTest ---\n") 374 | await leverageAllRangesTest(); 375 | console.log("\n--- deleverageTest ---\n") 376 | await deleverageTest(); 377 | })() 378 | -------------------------------------------------------------------------------- /test/selfLiquidate.test.ts: -------------------------------------------------------------------------------- 1 | import { assert } from "chai"; 2 | import { crvusd } from "../src/crvusd"; 3 | import { getLlamma, LlammaTemplate } from "../src/llammas"; 4 | 5 | const LLAMMAS = ['sfrxeth']; 6 | 7 | const selfLiquidationTest = (id: string) => { 8 | describe(`${id} self-liquidation test`, function () { 9 | let llamma: LlammaTemplate; 10 | 11 | before(async function () { 12 | llamma = getLlamma(id); 13 | const maxDebt = await llamma.createLoanMaxRecv(0.3, 10); 14 | await llamma.createLoan(0.3, maxDebt, 10); 15 | await llamma.swap(0, 1, Number(maxDebt) * 10, 0.05); 16 | }); 17 | 18 | it('Self-liquidations', async function () { 19 | const initialBalances = await llamma.wallet.balances(); 20 | const initialState = await llamma.userState(); 21 | const initialTokensToLiquidate = await llamma.tokensToLiquidate(); 22 | 23 | assert.isAbove(Number(initialState.collateral), 0); 24 | assert.isAbove(Number(initialState.stablecoin), 0); 25 | assert.isAbove(Number(initialState.debt), 0); 26 | assert.isAtLeast(Number(initialBalances.stablecoin), Number(initialTokensToLiquidate)); 27 | 28 | await llamma.selfLiquidate(0.1); 29 | 30 | const balances = await llamma.wallet.balances(); 31 | const state = await llamma.userState(); 32 | 33 | const tokensToLiquidate = await llamma.tokensToLiquidate(); 34 | assert.equal(Number(tokensToLiquidate), 0, 'tokens to liquidate'); 35 | assert.equal(Number(balances.collateral), Number(initialBalances.collateral) + Number(initialState.collateral), 'wallet collateral'); 36 | assert.approximately(Number(balances.stablecoin), Number(initialBalances.stablecoin) - Number(initialTokensToLiquidate), 1e-4, 'wallet stablecoin'); 37 | assert.equal(Number(state.collateral), 0, 'state callateral'); 38 | assert.equal(Number(state.stablecoin), 0, 'state stablecoin'); 39 | assert.equal(Number(state.debt), 0, 'state debt'); 40 | }); 41 | }) 42 | } 43 | 44 | describe('Self-liquidation test', async function () { 45 | this.timeout(120000); 46 | 47 | before(async function () { 48 | await crvusd.init('JsonRpc', {},{ gasPrice: 0 }); 49 | }); 50 | 51 | for (const llammaId of LLAMMAS) { 52 | selfLiquidationTest(llammaId); 53 | } 54 | }) 55 | -------------------------------------------------------------------------------- /test/swap.test.ts: -------------------------------------------------------------------------------- 1 | import { assert } from "chai"; 2 | import { crvusd } from "../src/crvusd"; 3 | import { getLlamma, LlammaTemplate } from "../src/llammas"; 4 | import { BN } from "../src/utils"; 5 | 6 | const LLAMMAS = ['sfrxeth']; 7 | 8 | const swapTest = (id: string) => { 9 | let llamma: LlammaTemplate; 10 | let maxDebt: string; 11 | 12 | before(async function () { 13 | llamma = getLlamma(id); 14 | maxDebt = await llamma.createLoanMaxRecv(0.3, 10); 15 | await llamma.createLoan(0.3, maxDebt, 10) 16 | }); 17 | 18 | after(async function () { 19 | await llamma.fullRepay(); 20 | }); 21 | 22 | 23 | describe(`${id} llamma swap test`, function () { 24 | for (let i = 0; i < 2; i++) { 25 | for (let j = 0; j < 2; j++) { 26 | if (i === j) continue; 27 | 28 | it(`${i} --> ${j}`, async function () { 29 | const initialBalances = await llamma.wallet.balances(); 30 | const swapAmount = i === 0 ? Number(maxDebt) / 10 : 0.003; 31 | const expected = Number(await llamma.swapExpected(i, j, swapAmount)); 32 | 33 | await llamma.swap(i, j, swapAmount, 0.05); 34 | 35 | const balances = await llamma.wallet.balances(); 36 | const out = Number(Object.values(balances)[j]) - Number(Object.values(initialBalances)[j]); 37 | 38 | assert.deepStrictEqual(BN(Object.values(balances)[i]).toString(), BN(Object.values(initialBalances)[i]).minus(BN(swapAmount)).toString(), 'in'); 39 | assert.isAtMost(Math.abs(out - expected) / expected, 5 * 1e-3, 'out'); 40 | }); 41 | } 42 | } 43 | }); 44 | } 45 | 46 | describe('Swap test', async function () { 47 | this.timeout(120000); 48 | 49 | before(async function () { 50 | await crvusd.init('JsonRpc', {},{ gasPrice: 0 }); 51 | }); 52 | 53 | for (const llammaId of LLAMMAS) { 54 | swapTest(llammaId); 55 | } 56 | }) 57 | -------------------------------------------------------------------------------- /tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "commonjs", 5 | "lib": ["ES2017"], 6 | "declaration": true, 7 | "outDir": "./lib", 8 | "rootDir": "./src", 9 | "strict": true, 10 | "esModuleInterop": true, 11 | "skipLibCheck": true, 12 | "forceConsistentCasingInFileNames": true, 13 | "resolveJsonModule": true 14 | }, 15 | "exclude": [ 16 | "**/*.test.ts" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Visit https://aka.ms/tsconfig.json to read more about this file */ 4 | 5 | /* Basic Options */ 6 | // "incremental": true, /* Enable incremental compilation */ 7 | "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */ 8 | "module": "ESNext", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */ 9 | "lib": ["ES2020"], /* Specify library files to be included in the compilation. */ 10 | // "allowJs": true, /* Allow javascript files to be compiled. */ 11 | // "checkJs": true, /* Report errors in .js files. */ 12 | // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */ 13 | "declaration": true, /* Generates corresponding '.d.ts' file. */ 14 | // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ 15 | // "sourceMap": true, /* Generates corresponding '.map' file. */ 16 | // "outFile": "./", /* Concatenate and emit output to single file. */ 17 | "outDir": "./dist", /* Redirect output structure to the directory. */ 18 | "rootDir": ".", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ 19 | // "composite": true, /* Enable project compilation */ 20 | // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ 21 | // "removeComments": true, /* Do not emit comments to output. */ 22 | // "noEmit": true, /* Do not emit outputs. */ 23 | // "importHelpers": true, /* Import emit helpers from 'tslib'. */ 24 | // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ 25 | // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ 26 | 27 | /* Strict Type-Checking Options */ 28 | "strict": true, /* Enable all strict type-checking options. */ 29 | // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ 30 | // "strictNullChecks": true, /* Enable strict null checks. */ 31 | // "strictFunctionTypes": true, /* Enable strict checking of function types. */ 32 | // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ 33 | // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ 34 | // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ 35 | // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ 36 | 37 | /* Additional Checks */ 38 | // "noUnusedLocals": true, /* Report errors on unused locals. */ 39 | // "noUnusedParameters": true, /* Report errors on unused parameters. */ 40 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ 41 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ 42 | // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ 43 | // "noPropertyAccessFromIndexSignature": true, /* Require undeclared properties from index signatures to use element accesses. */ 44 | 45 | /* Module Resolution Options */ 46 | "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ 47 | // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ 48 | // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ 49 | // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ 50 | // "typeRoots": [], /* List of folders to include type definitions from. */ 51 | // "types": [], /* Type declaration files to be included in compilation. */ 52 | // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ 53 | "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ 54 | // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ 55 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 56 | 57 | /* Source Map Options */ 58 | // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ 59 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 60 | // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ 61 | // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ 62 | 63 | /* Experimental Options */ 64 | // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ 65 | // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ 66 | 67 | /* Advanced Options */ 68 | "skipLibCheck": true, /* Skip type checking of declaration files. */ 69 | "forceConsistentCasingInFileNames": true, /* Disallow inconsistently-cased references to the same file. */ 70 | "resolveJsonModule": true 71 | } 72 | } 73 | --------------------------------------------------------------------------------