├── .gitignore ├── .gitattributes ├── brownie-config.yaml ├── tests ├── test_zap.py └── conftest.py ├── interfaces ├── YearnRegistry.json ├── CurveZapOut.json └── yVault.json └── contracts └── TreasuryZap.sol /.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__ 2 | .history 3 | .hypothesis/ 4 | build/ 5 | reports/ 6 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.sol linguist-language=Solidity 2 | *.vy linguist-language=Python 3 | -------------------------------------------------------------------------------- /brownie-config.yaml: -------------------------------------------------------------------------------- 1 | networks: 2 | default: mainnet-fork 3 | 4 | autofetch_sources: true 5 | 6 | dependencies: 7 | - OpenZeppelin/openzeppelin-contracts@3.2.0 8 | 9 | compiler: 10 | solc: 11 | version: 0.6.12 12 | remappings: 13 | - "@openzeppelinV3=OpenZeppelin/openzeppelin-contracts@3.2.0" 14 | -------------------------------------------------------------------------------- /tests/test_zap.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | 4 | def test_swap(whale, zap, token_out, token_in): 5 | if token_in == token_out: 6 | pytest.skip("same token") 7 | 8 | if token_in.balanceOf(whale) == 0: 9 | pytest.skip("no token_in balance") 10 | 11 | before = token_out.balanceOf(whale) 12 | token_in.approve(zap, token_in.balanceOf(whale)) 13 | amount_in = token_in.balanceOf(whale) 14 | zap.swap(token_in, token_out, amount_in) 15 | amount_out = token_out.balanceOf(whale) - before 16 | print( 17 | f"swap {amount_in / 10 ** token_in.decimals()} {token_in.symbol()} " 18 | f"for {amount_out / 10 ** token_out.decimals()} {token_out.symbol()}" 19 | ) 20 | assert amount_out > 0 21 | -------------------------------------------------------------------------------- /tests/conftest.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | 4 | tokens_in = { 5 | "aLINK": "0xA64BD6C70Cb9051F6A9ba1F163Fdc07E0DfB5F84", 6 | "LINK": "0x514910771AF9Ca656af840dff83E8264EcF986CA", 7 | "USDC": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", 8 | "yDAI+yUSDC+yUSDT+yTUSD": "0xdF5e0e81Dff6FAF3A7e52BA697820c5e32D806A8", 9 | "TUSD": "0x0000000000085d4780B73119b644AE5ecd22b376", 10 | "DAI": "0x6B175474E89094C44Da98b954EedeAC495271d0F", 11 | "USDT": "0xdAC17F958D2ee523a2206206994597C13D831ec7", 12 | "YFI": "0x0bc529c00C6401aEF6D220BE8C6Ea1667F6Ad93e", 13 | "yDAI+yUSDC+yUSDT+yBUSD": "0x3B3Ac5386837Dc563660FB6a0937DFAa5924333B", 14 | "crvRenWSBTC": "0x075b1bb99792c9E1041bA13afEf80C91a1e70fB3", 15 | "WETH": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", 16 | "3Crv": "0x6c3F90f043a72FA612cbac8115EE7e52BDe6E490", 17 | "GUSD": "0x056Fd409E1d7A124BD7017459dFEa2F387b6d5Cd", 18 | "cDAI+cUSDC": "0x845838DF265Dcd2c412A1Dc9e959c7d08537f8a2", 19 | } 20 | 21 | 22 | tokens_out = { 23 | "YFI": "0x0bc529c00C6401aEF6D220BE8C6Ea1667F6Ad93e", 24 | "DAI": "0x6B175474E89094C44Da98b954EedeAC495271d0F", 25 | } 26 | 27 | 28 | @pytest.fixture(scope="function", autouse=True) 29 | def shared_setup(fn_isolation): 30 | pass 31 | 32 | 33 | @pytest.fixture 34 | def whale(accounts): 35 | return accounts.at("0x93A62dA5a14C80f265DAbC077fCEE437B1a0Efde", force=True) 36 | 37 | 38 | @pytest.fixture 39 | def zap(TreasuryZap, whale): 40 | return TreasuryZap.deploy({"from": whale}) 41 | 42 | 43 | @pytest.fixture(params=tokens_in) 44 | def token_in(interface, request, whale): 45 | return interface.ERC20(tokens_in[request.param], owner=whale) 46 | 47 | 48 | @pytest.fixture(params=tokens_out) 49 | def token_out(interface, request): 50 | return interface.ERC20(tokens_out[request.param]) 51 | 52 | 53 | @pytest.fixture 54 | def tokens(web3, interface, whale): 55 | yregistry = interface.YearnRegistry(web3.ens.resolve("registry.ychad.eth")) 56 | return [ 57 | interface.ERC20(token, owner=whale) 58 | for token in yregistry.getVaultsInfo().dict()["tokenArray"] 59 | ] 60 | -------------------------------------------------------------------------------- /interfaces/YearnRegistry.json: -------------------------------------------------------------------------------- 1 | [{"inputs":[{"internalType":"address","name":"_governance","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"acceptGovernance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"}],"name":"addDelegatedVault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"}],"name":"addVault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"}],"name":"addWrappedVault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getName","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getVault","outputs":[{"internalType":"address","name":"vault","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"}],"name":"getVaultInfo","outputs":[{"internalType":"address","name":"controller","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"strategy","type":"address"},{"internalType":"bool","name":"isWrapped","type":"bool"},{"internalType":"bool","name":"isDelegated","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getVaults","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getVaultsInfo","outputs":[{"internalType":"address[]","name":"controllerArray","type":"address[]"},{"internalType":"address[]","name":"tokenArray","type":"address[]"},{"internalType":"address[]","name":"strategyArray","type":"address[]"},{"internalType":"bool[]","name":"isWrappedArray","type":"bool[]"},{"internalType":"bool[]","name":"isDelegatedArray","type":"bool[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getVaultsLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"governance","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isDelegatedVault","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingGovernance","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_pendingGovernance","type":"address"}],"name":"setPendingGovernance","outputs":[],"stateMutability":"nonpayable","type":"function"}] -------------------------------------------------------------------------------- /contracts/TreasuryZap.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: AGPL 2 | pragma solidity=0.6.12; 3 | 4 | import "@openzeppelinV3/contracts/token/ERC20/IERC20.sol"; 5 | import "@openzeppelinV3/contracts/math/SafeMath.sol"; 6 | import "@openzeppelinV3/contracts/utils/Address.sol"; 7 | import "@openzeppelinV3/contracts/token/ERC20/SafeERC20.sol"; 8 | 9 | 10 | interface CurveRegistry { 11 | function get_pool_from_lp_token(address) external view returns (address); 12 | } 13 | 14 | interface Uniswap { 15 | function swapExactTokensForTokens( 16 | uint256 amountIn, 17 | uint256 amountOutMin, 18 | address[] calldata path, 19 | address to, 20 | uint256 deadline 21 | ) external returns (uint256[] memory amounts); 22 | 23 | function addLiquidity( 24 | address tokenA, 25 | address tokenB, 26 | uint amountADesired, 27 | uint amountBDesired, 28 | uint amountAMin, 29 | uint amountBMin, 30 | address to, 31 | uint deadline 32 | ) external returns (uint amountA, uint amountB, uint liquidity); 33 | 34 | function getAmountsOut(uint amountIn, address[] memory path) external view returns (uint[] memory amounts); 35 | } 36 | 37 | 38 | interface Zapper { 39 | function ZapOut( 40 | address payable toWhomToIssue, 41 | address swapAddress, 42 | uint256 incomingCrv, 43 | address toToken, 44 | uint256 minToTokens 45 | ) external returns (uint256 ToTokensBought); 46 | } 47 | 48 | 49 | contract TreasuryZap { 50 | using SafeERC20 for IERC20; 51 | using Address for address; 52 | using SafeMath for uint256; 53 | 54 | address constant weth = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; 55 | address constant uniswap = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D; 56 | address constant curve_registry = 0x7D86446dDb609eD0F5f8684AcF30380a356b2B4c; 57 | address constant curve_zap_out = 0xA3061Cf6aC1423c6F40917AD49602cBA187181Dc; 58 | mapping(address => address) curve_deposit; 59 | 60 | constructor() public { 61 | curve_deposit[0x845838DF265Dcd2c412A1Dc9e959c7d08537f8a2] = 0xeB21209ae4C2c9FF2a86ACA31E123764A3B6Bc06; // compound 62 | curve_deposit[0x9fC689CCaDa600B6DF723D9E47D84d76664a1F23] = 0xac795D2c97e60DF6a99ff1c814727302fD747a80; // usdt 63 | curve_deposit[0xdF5e0e81Dff6FAF3A7e52BA697820c5e32D806A8] = 0xbBC81d23Ea2c3ec7e56D39296F0cbB648873a5d3; // y 64 | curve_deposit[0x3B3Ac5386837Dc563660FB6a0937DFAa5924333B] = 0xb6c057591E073249F2D9D88Ba59a46CFC9B59EdB; // busd 65 | curve_deposit[0xC25a3A3b969415c80451098fa907EC722572917F] = 0xFCBa3E75865d2d561BE8D220616520c171F12851; // susdv2 66 | curve_deposit[0xD905e2eaeBe188fc92179b6350807D8bd91Db0D8] = 0xA50cCc70b6a011CffDdf45057E39679379187287; // pax 67 | } 68 | 69 | function swap(address token_in, address token_out, uint amount_in) public returns (uint amount_out) { 70 | IERC20(token_in).safeTransferFrom(msg.sender, address(this), amount_in); 71 | address pool_in = token_to_curve_pool(token_in); 72 | if (pool_in != address(0)) { 73 | amount_out = swap_curve(token_in, token_out, amount_in); 74 | } else { 75 | amount_out = swap_uniswap(token_in, token_out, amount_in); 76 | } 77 | } 78 | 79 | function token_to_curve_pool(address token_in) internal returns (address pool) { 80 | pool = CurveRegistry(curve_registry).get_pool_from_lp_token(token_in); 81 | if (curve_deposit[token_in] != address(0)) pool = curve_deposit[token_in]; 82 | } 83 | 84 | function swap_curve(address token_in, address token_out, uint amount_in) public returns (uint amount_out) { 85 | IERC20(token_in).safeApprove(curve_zap_out, amount_in); 86 | address pool_in = token_to_curve_pool(token_in); 87 | amount_out = Zapper(curve_zap_out).ZapOut( 88 | payable(msg.sender), 89 | pool_in, 90 | amount_in, 91 | token_out, 92 | 0 93 | ); 94 | } 95 | 96 | function swap_uniswap(address token_in, address token_out, uint amount_in) public returns (uint amount_out) { 97 | if (token_in == token_out) return amount_in; 98 | bool is_weth = token_in == weth || token_out == weth; 99 | address[] memory path = new address[](is_weth ? 2 : 3); 100 | path[0] = token_in; 101 | if (is_weth) { 102 | path[1] = token_out; 103 | } else { 104 | path[1] = weth; 105 | path[2] = token_out; 106 | } 107 | if (IERC20(token_in).allowance(address(this), uniswap) < amount_in) 108 | IERC20(token_in).safeApprove(uniswap, type(uint256).max); 109 | uint[] memory amounts = Uniswap(uniswap).swapExactTokensForTokens( 110 | amount_in, 111 | 0, 112 | path, 113 | msg.sender, 114 | block.timestamp 115 | ); 116 | amount_out = amounts[amounts.length - 1]; 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /interfaces/CurveZapOut.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "contract ICurveRegistry", 6 | "name": "_curveRegistry", 7 | "type": "address" 8 | } 9 | ], 10 | "payable": false, 11 | "stateMutability": "nonpayable", 12 | "type": "constructor" 13 | }, 14 | { 15 | "anonymous": false, 16 | "inputs": [ 17 | { 18 | "indexed": true, 19 | "internalType": "address", 20 | "name": "previousOwner", 21 | "type": "address" 22 | }, 23 | { 24 | "indexed": true, 25 | "internalType": "address", 26 | "name": "newOwner", 27 | "type": "address" 28 | } 29 | ], 30 | "name": "OwnershipTransferred", 31 | "type": "event" 32 | }, 33 | { "payable": true, "stateMutability": "payable", "type": "fallback" }, 34 | { 35 | "constant": false, 36 | "inputs": [ 37 | { 38 | "internalType": "address payable", 39 | "name": "toWhomToIssue", 40 | "type": "address" 41 | }, 42 | { "internalType": "address", "name": "swapAddress", "type": "address" }, 43 | { "internalType": "uint256", "name": "incomingCrv", "type": "uint256" }, 44 | { "internalType": "address", "name": "toToken", "type": "address" }, 45 | { "internalType": "uint256", "name": "minToTokens", "type": "uint256" } 46 | ], 47 | "name": "ZapOut", 48 | "outputs": [ 49 | { "internalType": "uint256", "name": "ToTokensBought", "type": "uint256" } 50 | ], 51 | "payable": false, 52 | "stateMutability": "nonpayable", 53 | "type": "function" 54 | }, 55 | { 56 | "constant": true, 57 | "inputs": [], 58 | "name": "curveReg", 59 | "outputs": [ 60 | { 61 | "internalType": "contract ICurveRegistry", 62 | "name": "", 63 | "type": "address" 64 | } 65 | ], 66 | "payable": false, 67 | "stateMutability": "view", 68 | "type": "function" 69 | }, 70 | { 71 | "constant": true, 72 | "inputs": [], 73 | "name": "goodwill", 74 | "outputs": [{ "internalType": "uint16", "name": "", "type": "uint16" }], 75 | "payable": false, 76 | "stateMutability": "view", 77 | "type": "function" 78 | }, 79 | { 80 | "constant": false, 81 | "inputs": [ 82 | { 83 | "internalType": "contract IERC20", 84 | "name": "_TokenAddress", 85 | "type": "address" 86 | } 87 | ], 88 | "name": "inCaseTokengetsStuck", 89 | "outputs": [], 90 | "payable": false, 91 | "stateMutability": "nonpayable", 92 | "type": "function" 93 | }, 94 | { 95 | "constant": true, 96 | "inputs": [], 97 | "name": "intermediateStable", 98 | "outputs": [{ "internalType": "address", "name": "", "type": "address" }], 99 | "payable": false, 100 | "stateMutability": "view", 101 | "type": "function" 102 | }, 103 | { 104 | "constant": true, 105 | "inputs": [], 106 | "name": "isOwner", 107 | "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], 108 | "payable": false, 109 | "stateMutability": "view", 110 | "type": "function" 111 | }, 112 | { 113 | "constant": true, 114 | "inputs": [], 115 | "name": "owner", 116 | "outputs": [{ "internalType": "address", "name": "", "type": "address" }], 117 | "payable": false, 118 | "stateMutability": "view", 119 | "type": "function" 120 | }, 121 | { 122 | "constant": false, 123 | "inputs": [], 124 | "name": "renounceOwnership", 125 | "outputs": [], 126 | "payable": false, 127 | "stateMutability": "nonpayable", 128 | "type": "function" 129 | }, 130 | { 131 | "constant": false, 132 | "inputs": [ 133 | { "internalType": "uint16", "name": "_new_goodwill", "type": "uint16" } 134 | ], 135 | "name": "set_new_goodwill", 136 | "outputs": [], 137 | "payable": false, 138 | "stateMutability": "nonpayable", 139 | "type": "function" 140 | }, 141 | { 142 | "constant": false, 143 | "inputs": [ 144 | { 145 | "internalType": "address", 146 | "name": "_new_zgoodwillAddress", 147 | "type": "address" 148 | } 149 | ], 150 | "name": "set_new_zgoodwillAddress", 151 | "outputs": [], 152 | "payable": false, 153 | "stateMutability": "nonpayable", 154 | "type": "function" 155 | }, 156 | { 157 | "constant": true, 158 | "inputs": [], 159 | "name": "stopped", 160 | "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], 161 | "payable": false, 162 | "stateMutability": "view", 163 | "type": "function" 164 | }, 165 | { 166 | "constant": false, 167 | "inputs": [], 168 | "name": "toggleContractActive", 169 | "outputs": [], 170 | "payable": false, 171 | "stateMutability": "nonpayable", 172 | "type": "function" 173 | }, 174 | { 175 | "constant": false, 176 | "inputs": [ 177 | { 178 | "internalType": "address payable", 179 | "name": "newOwner", 180 | "type": "address" 181 | } 182 | ], 183 | "name": "transferOwnership", 184 | "outputs": [], 185 | "payable": false, 186 | "stateMutability": "nonpayable", 187 | "type": "function" 188 | }, 189 | { 190 | "constant": false, 191 | "inputs": [ 192 | { 193 | "internalType": "contract ICurveRegistry", 194 | "name": "newCurveRegistry", 195 | "type": "address" 196 | } 197 | ], 198 | "name": "updateCurveRegistry", 199 | "outputs": [], 200 | "payable": false, 201 | "stateMutability": "nonpayable", 202 | "type": "function" 203 | }, 204 | { 205 | "constant": false, 206 | "inputs": [ 207 | { 208 | "internalType": "address", 209 | "name": "newIntermediate", 210 | "type": "address" 211 | } 212 | ], 213 | "name": "updateIntermediateStable", 214 | "outputs": [], 215 | "payable": false, 216 | "stateMutability": "nonpayable", 217 | "type": "function" 218 | }, 219 | { 220 | "constant": false, 221 | "inputs": [], 222 | "name": "withdraw", 223 | "outputs": [], 224 | "payable": false, 225 | "stateMutability": "nonpayable", 226 | "type": "function" 227 | }, 228 | { 229 | "constant": true, 230 | "inputs": [], 231 | "name": "zgoodwillAddress", 232 | "outputs": [{ "internalType": "address", "name": "", "type": "address" }], 233 | "payable": false, 234 | "stateMutability": "view", 235 | "type": "function" 236 | } 237 | ] 238 | -------------------------------------------------------------------------------- /interfaces/yVault.json: -------------------------------------------------------------------------------- 1 | [{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"address","name":"_controller","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"constant":true,"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"available","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"balance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"controller","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"deposit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"depositAll","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"depositETH","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[],"name":"earn","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getPricePerFullShare","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"governance","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"reserve","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"harvest","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"max","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"min","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_controller","type":"address"}],"name":"setController","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_governance","type":"address"}],"name":"setGovernance","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_min","type":"uint256"}],"name":"setMin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"token","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_shares","type":"uint256"}],"name":"withdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"withdrawAll","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"withdrawAllETH","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_shares","type":"uint256"}],"name":"withdrawETH","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}] --------------------------------------------------------------------------------