def main(): deployer = accounts.at('0xB593d82d53e2c187dc49673709a6E9f806cdC835', force=True) # deployer = accounts.load('gh') werc20 = WERC20.at('0xe28D9dF7718b0b5Ba69E01073fE82254a9eD2F98') wmas = WMasterChef.at('0x373ae78a14577682591E088F2E78EF1417612c68') wliq = WLiquidityGauge.at('0xfdB4f97953150e47C8606758C13e70b5a789a7ec') wsindex = WStakingRewards.at('0x713df2DDDA9C7d7bDa98A9f8fCd82c06c50fbd90') wsperp = WStakingRewards.at('0xC4635854480ffF80F742645da0310e9e59795c63') uni_kp3r_oracle = ERC20KP3ROracle.at( '0x8E2A3777AB22e1c5f6d1fF2BcC6C4aA6aB1DeA14') sushi_kp3r_oracle = ERC20KP3ROracle.at( '0xC331687FD71bb1D7f2e237091F8888dDcaD50C9a') core_oracle = CoreOracle.at('0x1E5BDdd0cDF8839d6b27b34927869eF0AD7bf692') uni_oracle = UniswapV2Oracle.at( '0x910aD02D355c2966e8dD8E32C890cD50DB29C3B9') bal_oracle = BalancerPairOracle.at( '0x8F93B0AA2643bf74ab38d6a5910fA82D2da02134') crv_oracle = CurveOracle.at('0x04DE0E42B3b0483248deafE86C4F5428613b76Ff') proxy_oracle = ProxyOracle.at('0x43c425fB2b00a991A51b18c217D749E393bF1AB2') # pair token with oracle from .tokens import Tokens # re-set oracles oracle_params = [ # lp tokens [Tokens.bal_perp_usdc, [14886, 6718, 10250]], ] token_list_2, param_list = zip(*oracle_params) proxy_oracle.setOracles(token_list_2, param_list, {'from': deployer}) proxy_oracle.unsetOracles([Tokens.bal_dai_weth], {'from': deployer}) print('DONE') ########################################################### # test spells (UNCOMMENT TO TEST) for token in [ Tokens.weth, Tokens.dai, Tokens.usdc, Tokens.usdt, Tokens.dpi, Tokens.yfi, Tokens.snx, Tokens.susd ]: token = interface.IERC20Ex(token) deposit_safebox(token) bank = HomoraBank.at('0x5f5Cd91070960D13ee549C9CC47e7a4Cd00457bb') uniswap_spell = UniswapV2SpellV1.at( '0xc671B7251a789de0835a2fa33c83c8D4afB39092') sushiswap_spell = SushiswapSpellV1.at( '0x21Fa95485f4571A3a0d0c396561cF4D8D13D445d') balancer_spell = BalancerSpellV1.at( '0x15B79c184A6a8E19a4CA1F637081270343E4D15D') curve_spell = CurveSpellV1.at('0x42C750024E02816eE32EB2eB4DA79ff5BF343D30')
def main(): deployer = accounts.at('0xB593d82d53e2c187dc49673709a6E9f806cdC835', force=True) # deployer = accounts.load('gh') werc20 = WERC20.at('0xe28D9dF7718b0b5Ba69E01073fE82254a9eD2F98') wmas = WMasterChef.at('0x373ae78a14577682591E088F2E78EF1417612c68') wliq = WLiquidityGauge.at('0xfdB4f97953150e47C8606758C13e70b5a789a7ec') wsindex = WStakingRewards.at('0x713df2DDDA9C7d7bDa98A9f8fCd82c06c50fbd90') wsperp = WStakingRewards.at('0xC4635854480ffF80F742645da0310e9e59795c63') kp3r_oracle = ERC20KP3ROracle.at( '0x8E2A3777AB22e1c5f6d1fF2BcC6C4aA6aB1DeA14') core_oracle = CoreOracle.at('0x1E5BDdd0cDF8839d6b27b34927869eF0AD7bf692') uni_oracle = UniswapV2Oracle.at( '0x910aD02D355c2966e8dD8E32C890cD50DB29C3B9') bal_oracle = BalancerPairOracle.at( '0x8F93B0AA2643bf74ab38d6a5910fA82D2da02134') crv_oracle = CurveOracle.at('0x04DE0E42B3b0483248deafE86C4F5428613b76Ff') proxy_oracle = ProxyOracle.at('0x43c425fB2b00a991A51b18c217D749E393bF1AB2') bank_impl = HomoraBank.at('0x95ab3Ca8133b47f16f47F6A79410680fE87a6139') proxy_admin = Contract.from_explorer( '0x090eCE252cEc5998Db765073D07fac77b8e60CB2') bank = HomoraBank.at('0x5f5Cd91070960D13ee549C9CC47e7a4Cd00457bb') proxy_admin.upgrade(bank, bank_impl, {'from': deployer}) bank.setOracle(proxy_oracle, {'from': deployer}) uniswap_spell = UniswapV2SpellV1.deploy( bank, werc20, '0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D', {'from': deployer}, ) sushiswap_spell = SushiswapSpellV1.deploy( bank, werc20, '0xd9e1cE17f2641f24aE83637ab66a2cca9C378B9F', wmas, {'from': deployer}, ) balancer_spell = BalancerSpellV1.at( '0x15B79c184A6a8E19a4CA1F637081270343E4D15D') curve_spell = CurveSpellV1.deploy( bank, werc20, '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', wliq, {'from': deployer}, ) print('DONE')
def main(): admin = accounts[0] alice = accounts[1] dai = interface.IERC20Ex('0x6B175474E89094C44Da98b954EedeAC495271d0F') usdc = interface.IERC20Ex('0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48') usdt = interface.IERC20Ex('0xdAC17F958D2ee523a2206206994597C13D831ec7') weth = interface.IERC20Ex('0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2') eth_usdt = interface.IERC20Ex('0x0d4a11d5EEaaC28EC3F61d100daF4d40471f1852') eth_usdc = interface.IERC20Ex('0xb4e16d0168e52d35cacd2c6185b44281ec28c9dc') usdt_usdc = interface.IERC20Ex( '0x3041cbd36888becc7bbcbc0045e3b1f144466f5f') uni_pair = interface.IUniswapV2Pair( '0xa478c2975ab1ea89e8196811f51a7b7ade33eb11') resA, resB, _ = uni_pair.getReserves() if uni_pair.token0() == weth: weth_price = resB * 10**18 // resA else: weth_price = resA * 10**18 // resB print('weth price', weth_price) simple_oracle = SimpleOracle.deploy({'from': admin}) simple_oracle.setETHPx([dai, usdt, usdc, weth], [ 2**112 * 10**18 // weth_price, 2**112 * 10**30 // weth_price, 2**112 * 10**30 // weth_price, 2**112 ]) uniswap_oracle = UniswapV2Oracle.deploy(simple_oracle, {'from': admin}) # expected ~100k * 2**112 print('ETH-USDT LP:', uniswap_oracle.getETHPx(eth_usdt)) # expected ~100k * 2**112 print('ETH-USDC LP:', uniswap_oracle.getETHPx(eth_usdc)) # expected ~3.8e9 * 2**112 print('USDT-USDC LP:', uniswap_oracle.getETHPx(usdt_usdc)) assert almostEqual( uniswap_oracle.getETHPx(eth_usdt), weth.balanceOf(eth_usdt) * 2 * 2**112 // eth_usdt.totalSupply()) assert almostEqual( uniswap_oracle.getETHPx(eth_usdc), weth.balanceOf(eth_usdc) * 2 * 2**112 // eth_usdc.totalSupply()) assert almostEqual( uniswap_oracle.getETHPx(usdt_usdc), usdt.balanceOf(usdt_usdc) * 2 * simple_oracle.getETHPx(usdt) // usdt_usdc.totalSupply())
def main(): admin = accounts[0] alice = accounts[1] dai = interface.IERC20Ex('0x6B175474E89094C44Da98b954EedeAC495271d0F') usdc = interface.IERC20Ex('0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48') usdt = interface.IERC20Ex('0xdAC17F958D2ee523a2206206994597C13D831ec7') weth = interface.IERC20Ex('0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2') eth_usdt = interface.IERC20Ex('0x0d4a11d5EEaaC28EC3F61d100daF4d40471f1852') eth_usdc = interface.IERC20Ex('0xb4e16d0168e52d35cacd2c6185b44281ec28c9dc') usdt_usdc = interface.IERC20Ex( '0x3041cbd36888becc7bbcbc0045e3b1f144466f5f') simple_oracle = SimpleOracle.deploy({'from': admin}) simple_oracle.setETHPx([dai, usdt, usdc, weth], [ 9060553589188986552095106856227, 9002288773315920458132820329673073223442669, 9011535487953795006625883219171279625142296, 2**112 ]) uniswap_oracle = UniswapV2Oracle.deploy(simple_oracle, {'from': admin}) # expected ~100k * 2**112 print('ETH-USDT LP:', uniswap_oracle.getETHPx(eth_usdt)) # expected ~100k * 2**112 print('ETH-USDC LP:', uniswap_oracle.getETHPx(eth_usdc)) # expected ~3.8e9 * 2**112 print('USDT-USDC LP:', uniswap_oracle.getETHPx(usdt_usdc)) assert almostEqual( uniswap_oracle.getETHPx(eth_usdt), weth.balanceOf(eth_usdt) * 2 * 2**112 // eth_usdt.totalSupply()) assert almostEqual( uniswap_oracle.getETHPx(eth_usdc), weth.balanceOf(eth_usdc) * 2 * 2**112 // eth_usdc.totalSupply()) assert almostEqual( uniswap_oracle.getETHPx(usdt_usdc), usdt.balanceOf(usdt_usdc) * 2 * simple_oracle.getETHPx(usdt) // usdt_usdc.totalSupply())
def main(): deployer = accounts.load('deployer') oracle = ERC20KP3ROracle.deploy( '0x73353801921417F465377c8d898c6f4C0270282C', {'from': deployer}, ) lp_oracle = UniswapV2Oracle.deploy(oracle, {'from': deployer}) # usdt data = oracle.getETHPx('0xdac17f958d2ee523a2206206994597c13d831ec7') print(data) print(1 / (data / (2**112))) # usdc data = oracle.getETHPx('0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48') print(data) print(1 / (data / (2**112))) # usdt-usdc data = lp_oracle.getETHPx('0x3041cbd36888becc7bbcbc0045e3b1f144466f5f') print(data) print(data / (2**112))
def main(): deployer = accounts.at('0xB593d82d53e2c187dc49673709a6E9f806cdC835', force=True) # deployer = accounts.load('gh') werc20 = WERC20.at('0xe28D9dF7718b0b5Ba69E01073fE82254a9eD2F98') wmas = WMasterChef.at('0x373ae78a14577682591E088F2E78EF1417612c68') wliq = WLiquidityGauge.at('0xfdB4f97953150e47C8606758C13e70b5a789a7ec') wsindex = WStakingRewards.at('0x713df2DDDA9C7d7bDa98A9f8fCd82c06c50fbd90') wsperp = WStakingRewards.at('0xC4635854480ffF80F742645da0310e9e59795c63') uni_kp3r_oracle = ERC20KP3ROracle.at( '0x8E2A3777AB22e1c5f6d1fF2BcC6C4aA6aB1DeA14') sushi_kp3r_oracle = ERC20KP3ROracle.at( '0xC331687FD71bb1D7f2e237091F8888dDcaD50C9a') core_oracle = CoreOracle.at('0x1E5BDdd0cDF8839d6b27b34927869eF0AD7bf692') uni_oracle = UniswapV2Oracle.at( '0x910aD02D355c2966e8dD8E32C890cD50DB29C3B9') bal_oracle = BalancerPairOracle.at( '0x8F93B0AA2643bf74ab38d6a5910fA82D2da02134') crv_oracle = CurveOracle.at('0x04DE0E42B3b0483248deafE86C4F5428613b76Ff') proxy_oracle = ProxyOracle.at('0x43c425fB2b00a991A51b18c217D749E393bF1AB2') # pair token with oracle from .tokens import Tokens # re-set oracles oracle_params = [ # lp tokens [Tokens.bal_dai_weth, [12616, 7927, 10250]], ] token_list_2, param_list = zip(*oracle_params) proxy_oracle.setOracles(token_list_2, param_list, {'from': deployer}) print('DONE')
def main(): admin = accounts[0] alice = accounts[1] usdt = interface.IERC20Ex('0xdAC17F958D2ee523a2206206994597C13D831ec7') weth = interface.IERC20Ex('0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2') lp = interface.IERC20Ex('0x0d4a11d5EEaaC28EC3F61d100daF4d40471f1852') crusdt = interface.ICErc20('0x797AAB1ce7c01eB727ab980762bA88e7133d2157') router = interface.IUniswapV2Router02( '0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D') chef = accounts.at('0xc2edad668740f1aa35e4d8f227fb8e17dca888cd', force=True) wchef = WMasterChef.deploy(chef, {'from': admin}) werc20 = WERC20.deploy({'from': admin}) simple_oracle = SimpleOracle.deploy({'from': admin}) simple_oracle.setETHPx( [usdt, weth], [9011535487953795006625883219171279625142296, 2**112]) uniswap_oracle = UniswapV2Oracle.deploy(simple_oracle, {'from': admin}) core_oracle = CoreOracle.deploy({'from': admin}) oracle = ProxyOracle.deploy(core_oracle, {'from': admin}) oracle.setWhitelistERC1155([werc20], True, {'from': admin}) core_oracle.setRoute( [usdt, weth, lp], [simple_oracle, simple_oracle, uniswap_oracle], {'from': admin}, ) oracle.setOracles( [usdt, weth, lp], [ [10000, 10000, 10000], [10000, 10000, 10000], [10000, 10000, 10000], ], {'from': admin}, ) homora = HomoraBank.deploy({'from': admin}) homora.initialize(oracle, 1000, {'from': admin}) # 10% fee setup_bank_hack(homora) homora.addBank(usdt, crusdt, {'from': admin}) # setup initial funds to alice mint_tokens(usdt, alice) mint_tokens(weth, alice) # check alice's funds print(f'Alice usdt balance {usdt.balanceOf(alice)}') print(f'Alice weth balance {weth.balanceOf(alice)}') # Steal some LP from the staking pool mint_tokens(lp, alice) # set approval usdt.approve(homora, 2**256 - 1, {'from': alice}) usdt.approve(crusdt, 2**256 - 1, {'from': alice}) weth.approve(homora, 2**256 - 1, {'from': alice}) lp.approve(homora, 2**256 - 1, {'from': alice}) uniswap_spell = UniswapV2SpellV1.deploy(homora, werc20, router, {'from': admin}) # first time call to reduce gas uniswap_spell.getPair(weth, usdt, {'from': admin}) # whitelist spell in bank homora.setWhitelistSpells([uniswap_spell], [True], {'from': admin}) # whitelist lp in spell uniswap_spell.setWhitelistLPTokens([lp], [True], {'from': admin}) ##################################################################################### print( '=========================================================================' ) print('Case 1.') prevABal = usdt.balanceOf(alice) prevBBal = weth.balanceOf(alice) prevLPBal = lp.balanceOf(alice) prevLPBal_bank = lp.balanceOf(homora) prevLPBal_werc20 = lp.balanceOf(werc20) if interface.IUniswapV2Pair(lp).token0() == usdt: prevARes, prevBRes, _ = interface.IUniswapV2Pair(lp).getReserves() else: prevBRes, prevARes, _ = interface.IUniswapV2Pair(lp).getReserves() usdt_amt = 400 * 10**6 weth_amt = 10**18 lp_amt = 1 * 10**16 borrow_usdt_amt = 0 borrow_weth_amt = 0 tx = homora.execute( 0, uniswap_spell, uniswap_spell.addLiquidityWERC20.encode_input( usdt, # token 0 weth, # token 1 [ usdt_amt, # supply USDT weth_amt, # supply WETH lp_amt, # supply LP borrow_usdt_amt, # borrow USDT borrow_weth_amt, # borrow WETH 0, # borrow LP tokens 0, # min USDT 0 ], # min WETH ), {'from': alice}) curABal = usdt.balanceOf(alice) curBBal = weth.balanceOf(alice) curLPBal = lp.balanceOf(alice) curLPBal_bank = lp.balanceOf(homora) curLPBal_werc20 = lp.balanceOf(werc20) if interface.IUniswapV2Pair(lp).token0() == usdt: curARes, curBRes, _ = interface.IUniswapV2Pair(lp).getReserves() else: curBRes, curARes, _ = interface.IUniswapV2Pair(lp).getReserves() print('spell lp balance', lp.balanceOf(uniswap_spell)) print('Alice delta A balance', curABal - prevABal) print('Alice delta B balance', curBBal - prevBBal) print('add liquidity gas', tx.gas_used) print('bank lp balance', curLPBal_bank) _, _, _, totalDebt, totalShare = homora.getBankInfo(usdt) print('bank usdt totalDebt', totalDebt) print('bank usdt totalShare', totalShare) print('bank prev LP balance', prevLPBal_bank) print('bank cur LP balance', curLPBal_bank) print('werc20 prev LP balance', prevLPBal_werc20) print('werc20 cur LP balance', curLPBal_werc20) print('prev usdt res', prevARes) print('cur usdt res', curARes) print('prev weth res', prevBRes) print('cur weth res', curBRes) # alice assert almostEqual(curABal - prevABal, -usdt_amt), 'incorrect USDT amt' assert almostEqual(curBBal - prevBBal, -weth_amt), 'incorrect WETH amt' assert curLPBal - prevLPBal == -lp_amt, 'incorrect LP amt' # spell assert usdt.balanceOf(uniswap_spell) == 0, 'non-zero spell USDT balance' assert weth.balanceOf(uniswap_spell) == 0, 'non-zero spell WETH balance' assert lp.balanceOf(uniswap_spell) == 0, 'non-zero spell LP balance' assert totalDebt == borrow_usdt_amt # check balance and pool reserves assert curABal - prevABal - borrow_usdt_amt == - \ (curARes - prevARes), 'not all USDT tokens go to LP pool' assert almostEqual( curBBal - prevBBal - borrow_weth_amt, -(curBRes - prevBRes)), 'not all WETH tokens go to LP pool' ##################################################################################### print( '=========================================================================' ) print('Case 2.') # remove liquidity from the same position prevABal = usdt.balanceOf(alice) prevBBal = weth.balanceOf(alice) prevLPBal = lp.balanceOf(alice) prevLPBal_bank = lp.balanceOf(homora) prevLPBal_werc20 = lp.balanceOf(werc20) prevETHBal = alice.balance() if interface.IUniswapV2Pair(lp).token0() == usdt: prevARes, prevBRes, _ = interface.IUniswapV2Pair(lp).getReserves() else: prevBRes, prevARes, _ = interface.IUniswapV2Pair(lp).getReserves() lp_take_amt = 1 * 10**16 lp_want = 1 * 10**15 usdt_repay = 2**256 - 1 # max weth_repay = 0 real_usdt_repay = homora.borrowBalanceStored(1, usdt) tx = homora.execute( 1, uniswap_spell, uniswap_spell.removeLiquidityWERC20.encode_input( usdt, # token 0 weth, # token 1 [ lp_take_amt, # take out LP tokens lp_want, # withdraw LP tokens to wallet usdt_repay, # repay USDT 0, # repay WETH 0, # repay LP 0, # min USDT 0 ], # min WETH ), {'from': alice}) curABal = usdt.balanceOf(alice) curBBal = weth.balanceOf(alice) curLPBal = lp.balanceOf(alice) curLPBal_bank = lp.balanceOf(homora) curLPBal_werc20 = lp.balanceOf(werc20) curETHBal = alice.balance() if interface.IUniswapV2Pair(lp).token0() == usdt: curARes, curBRes, _ = interface.IUniswapV2Pair(lp).getReserves() else: curBRes, curARes, _ = interface.IUniswapV2Pair(lp).getReserves() print('spell lp balance', lp.balanceOf(uniswap_spell)) print('spell usdt balance', usdt.balanceOf(uniswap_spell)) print('spell weth balance', weth.balanceOf(uniswap_spell)) print('Alice delta A balance', curABal - prevABal) print('Alice delta B balance', curBBal - prevBBal) print('Alice delta LP balance', curLPBal - prevLPBal) print('remove liquidity gas', tx.gas_used) print('bank delta lp balance', curLPBal_bank - prevLPBal_bank) print('bank total lp balance', curLPBal_bank) _, _, _, totalDebt, totalShare = homora.getBankInfo(usdt) print('bank usdt totalDebt', totalDebt) print('bank usdt totalShare', totalShare) print('LP want', lp_want) print('bank delta LP amount', curLPBal_bank - prevLPBal_bank) print('LP take amount', lp_take_amt) print('prev werc20 LP balance', prevLPBal_werc20) print('cur werc20 LP balance', curLPBal_werc20) print('real usdt repay', real_usdt_repay) # alice assert almostEqual(curBBal - prevBBal, 0), 'incorrect WETH amt' assert almostEqual(curLPBal - prevLPBal, lp_want), 'incorrect LP amt' # werc20 assert almostEqual(curLPBal_werc20 - prevLPBal_werc20, -lp_take_amt), 'incorrect werc20 LP amt' # spell assert usdt.balanceOf(uniswap_spell) == 0, 'non-zero spell USDT balance' assert weth.balanceOf(uniswap_spell) == 0, 'non-zero spell WETH balance' assert lp.balanceOf(uniswap_spell) == 0, 'non-zero spell LP balance' # check balance and pool reserves assert almostEqual( curABal - prevABal + real_usdt_repay, -(curARes - prevARes)), 'inconsistent USDT from withdraw' assert almostEqual(curBBal - prevBBal, 0), 'inconsistent WETH from withdraw' assert almostEqual(curETHBal - prevETHBal + weth_repay, -(curBRes - prevBRes)), 'inconsistent ETH from withdraw' return tx
def main(): admin = accounts[0] alice = accounts[1] usdt = interface.IERC20Ex('0xdAC17F958D2ee523a2206206994597C13D831ec7') usdc = interface.IERC20Ex('0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48') lp = interface.IERC20Ex('0x3041cbd36888becc7bbcbc0045e3b1f144466f5f') crusdt = interface.ICErc20('0x797AAB1ce7c01eB727ab980762bA88e7133d2157') crusdc = interface.ICErc20('0x44fbebd2f576670a6c33f6fc0b00aa8c5753b322') router = interface.IUniswapV2Router02( '0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D') chef = accounts.at('0xc2edad668740f1aa35e4d8f227fb8e17dca888cd', force=True) wchef = WMasterChef.deploy(chef, {'from': admin}) werc20 = WERC20.deploy({'from': admin}) simple_oracle = SimpleOracle.deploy({'from': admin}) simple_oracle.setETHPx([usdt, usdc], [ 8343331721347310729683379470025550036595362, 8344470555541464992529317899641128796042472 ]) uniswap_oracle = UniswapV2Oracle.deploy(simple_oracle, {'from': admin}) core_oracle = CoreOracle.deploy({'from': admin}) oracle = ProxyOracle.deploy(core_oracle, {'from': admin}) oracle.setWhitelistERC1155([werc20], True, {'from': admin}) core_oracle.setRoute( [usdt, usdc, lp], [simple_oracle, simple_oracle, uniswap_oracle], {'from': admin}, ) oracle.setOracles( [usdt, usdc, lp], [ [10000, 10000, 10000], [10000, 10000, 10000], [10000, 10000, 10000], ], {'from': admin}, ) # initialize homora = HomoraBank.deploy({'from': admin}) homora.initialize(oracle, 1000, {'from': admin}) # 10% fee setup_bank_hack(homora) # add bank homora.addBank(usdt, crusdt, {'from': admin}) homora.addBank(usdc, crusdc, {'from': admin}) # setup initial funds to alice mint_tokens(usdt, alice) mint_tokens(usdc, alice) # check alice's funds print(f'Alice usdt balance {usdt.balanceOf(alice)}') print(f'Alice usdc balance {usdc.balanceOf(alice)}') # steal some LP from the staking pool mint_tokens(lp, alice) # set approval usdt.approve(homora, 2**256 - 1, {'from': alice}) usdt.approve(crusdt, 2**256 - 1, {'from': alice}) usdc.approve(homora, 2**256 - 1, {'from': alice}) usdc.approve(crusdc, 2**256 - 1, {'from': alice}) lp.approve(homora, 2**256 - 1, {'from': alice}) uniswap_spell = UniswapV2SpellV1.deploy(homora, werc20, router, {'from': admin}) # first time call to reduce gas uniswap_spell.getPair(usdt, usdc, {'from': admin}) ##################################################################################### print( '=========================================================================' ) print('Case 1.') prevABal = usdt.balanceOf(alice) prevBBal = usdc.balanceOf(alice) prevLPBal = lp.balanceOf(alice) prevLPBal_bank = lp.balanceOf(homora) prevLPBal_werc20 = lp.balanceOf(werc20) usdt_amt = 40000 * 10**6 # 40000 USDT usdc_amt = 50000 * 10**6 # 50000 USDC lp_amt = 1 * 10**7 borrow_usdt_amt = 1000 * 10**6 # 1000 USDT borrow_usdc_amt = 200 * 10**6 # 200 USDC tx = homora.execute( 0, uniswap_spell, uniswap_spell.addLiquidityWERC20.encode_input( usdt, # token 0 usdc, # token 1 [ usdt_amt, # supply USDT usdc_amt, # supply USDC lp_amt, # supply LP borrow_usdt_amt, # borrow USDT borrow_usdc_amt, # borrow USDC 0, # borrow LP tokens 0, # min USDT 0 ], # min USDC ), {'from': alice}) curABal = usdt.balanceOf(alice) curBBal = usdc.balanceOf(alice) curLPBal = lp.balanceOf(alice) curLPBal_bank = lp.balanceOf(homora) curLPBal_werc20 = lp.balanceOf(werc20) print('spell lp balance', lp.balanceOf(uniswap_spell)) print('Alice delta A balance', curABal - prevABal) print('Alice delta B balance', curBBal - prevBBal) print('add liquidity gas', tx.gas_used) print('bank lp balance', curLPBal_bank) _, _, _, usdtDebt, usdtDebtShare = homora.getBankInfo(usdt) _, _, _, usdcDebt, usdcDebtShare = homora.getBankInfo(usdc) print('bank usdt totalDebt', usdtDebt) print('bank usdt totalShare', usdtDebtShare) print('bank usdc totalDebt', usdcDebt) print('bank usdc totalShare', usdcDebtShare) print('bank prev LP balance', prevLPBal_bank) print('bank cur LP balance', curLPBal_bank) print('werc20 prev LP balance', prevLPBal_werc20) print('werc20 cur LP balance', curLPBal_werc20) # alice assert almostEqual(curABal - prevABal, -usdt_amt), 'incorrect USDT amt' assert almostEqual(curBBal - prevBBal, -usdc_amt), 'incorrect USDC amt' assert almostEqual(curLPBal - prevLPBal, -lp_amt), 'incorrect LP amt' # spell assert usdt.balanceOf(uniswap_spell) == 0, 'non-zero spell USDT balance' assert usdc.balanceOf(uniswap_spell) == 0, 'non-zero spell USDC balance' assert lp.balanceOf(uniswap_spell) == 0, 'non-zero spell LP balance' # debt assert usdtDebt == borrow_usdt_amt assert usdcDebt == borrow_usdc_amt ##################################################################################### print( '=========================================================================' ) print('Case 2.') # remove liquidity from the same position prevABal = usdt.balanceOf(alice) prevBBal = usdc.balanceOf(alice) prevLPBal = lp.balanceOf(alice) prevLPBal_bank = lp.balanceOf(homora) prevLPBal_werc20 = lp.balanceOf(werc20) _, _, _, collSize = homora.getPositionInfo(1) lp_take_amt = 2**256 - 1 # max lp_want = 1 * 10**5 usdt_repay = 2**256 - 1 # max usdc_repay = 2**256 - 1 # max tx = homora.execute( 1, uniswap_spell, uniswap_spell.removeLiquidityWERC20.encode_input( usdt, # token 0 usdc, # token 1 [ lp_take_amt, # take out LP tokens lp_want, # withdraw LP tokens to wallet usdt_repay, # repay USDT usdc_repay, # repay USDC 0, # repay LP 0, # min USDT 0 ], # min USDC ), {'from': alice}) curABal = usdt.balanceOf(alice) curBBal = usdc.balanceOf(alice) curLPBal = lp.balanceOf(alice) curLPBal_bank = lp.balanceOf(homora) curLPBal_werc20 = lp.balanceOf(werc20) print('spell lp balance', lp.balanceOf(uniswap_spell)) print('spell usdt balance', usdt.balanceOf(uniswap_spell)) print('spell usdc balance', usdc.balanceOf(uniswap_spell)) print('Alice delta A balance', curABal - prevABal) print('Alice delta B balance', curBBal - prevBBal) print('Alice delta LP balance', curLPBal - prevLPBal) print('remove liquidity gas', tx.gas_used) print('bank delta lp balance', curLPBal_bank - prevLPBal_bank) print('bank total lp balance', curLPBal_bank) _, _, _, usdtDebt, usdtDebtShare = homora.getBankInfo(usdt) _, _, _, usdcDebt, usdcDebtShare = homora.getBankInfo(usdc) print('bank usdt totalDebt', usdtDebt) print('bank usdt totalShare', usdtDebtShare) print('bank usdc totalDebt', usdcDebt) print('bank usdc totalShare', usdcDebtShare) print('LP want', lp_want) print('bank delta LP amount', curLPBal_bank - prevLPBal_bank) print('LP take amount', lp_take_amt) print('prev werc20 LP balance', prevLPBal_werc20) print('cur werc20 LP balance', curLPBal_werc20) print('coll size', collSize) # alice assert almostEqual(curLPBal - prevLPBal, lp_want), 'incorrect LP amt' # werc20 assert almostEqual(curLPBal_werc20 - prevLPBal_werc20, -collSize), 'incorrect werc20 LP amt' # spell assert usdt.balanceOf(uniswap_spell) == 0, 'non-zero spell USDT balance' assert usdc.balanceOf(uniswap_spell) == 0, 'non-zero spell USDC balance' assert lp.balanceOf(uniswap_spell) == 0, 'non-zero spell LP balance' # debt assert usdtDebt == 0, 'usdtDebt should be 0' assert usdcDebt == 0, 'usdcDebt should be 0' return tx
def main(): admin = accounts[0] alice = accounts[1] bob = accounts[2] dpi = interface.IERC20Ex('0x1494ca1f11d487c2bbe4543e90080aeba4ba3c2b') weth = interface.IERC20Ex('0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2') usdt = interface.IERC20Ex('0xdac17f958d2ee523a2206206994597c13d831ec7') lp = interface.IERC20Ex('0x4d5ef58aac27d99935e5b6b4a6778ff292059991') lp_usdt = interface.IERC20Ex('0x0d4a11d5eeaac28ec3f61d100daf4d40471f1852') crdpi = MockCErc20.deploy(dpi, {'from': admin}) crusdt = interface.ICErc20('0x797AAB1ce7c01eB727ab980762bA88e7133d2157') router = interface.IUniswapV2Router02( '0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D') staking = accounts.at('0xB93b505Ed567982E2b6756177ddD23ab5745f309', force=True) index = interface.IERC20Ex( interface.IStakingRewardsEx(staking).rewardsToken()) wstaking = WStakingRewards.deploy(staking, lp, index, {'from': admin}) werc20 = WERC20.deploy({'from': admin}) simple_oracle = SimpleOracle.deploy({'from': admin}) simple_oracle.setETHPx([dpi, weth, usdt], [2**112 * 100 // 700, 2**112, 2**112 // 700]) uniswap_oracle = UniswapV2Oracle.deploy(simple_oracle, {'from': admin}) core_oracle = CoreOracle.deploy({'from': admin}) oracle = ProxyOracle.deploy(core_oracle, {'from': admin}) oracle.setWhitelistERC1155([werc20, wstaking], True, {'from': admin}) core_oracle.setRoute( [dpi, weth, lp, usdt, lp_usdt], [ simple_oracle, simple_oracle, uniswap_oracle, simple_oracle, uniswap_oracle ], {'from': admin}, ) oracle.setOracles( [dpi, weth, lp, usdt, lp_usdt], [ [10000, 10000, 10000], [10000, 10000, 10000], [10000, 10000, 10000], [10000, 10000, 10000], [10000, 10000, 10000], ], {'from': admin}, ) homora = HomoraBank.deploy({'from': admin}) homora.initialize(oracle, 1000, {'from': admin}) # 10% fee setup_bank_hack(homora) homora.addBank(dpi, crdpi, {'from': admin}) homora.addBank(usdt, crusdt, {'from': admin}) # setup initial funds to alice mint_tokens(dpi, alice) mint_tokens(weth, alice) mint_tokens(usdt, alice) mint_tokens(dpi, crdpi) # check alice's funds print(f'Alice dpi balance {dpi.balanceOf(alice)}') print(f'Alice weth balance {weth.balanceOf(alice)}') # Steal some LP from the staking pool mint_tokens(lp, alice) mint_tokens(lp, bob) mint_tokens(lp_usdt, alice) mint_tokens(lp_usdt, bob) # set approval dpi.approve(homora, 2**256 - 1, {'from': alice}) dpi.approve(crdpi, 2**256 - 1, {'from': alice}) weth.approve(homora, 2**256 - 1, {'from': alice}) usdt.approve(homora, 2**256 - 1, {'from': alice}) usdt.approve(crusdt, 2**256 - 1, {'from': alice}) lp.approve(homora, 2**256 - 1, {'from': alice}) lp.approve(staking, 2**256 - 1, {'from': bob}) uniswap_spell = UniswapV2SpellV1.deploy(homora, werc20, router, {'from': admin}) # first time call to reduce gas uniswap_spell.getPair(weth, dpi, {'from': admin}) ##################################################################################### print( '=========================================================================' ) print('Case 1. add liquidity first time') prevABal = dpi.balanceOf(alice) prevBBal = weth.balanceOf(alice) prevLPBal = lp.balanceOf(alice) prevLPBal_bank = lp.balanceOf(homora) prevLPBal_staking = lp.balanceOf(staking) if interface.IUniswapV2Pair(lp).token0() == dpi: prevARes, prevBRes, _ = interface.IUniswapV2Pair(lp).getReserves() else: prevBRes, prevARes, _ = interface.IUniswapV2Pair(lp).getReserves() dpi_amt = 10 * 10**18 weth_amt = 10**18 lp_amt = 0 borrow_dpi_amt = 10**18 borrow_weth_amt = 0 real_dpi_borrow_amt = borrow_dpi_amt tx = homora.execute( 0, uniswap_spell, uniswap_spell.addLiquidityWStakingRewards.encode_input( dpi, # token 0 weth, # token 1 [ dpi_amt, # supply DPI weth_amt, # supply WETH lp_amt, # supply LP borrow_dpi_amt, # borrow DPI borrow_weth_amt, # borrow WETH 0, # borrow LP tokens 0, # min DPI 0 ], # min WETH wstaking, ), {'from': alice}) curABal = dpi.balanceOf(alice) curBBal = weth.balanceOf(alice) curLPBal = lp.balanceOf(alice) curLPBal_bank = lp.balanceOf(homora) curLPBal_staking = lp.balanceOf(staking) if interface.IUniswapV2Pair(lp).token0() == dpi: curARes, curBRes, _ = interface.IUniswapV2Pair(lp).getReserves() else: curBRes, curARes, _ = interface.IUniswapV2Pair(lp).getReserves() print('spell lp balance', lp.balanceOf(uniswap_spell)) print('Alice delta A balance', curABal - prevABal) print('Alice delta B balance', curBBal - prevBBal) print('add liquidity gas', tx.gas_used) print('bank lp balance', curLPBal_bank) _, _, _, totalDebt, totalShare = homora.getBankInfo(dpi) print('bank dpi totalDebt', totalDebt) print('bank dpi totalShare', totalShare) print('bank prev LP balance', prevLPBal_bank) print('bank cur LP balance', curLPBal_bank) print('staking prev LP balance', prevLPBal_staking) print('staking cur LP balance', curLPBal_staking) print('prev dpi res', prevARes) print('cur dpi res', curARes) print('prev weth res', prevBRes) print('cur weth res', curBRes) # alice assert almostEqual(curABal - prevABal, -dpi_amt), 'incorrect DPI amt' assert almostEqual(curBBal - prevBBal, -weth_amt), 'incorrect WETH amt' assert curLPBal - prevLPBal == -lp_amt, 'incorrect LP amt' # spell assert dpi.balanceOf(uniswap_spell) == 0, 'non-zero spell DPI balance' assert weth.balanceOf(uniswap_spell) == 0, 'non-zero spell WETH balance' assert lp.balanceOf(uniswap_spell) == 0, 'non-zero spell LP balance' assert totalDebt == borrow_dpi_amt # check balance and pool reserves assert curABal - prevABal - borrow_dpi_amt == - \ (curARes - prevARes), 'not all DPI tokens go to LP pool' assert curBBal - prevBBal - borrow_weth_amt == - \ (curBRes - prevBRes), 'not all WETH tokens go to LP pool' _, _, collId, collSize = homora.getPositionInfo(1) print('collSize', collSize) # staking directly prevIndex = index.balanceOf(bob) print('bob lp balance', interface.IERC20Ex(lp).balanceOf(bob)) tx = interface.IStakingRewards(staking).stake(collSize, {'from': bob}) chain.sleep(20000) prevAliceIndexBalance = index.balanceOf(alice) print('Alice index balance', prevAliceIndexBalance) ##################################################################################### print( '=========================================================================' ) print('Case 2. add liquidity (failed tx desired)') usdt_amt = 10 * 10**6 weth_amt = 10**18 lp_amt = 0 borrow_usdt_amt = 0 borrow_weth_amt = 0 try: tx = homora.execute( 1, uniswap_spell, uniswap_spell.addLiquidityWStakingRewards.encode_input( usdt, # token 0 weth, # token 1 [ usdt_amt, # supply USDT weth_amt, # supply WETH lp_amt, # supply LP borrow_usdt_amt, # borrow USDT borrow_weth_amt, # borrow WETH 0, # borrow LP tokens 0, # min USDT 0 ], # min WETH wstaking, ), {'from': alice}) except VirtualMachineError: pass ##################################################################################### print( '=========================================================================' ) print('Case 3. remove liquidity (failed tx desired)') lp_take_amt = collSize lp_want = 0 usdt_repay = 0 weth_repay = 0 try: tx = homora.execute( 1, uniswap_spell, uniswap_spell.removeLiquidityWStakingRewards.encode_input( usdt, # token 0 weth, # token 1 [ lp_take_amt, # take out LP tokens lp_want, # withdraw LP tokens to wallet usdt_repay, # repay USDT weth_repay, # repay WETH 0, # repay LP tokens 0, # min USDT 0 ], # min WETH wstaking, ), {'from': alice}) except VirtualMachineError: pass ##################################################################################### print( '=========================================================================' ) print('Case 4. remove liquidity') prevABal = dpi.balanceOf(alice) prevBBal = weth.balanceOf(alice) prevLPBal = lp.balanceOf(alice) prevLPBal_bank = lp.balanceOf(homora) prevLPBal_staking = lp.balanceOf(staking) prevETHBal = alice.balance() if interface.IUniswapV2Pair(lp).token0() == dpi: prevARes, prevBRes, _ = interface.IUniswapV2Pair(lp).getReserves() else: prevBRes, prevARes, _ = interface.IUniswapV2Pair(lp).getReserves() lp_take_amt = collSize lp_want = 0 dpi_repay = 2**256 - 1 weth_repay = 0 tx = homora.execute( 1, uniswap_spell, uniswap_spell.removeLiquidityWStakingRewards.encode_input( dpi, # token 0 weth, # token 1 [ lp_take_amt, # take out LP tokens lp_want, # withdraw LP tokens to wallet dpi_repay, # repay DPI weth_repay, # repay WETH 0, # repay LP tokens 0, # min DPI 0 ], # min WETH wstaking, ), {'from': alice}) curABal = dpi.balanceOf(alice) curBBal = weth.balanceOf(alice) curLPBal = lp.balanceOf(alice) curLPBal_bank = lp.balanceOf(homora) curLPBal_staking = lp.balanceOf(staking) curETHBal = alice.balance() if interface.IUniswapV2Pair(lp).token0() == dpi: curARes, curBRes, _ = interface.IUniswapV2Pair(lp).getReserves() else: curBRes, curARes, _ = interface.IUniswapV2Pair(lp).getReserves() print('spell lp balance', lp.balanceOf(uniswap_spell)) print('Alice delta A balance', curABal - prevABal) print('Alice delta B balance', curBBal - prevBBal) print('add liquidity gas', tx.gas_used) print('bank lp balance', curLPBal_bank) _, _, _, totalDebt, totalShare = homora.getBankInfo(dpi) print('bank dpi totalDebt', totalDebt) print('bank dpi totalShare', totalShare) print('bank prev LP balance', prevLPBal_bank) print('bank cur LP balance', curLPBal_bank) print('wstaking prev LP balance', prevLPBal_staking) print('wstaking cur LP balance', curLPBal_staking) print('prev dpi res', prevARes) print('cur dpi res', curARes) print('prev weth res', prevBRes) print('cur weth res', curBRes) # alice assert almostEqual(curBBal - prevBBal, 0), 'incorrect WETH amt' assert almostEqual(curLPBal - prevLPBal, lp_want), 'incorrect LP amt' # staking assert almostEqual(curLPBal_staking - prevLPBal_staking, -lp_take_amt), 'incorrect staking LP amt' # spell assert dpi.balanceOf(uniswap_spell) == 0, 'non-zero spell DPI balance' assert weth.balanceOf(uniswap_spell) == 0, 'non-zero spell WETH balance' assert lp.balanceOf(uniswap_spell) == 0, 'non-zero spell LP balance' # check balance and pool reserves assert almostEqual(curABal - prevABal + real_dpi_borrow_amt, -(curARes - prevARes)), 'inconsistent DPI from withdraw' assert almostEqual(curBBal - prevBBal, 0), 'inconsistent WETH from withdraw' assert almostEqual(curETHBal - prevETHBal + weth_repay, -(curBRes - prevBRes)), 'inconsistent ETH from withdraw' curAliceIndexBalance = index.balanceOf(alice) print('Alice index balance', curAliceIndexBalance) receivedIndex = curAliceIndexBalance - prevAliceIndexBalance print('received index', receivedIndex) # check with staking directly tx = interface.IStakingRewards(staking).getReward({'from': bob}) receivedIndexFromStaking = index.balanceOf(bob) - prevIndex print('receivedIndexFromStaking', receivedIndexFromStaking) assert almostEqual(receivedIndex, receivedIndexFromStaking)
def main(): deployer = accounts.at('0xB593d82d53e2c187dc49673709a6E9f806cdC835', force=True) # deployer = accounts.load('gh') werc20 = WERC20.at('0xe28D9dF7718b0b5Ba69E01073fE82254a9eD2F98') wmas = WMasterChef.at('0x373ae78a14577682591E088F2E78EF1417612c68') wliq = WLiquidityGauge.at('0xfdB4f97953150e47C8606758C13e70b5a789a7ec') wsindex = WStakingRewards.at('0x713df2DDDA9C7d7bDa98A9f8fCd82c06c50fbd90') wsperp = WStakingRewards.at('0xC4635854480ffF80F742645da0310e9e59795c63') uni_kp3r_oracle = ERC20KP3ROracle.at('0x8E2A3777AB22e1c5f6d1fF2BcC6C4aA6aB1DeA14') sushi_kp3r_oracle = ERC20KP3ROracle.deploy( '0xf67Ab1c914deE06Ba0F264031885Ea7B276a7cDa', {'from': deployer}) core_oracle = CoreOracle.at('0x1E5BDdd0cDF8839d6b27b34927869eF0AD7bf692') uni_oracle = UniswapV2Oracle.at('0x910aD02D355c2966e8dD8E32C890cD50DB29C3B9') bal_oracle = BalancerPairOracle.at('0x8F93B0AA2643bf74ab38d6a5910fA82D2da02134') crv_oracle = CurveOracle.at('0x04DE0E42B3b0483248deafE86C4F5428613b76Ff') proxy_oracle = ProxyOracle.at('0x43c425fB2b00a991A51b18c217D749E393bF1AB2') # pair token with oracle from .tokens import Tokens token_oracle_settings = [ # base tokens [Tokens.weth, uni_kp3r_oracle], [Tokens.dai, uni_kp3r_oracle], [Tokens.usdc, uni_kp3r_oracle], [Tokens.usdt, uni_kp3r_oracle], [Tokens.dpi, uni_kp3r_oracle], [Tokens.yfi, sushi_kp3r_oracle], [Tokens.perp, uni_kp3r_oracle], [Tokens.snx, sushi_kp3r_oracle], [Tokens.susd, sushi_kp3r_oracle], [Tokens.uni, uni_kp3r_oracle], [Tokens.sushi, sushi_kp3r_oracle], # lp tokens [Tokens.uni_eth_yfi, uni_oracle], [Tokens.sushi_eth_yfi, uni_oracle], [Tokens.uni_eth_dpi, uni_oracle], [Tokens.crv_3pool, crv_oracle], [Tokens.sushi_eth_dpi, uni_oracle], [Tokens.uni_eth_snx, uni_oracle], [Tokens.uni_eth_susd, uni_oracle], [Tokens.sushi_eth_susd, uni_oracle], [Tokens.sushi_eth_snx, uni_oracle], [Tokens.crv_susd, crv_oracle], [Tokens.sushi_eth_sushi, uni_oracle], [Tokens.uni_eth_uni, uni_oracle], [Tokens.bal_perp_usdc, bal_oracle], ] token_list, oracle_list = zip(*token_oracle_settings) # re-route to new uniswap oracle core_oracle.setRoute(token_list, oracle_list, {'from': deployer}) # re-set oracles oracle_params = [ # base tokens [Tokens.weth, [17158, 5828, 12500]], [Tokens.dai, [10790, 9268, 12500]], [Tokens.usdc, [10651, 9389, 12500]], [Tokens.usdt, [10743, 9308, 12500]], [Tokens.dpi, [16195, 6175, 12500]], [Tokens.yfi, [29155, 3430, 12500]], [Tokens.perp, [20042, 4989, 12500]], [Tokens.snx, [18162, 5506, 12500]], [Tokens.susd, [12129, 8245, 12500]], [Tokens.uni, [16022, 6241, 12500]], [Tokens.sushi, [19418, 5150, 12500]], # lp tokens [Tokens.uni_eth_dpi, [17158, 5828, 12500]], [Tokens.uni_eth_yfi, [29155, 3430, 12500]], [Tokens.uni_eth_snx, [18162, 5506, 12500]], [Tokens.uni_eth_susd, [17158, 5828, 12500]], [Tokens.uni_eth_uni, [17158, 5828, 12500]], [Tokens.sushi_eth_dpi, [17158, 5828, 12500]], [Tokens.sushi_eth_yfi, [29155, 3430, 12500]], [Tokens.sushi_eth_snx, [18162, 5506, 12500]], [Tokens.sushi_eth_susd, [17158, 5828, 12500]], [Tokens.sushi_eth_sushi, [19418, 5150, 12500]], [Tokens.bal_perp_usdc, [20042, 4989, 12500]], [Tokens.crv_3pool, [10790, 9268, 12500]], [Tokens.crv_susd, [12129, 8245, 12500]], ] token_list_2, param_list = zip(*oracle_params) proxy_oracle.setOracles(token_list_2, param_list, {'from': deployer}) print('DONE') ########################################################### # test spells (UNCOMMENT TO TEST) bank = HomoraBank.at('0x5f5Cd91070960D13ee549C9CC47e7a4Cd00457bb') uniswap_spell = UniswapV2SpellV1.at('0xc671B7251a789de0835a2fa33c83c8D4afB39092') sushiswap_spell = SushiswapSpellV1.at('0x21Fa95485f4571A3a0d0c396561cF4D8D13D445d') balancer_spell = BalancerSpellV1.at('0x15B79c184A6a8E19a4CA1F637081270343E4D15D') curve_spell = CurveSpellV1.at('0x42C750024E02816eE32EB2eB4DA79ff5BF343D30')
def main(): deployer = accounts.at('0xB593d82d53e2c187dc49673709a6E9f806cdC835', force=True) # deployer = accounts.load('gh') werc20 = WERC20.at('0xe28D9dF7718b0b5Ba69E01073fE82254a9eD2F98') wmas = WMasterChef.at('0x373ae78a14577682591E088F2E78EF1417612c68') wliq = WLiquidityGauge.at('0xfdB4f97953150e47C8606758C13e70b5a789a7ec') wsindex = WStakingRewards.at('0x713df2DDDA9C7d7bDa98A9f8fCd82c06c50fbd90') wsperp = WStakingRewards.at('0xC4635854480ffF80F742645da0310e9e59795c63') kp3r_oracle = ERC20KP3ROracle.at('0x8E2A3777AB22e1c5f6d1fF2BcC6C4aA6aB1DeA14') core_oracle = CoreOracle.at('0x1E5BDdd0cDF8839d6b27b34927869eF0AD7bf692') uni_oracle = UniswapV2Oracle.deploy(core_oracle, {'from': deployer}) bal_oracle = BalancerPairOracle.at('0x8F93B0AA2643bf74ab38d6a5910fA82D2da02134') crv_oracle = CurveOracle.at('0x04DE0E42B3b0483248deafE86C4F5428613b76Ff') proxy_oracle = ProxyOracle.deploy(core_oracle, {'from': deployer}) # re-route to new uniswap oracle core_oracle.setRoute([ '0x0bc529c00C6401aEF6D220BE8C6Ea1667F6Ad93e', # YFI '0xA478c2975Ab1Ea89e8196811F51A7B7Ade33eB11', # UNI DAI-WETH '0x0d4a11d5EEaaC28EC3F61d100daF4d40471f1852', # UNI WETH-USDT '0xB4e16d0168e52d35CaCD2c6185b44281Ec28C9Dc', # UNI USDC-WETH '0xBb2b8038a1640196FbE3e38816F3e67Cba72D940', # UNI WBTC-WETH '0x2fDbAdf3C4D5A8666Bc06645B8358ab803996E28', # UNI WETH-YFI '0x4d5ef58aAc27d99935E5b6B4A6778ff292059991', # UNI DPI-WETH '0x06da0fd433C1A5d7a4faa01111c044910A184553', # SUSHI WETH-USDT '0x088ee5007C98a9677165D78dD2109AE4a3D04d0C', # SUSHI WETH-YFI '0x34b13F8CD184F55d0Bd4Dd1fe6C07D46f245c7eD', # SUSHI DPI-WETH ], [ kp3r_oracle, uni_oracle, uni_oracle, uni_oracle, uni_oracle, uni_oracle, uni_oracle, uni_oracle, uni_oracle, uni_oracle, ], {'from': deployer}) # re-set oracles proxy_oracle.setOracles([ '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', # WETH '0x6B175474E89094C44Da98b954EedeAC495271d0F', # DAI '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', # USDC '0xdAC17F958D2ee523a2206206994597C13D831ec7', # USDT '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', # WBTC '0x1494CA1F11D487c2bBe4543E90080AeBa4BA3C2b', # DPI '0x0bc529c00C6401aEF6D220BE8C6Ea1667F6Ad93e', # YFI '0xA478c2975Ab1Ea89e8196811F51A7B7Ade33eB11', # UNI DAI-WETH '0x0d4a11d5EEaaC28EC3F61d100daF4d40471f1852', # UNI WETH-USDT '0xB4e16d0168e52d35CaCD2c6185b44281Ec28C9Dc', # UNI USDC-WETH '0xBb2b8038a1640196FbE3e38816F3e67Cba72D940', # UNI WBTC-WETH '0x2fDbAdf3C4D5A8666Bc06645B8358ab803996E28', # UNI WETH-YFI '0x4d5ef58aAc27d99935E5b6B4A6778ff292059991', # UNI DPI-WETH '0x06da0fd433C1A5d7a4faa01111c044910A184553', # SUSHI WETH-USDT '0x088ee5007C98a9677165D78dD2109AE4a3D04d0C', # SUSHI WETH-YFI '0x34b13F8CD184F55d0Bd4Dd1fe6C07D46f245c7eD', # SUSHI DPI-WETH '0x8b6e6E7B5b3801FEd2CaFD4b22b8A16c2F2Db21a', # BAL WETH-DAI 80-20 '0xF54025aF2dc86809Be1153c1F20D77ADB7e8ecF4', # BAL PERP-USDC 80-20 '0x6c3F90f043a72FA612cbac8115EE7e52BDe6E490', # CRV 3-POOL ], [ [14350, 6970, 10250], # WETH [10840, 9230, 10250], # DAI [10840, 9230, 10250], # USDC [10840, 9230, 10250], # USDT [14350, 6970, 10250], # WBTC [50000, 0, 10250], # DPI [50000, 0, 10250], # YFI [50000, 6970, 10250], # UNI DAI-WETH [50000, 6970, 10250], # UNI WETH-USDT [50000, 6970, 10250], # UNI USDC-WETH [50000, 6970, 10250], # UNI WBTC-WETH [50000, 6970, 10250], # UNI WETH-YFI [50000, 6970, 10250], # UNI DPI-WETH [50000, 6970, 10250], # SUSHI WETH-USDT [50000, 6970, 10250], # SUSHI WETH-YFI [50000, 6970, 10250], # SUSHI DPI-WETH [50000, 6970, 10250], # BAL WETH-DAI 80-20 [50000, 0, 10250], # BAL PERP-USDC 80-20 [50000, 9230, 10250], # CRV 3-POOL ], {'from': deployer}) proxy_oracle.setWhitelistERC1155( [werc20, wmas, wliq, wsindex, wsperp], True, {'from': deployer}, ) bank_impl = HomoraBank.deploy({'from': deployer}) proxy_admin = Contract.from_explorer('0x090eCE252cEc5998Db765073D07fac77b8e60CB2') bank = Contract.from_explorer('0x5f5Cd91070960D13ee549C9CC47e7a4Cd00457bb') proxy_admin.upgrade(bank, bank_impl, {'from': deployer}) bank.setOracle(proxy_oracle, {'from': deployer}) uniswap_spell = UniswapV2SpellV1.deploy( bank, werc20, '0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D', {'from': deployer}, ) sushiswap_spell = SushiswapSpellV1.deploy( bank, werc20, '0xd9e1cE17f2641f24aE83637ab66a2cca9C378B9F', wmas, {'from': deployer}, ) balancer_spell = BalancerSpellV1.at('0x15B79c184A6a8E19a4CA1F637081270343E4D15D') curve_spell = CurveSpellV1.deploy( bank, werc20, '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', wliq, {'from': deployer}, ) print('DONE')
def main(): admin = accounts[0] alice = accounts[1] bob = accounts[2] dpi = interface.IERC20Ex('0x1494ca1f11d487c2bbe4543e90080aeba4ba3c2b') weth = interface.IERC20Ex('0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2') lp = interface.IERC20Ex('0x4d5ef58aac27d99935e5b6b4a6778ff292059991') crdpi = MockCErc20.deploy(dpi, {'from': admin}) router = interface.IUniswapV2Router02( '0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D') staking = accounts.at('0xB93b505Ed567982E2b6756177ddD23ab5745f309', force=True) index = interface.IERC20Ex(interface.IStakingRewardsEx(staking).rewardsToken()) wstaking = WStakingRewards.deploy(staking, lp, index, {'from': admin}) werc20 = WERC20.deploy({'from': admin}) simple_oracle = SimpleOracle.deploy({'from': admin}) simple_oracle.setETHPx([dpi, weth], [2**112 * 100 // 700, 2**112]) uniswap_oracle = UniswapV2Oracle.deploy(simple_oracle, {'from': admin}) core_oracle = CoreOracle.deploy({'from': admin}) oracle = ProxyOracle.deploy(core_oracle, {'from': admin}) oracle.setWhitelistERC1155([werc20, wstaking], True, {'from': admin}) core_oracle.setRoute( [dpi, weth, lp], [simple_oracle, simple_oracle, uniswap_oracle], {'from': admin}, ) oracle.setOracles( [dpi, weth, lp], [ [10000, 10000, 10000], [10000, 10000, 10000], [10000, 10000, 10000], ], {'from': admin}, ) homora = HomoraBank.deploy({'from': admin}) homora.initialize(oracle, 1000, {'from': admin}) # 10% fee setup_bank_hack(homora) homora.addBank(dpi, crdpi, {'from': admin}) # setup initial funds to alice mint_tokens(dpi, alice) mint_tokens(weth, alice) mint_tokens(dpi, crdpi) # check alice's funds print(f'Alice dpi balance {dpi.balanceOf(alice)}') print(f'Alice weth balance {weth.balanceOf(alice)}') # Steal some LP from the staking pool mint_tokens(lp, alice) mint_tokens(lp, bob) # set approval dpi.approve(homora, 2**256-1, {'from': alice}) dpi.approve(crdpi, 2**256-1, {'from': alice}) weth.approve(homora, 2**256-1, {'from': alice}) lp.approve(homora, 2**256-1, {'from': alice}) lp.approve(staking, 2**256-1, {'from': bob}) uniswap_spell = UniswapV2SpellV1.deploy( homora, werc20, router, {'from': admin}) # first time call to reduce gas uniswap_spell.getPair(weth, dpi, {'from': admin}) # whitelist spell in bank homora.setWhitelistSpells([uniswap_spell], [True], {'from': admin}) # whitelist token in bank homora.setWhitelistTokens([dpi], [True], {'from': admin}) # whitelist lp in spell uniswap_spell.setWhitelistLPTokens([lp], [True], {'from': admin}) ##################################################################################### print('=========================================================================') print('Case 1. add liquidity') prevABal = dpi.balanceOf(alice) prevBBal = weth.balanceOf(alice) prevLPBal = lp.balanceOf(alice) prevLPBal_bank = lp.balanceOf(homora) prevLPBal_staking = lp.balanceOf(staking) if interface.IUniswapV2Pair(lp).token0() == dpi: prevARes, prevBRes, _ = interface.IUniswapV2Pair(lp).getReserves() else: prevBRes, prevARes, _ = interface.IUniswapV2Pair(lp).getReserves() dpi_amt = 10 * 10**18 weth_amt = 10**18 lp_amt = 0 borrow_dpi_amt = 10**18 borrow_weth_amt = 0 tx = homora.execute( 0, uniswap_spell, uniswap_spell.addLiquidityWStakingRewards.encode_input( dpi, # token 0 weth, # token 1 [dpi_amt, # supply DPI weth_amt, # supply WETH lp_amt, # supply LP borrow_dpi_amt, # borrow DPI borrow_weth_amt, # borrow WETH 0, # borrow LP tokens 0, # min DPI 0], # min WETH wstaking, ), {'from': alice} ) curABal = dpi.balanceOf(alice) curBBal = weth.balanceOf(alice) curLPBal = lp.balanceOf(alice) curLPBal_bank = lp.balanceOf(homora) curLPBal_staking = lp.balanceOf(staking) if interface.IUniswapV2Pair(lp).token0() == dpi: curARes, curBRes, _ = interface.IUniswapV2Pair(lp).getReserves() else: curBRes, curARes, _ = interface.IUniswapV2Pair(lp).getReserves() print('spell lp balance', lp.balanceOf(uniswap_spell)) print('Alice delta A balance', curABal - prevABal) print('Alice delta B balance', curBBal - prevBBal) print('add liquidity gas', tx.gas_used) print('bank lp balance', curLPBal_bank) _, _, _, totalDebt, totalShare = homora.getBankInfo(dpi) print('bank dpi totalDebt', totalDebt) print('bank dpi totalShare', totalShare) print('bank prev LP balance', prevLPBal_bank) print('bank cur LP balance', curLPBal_bank) print('staking prev LP balance', prevLPBal_staking) print('staking cur LP balance', curLPBal_staking) print('prev dpi res', prevARes) print('cur dpi res', curARes) print('prev weth res', prevBRes) print('cur weth res', curBRes) # alice assert almostEqual(curABal - prevABal, -dpi_amt), 'incorrect DPI amt' assert almostEqual(curBBal - prevBBal, -weth_amt), 'incorrect WETH amt' assert curLPBal - prevLPBal == -lp_amt, 'incorrect LP amt' # spell assert dpi.balanceOf(uniswap_spell) == 0, 'non-zero spell DPI balance' assert weth.balanceOf(uniswap_spell) == 0, 'non-zero spell WETH balance' assert lp.balanceOf(uniswap_spell) == 0, 'non-zero spell LP balance' assert totalDebt == borrow_dpi_amt # check balance and pool reserves assert curABal - prevABal - borrow_dpi_amt == - \ (curARes - prevARes), 'not all DPI tokens go to LP pool' assert curBBal - prevBBal - borrow_weth_amt == - \ (curBRes - prevBRes), 'not all WETH tokens go to LP pool' # ##################################################################################### print('=========================================================================') print('Case 2. harvest first time') prevIndexBalance = index.balanceOf(alice) print('Alice INDEX balance before harvest', prevIndexBalance) _, _, collId, collSize = homora.getPositionInfo(1) print('collSize', collSize) # staking directly prevIndex = index.balanceOf(bob) print('bob lp balance', interface.IERC20Ex(lp).balanceOf(bob)) tx = interface.IStakingRewards(staking).stake(collSize, {'from': bob}) chain.sleep(20000) tx = homora.execute( 1, uniswap_spell, uniswap_spell.harvestWStakingRewards.encode_input(wstaking), {'from': alice} ) print('tx gas used', tx.gas_used) curIndexBalance = index.balanceOf(alice) print('Alice INDEX balance after harvest', curIndexBalance) receivedIndex = curIndexBalance - prevIndexBalance # check with staking directly tx = interface.IStakingRewards(staking).getReward({'from': bob}) receivedIndexFromStaking = index.balanceOf(bob) - prevIndex print('receivedIndexFromStaking', receivedIndexFromStaking) assert almostEqual(receivedIndex, receivedIndexFromStaking) # ##################################################################################### print('=========================================================================') print('Case 3. harvest second time') prevIndexBalance = index.balanceOf(alice) print('Alice INDEX balance before harvest', prevIndexBalance) prevIndex = index.balanceOf(bob) print('bob lp balance', interface.IERC20Ex(lp).balanceOf(bob)) chain.sleep(20000) tx = homora.execute( 1, uniswap_spell, uniswap_spell.harvestWStakingRewards.encode_input(wstaking), {'from': alice} ) print('tx gas used', tx.gas_used) curIndexBalance = index.balanceOf(alice) print('Alice INDEX balance after harvest', curIndexBalance) receivedIndex = curIndexBalance - prevIndexBalance # check with staking directly tx = interface.IStakingRewards(staking).getReward({'from': bob}) receivedIndexFromStaking = index.balanceOf(bob) - prevIndex print('receivedIndexFromStaking', receivedIndexFromStaking) assert almostEqual(receivedIndex, receivedIndexFromStaking)
def main(): admin = accounts[0] alice = accounts[1] usdt = interface.IERC20Ex('0xdAC17F958D2ee523a2206206994597C13D831ec7') usdc = interface.IERC20Ex('0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48') lp = interface.IERC20Ex('0x3041cbd36888becc7bbcbc0045e3b1f144466f5f') crusdt = interface.ICErc20('0x797AAB1ce7c01eB727ab980762bA88e7133d2157') crusdc = interface.ICErc20('0x44fbebd2f576670a6c33f6fc0b00aa8c5753b322') router = interface.IUniswapV2Router02( '0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D') werc20 = WERC20.deploy({'from': admin}) simple_oracle = SimpleOracle.deploy({'from': admin}) simple_oracle.setETHPx([usdt, usdc], [ 8343331721347310729683379470025550036595362, 8344470555541464992529317899641128796042472 ]) uniswap_oracle = UniswapV2Oracle.deploy(simple_oracle, {'from': admin}) oracle = ProxyOracle.deploy({'from': admin}) oracle.setWhitelistERC1155([werc20], True, {'from': admin}) oracle.setOracles( [ '0xdAC17F958D2ee523a2206206994597C13D831ec7', # USDT '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', # USDC '0x3041cbd36888becc7bbcbc0045e3b1f144466f5f', # USDT-USDC ], [ [simple_oracle, 10000, 10000, 10000], [simple_oracle, 10000, 10000, 10000], [uniswap_oracle, 10000, 10000, 10000], ], {'from': admin}, ) # initialize homora = HomoraBank.deploy({'from': admin}) homora.initialize(oracle, 1000, {'from': admin}) # 10% fee setup_bank_hack(homora) # add bank homora.addBank(usdt, crusdt, {'from': admin}) homora.addBank(usdc, crusdc, {'from': admin}) # setup initial funds 10^6 USDT + 10^6 USDC to alice setup_transfer( usdt, accounts.at('0xbe0eb53f46cd790cd13851d5eff43d12404d33e8', force=True), alice, 10**6 * 10**6) setup_transfer( usdc, accounts.at('0xa191e578a6736167326d05c119ce0c90849e84b7', force=True), alice, 10**6 * 10**6) # setup initial funds 10^6 USDT + 10^6 USDC to homora bank setup_transfer( usdt, accounts.at('0xbe0eb53f46cd790cd13851d5eff43d12404d33e8', force=True), homora, 10**6 * 10**6) setup_transfer( usdc, accounts.at('0x397ff1542f962076d0bfe58ea045ffa2d347aca0', force=True), homora, 10**6 * 10**6) # check alice's funds print(f'Alice usdt balance {usdt.balanceOf(alice)}') print(f'Alice usdc balance {usdc.balanceOf(alice)}') # steal some LP from the staking pool lp.transfer( alice, 1 * 10**8, { 'from': accounts.at('0x85af1678527f63eb6492ab158ed5d2a94b8732c0', force=True) }) # set approval usdt.approve(homora, 2**256 - 1, {'from': alice}) usdt.approve(crusdt, 2**256 - 1, {'from': alice}) usdc.approve(homora, 2**256 - 1, {'from': alice}) usdc.approve(crusdc, 2**256 - 1, {'from': alice}) lp.approve(homora, 2**256 - 1, {'from': alice}) uniswap_spell = UniswapV2SpellV1.deploy(homora, werc20, router, {'from': admin}) # first time call to reduce gas uniswap_spell.getPair(usdt, usdc, {'from': admin}) ##################################################################################### # add liquidity print( '=========================================================================' ) print('Case 1.') prevABal = usdt.balanceOf(alice) prevBBal = usdc.balanceOf(alice) prevLPBal = lp.balanceOf(alice) prevLPBal_bank = lp.balanceOf(homora) prevLPBal_werc20 = lp.balanceOf(werc20) if interface.IUniswapV2Pair(lp).token0() == usdt: prevARes, prevBRes, _ = interface.IUniswapV2Pair(lp).getReserves() else: prevBRes, prevARes, _ = interface.IUniswapV2Pair(lp).getReserves() usdt_amt = 40000 * 10**6 usdc_amt = 50000 * 10**6 lp_amt = 1 * 10**7 borrow_usdt_amt = 1000 * 10**6 borrow_usdc_amt = 200 * 10**6 tx = homora.execute( 0, uniswap_spell, uniswap_spell.addLiquidity.encode_input( usdt, # token 0 usdc, # token 1 [ usdt_amt, # supply USDT usdc_amt, # supply USDC lp_amt, # supply LP borrow_usdt_amt, # borrow USDT borrow_usdc_amt, # borrow USDC 0, # borrow 0 LP tokens 0, # min USDT 0 ], # min USDC ), {'from': alice}) position_id = tx.return_value print('position_id', position_id) curABal = usdt.balanceOf(alice) curBBal = usdc.balanceOf(alice) curLPBal = lp.balanceOf(alice) curLPBal_bank = lp.balanceOf(homora) curLPBal_werc20 = lp.balanceOf(werc20) if interface.IUniswapV2Pair(lp).token0() == usdt: curARes, curBRes, _ = interface.IUniswapV2Pair(lp).getReserves() else: curBRes, curARes, _ = interface.IUniswapV2Pair(lp).getReserves() print('spell lp balance', lp.balanceOf(uniswap_spell)) print('Alice delta A balance', curABal - prevABal) print('Alice delta B balance', curBBal - prevBBal) print('add liquidity gas', tx.gas_used) print('bank lp balance', curLPBal_bank) _, _, _, usdtDebt, usdtDebtShare = homora.getBankInfo(usdt) _, _, _, usdcDebt, usdcDebtShare = homora.getBankInfo(usdc) print('bank usdt debt', usdtDebt) print('bank usdt debt share', usdtDebtShare) print('bank usdc debt', usdcDebt) print('bank usdc debt share', usdcDebtShare) print('bank prev LP balance', prevLPBal_bank) print('bank cur LP balance', curLPBal_bank) print('werc20 prev LP balance', prevLPBal_werc20) print('werc20 cur LP balance', curLPBal_werc20) print('prev usdt res', prevARes) print('cur usdt res', curARes) print('prev usdc res', prevBRes) print('cur usdc res', curBRes) # alice assert almostEqual(curABal - prevABal, -usdt_amt), 'incorrect USDT amt' assert almostEqual(curBBal - prevBBal, -usdc_amt), 'incorrect USDC amt' assert curLPBal - prevLPBal == -lp_amt, 'incorrect LP amt' # spell assert usdt.balanceOf(uniswap_spell) == 0, 'non-zero spell USDT balance' assert usdc.balanceOf(uniswap_spell) == 0, 'non-zero spell USDC balance' assert lp.balanceOf(uniswap_spell) == 0, 'non-zero spell LP balance' assert usdtDebt == borrow_usdt_amt assert usdcDebt == borrow_usdc_amt # check balance and pool reserves assert curABal - prevABal - borrow_usdt_amt == - \ (curARes - prevARes), 'not all USDT tokens go to LP pool' assert curBBal - prevBBal - borrow_usdc_amt == - \ (curBRes - prevBRes), 'not all USDC tokens go to LP pool' ##################################################################################### # add liquidity to the same position print( '=========================================================================' ) print('Case 2.') prevABal = usdt.balanceOf(alice) prevBBal = usdc.balanceOf(alice) prevLPBal = lp.balanceOf(alice) prevLPBal_bank = lp.balanceOf(homora) prevLPBal_werc20 = lp.balanceOf(werc20) if interface.IUniswapV2Pair(lp).token0() == usdt: prevARes, prevBRes, _ = interface.IUniswapV2Pair(lp).getReserves() else: prevBRes, prevARes, _ = interface.IUniswapV2Pair(lp).getReserves() usdt_amt = 20000 * 10**6 usdc_amt = 30000 * 10**6 lp_amt = 1 * 10**7 borrow_usdt_amt = 1000 * 10**6 borrow_usdc_amt = 200 * 10**6 tx = homora.execute( 1, uniswap_spell, uniswap_spell.addLiquidity.encode_input( usdt, # token 0 usdc, # token 1 [ usdt_amt, # supply USDT usdc_amt, # supply USDC lp_amt, # supply LP borrow_usdt_amt, # borrow USDT borrow_usdc_amt, # borrow USDC 0, # borrow LP 0, # min USDT 0 ], # min USDC ), {'from': alice}) position_id = tx.return_value print('position_id', position_id) curABal = usdt.balanceOf(alice) curBBal = usdc.balanceOf(alice) curLPBal = lp.balanceOf(alice) curLPBal_bank = lp.balanceOf(homora) curLPBal_werc20 = lp.balanceOf(werc20) if interface.IUniswapV2Pair(lp).token0() == usdt: curARes, curBRes, _ = interface.IUniswapV2Pair(lp).getReserves() else: curBRes, curARes, _ = interface.IUniswapV2Pair(lp).getReserves() print('spell lp balance', lp.balanceOf(uniswap_spell)) print('Alice delta A balance', curABal - prevABal) print('Alice delta B balance', curBBal - prevBBal) print('add liquidity gas', tx.gas_used) print('bank lp balance', curLPBal_bank) _, _, _, usdtDebt, usdtDebtShare = homora.getBankInfo(usdt) _, _, _, usdcDebt, usdcDebtShare = homora.getBankInfo(usdc) print('bank usdt debt', usdtDebt) print('bank usdt debt share', usdtDebtShare) print('bank usdc debt', usdcDebt) print('bank usdc debt share', usdcDebtShare) print('bank prev LP balance', prevLPBal_bank) print('bank cur LP balance', curLPBal_bank) print('werc20 prev LP balance', prevLPBal_werc20) print('werc20 cur LP balance', curLPBal_werc20) print('prev usdt res', prevARes) print('cur usdt res', curARes) print('prev usdc res', prevBRes) print('cur usdc res', curBRes) # assert position_id assert position_id == 1 # position doesn't increase # alice assert almostEqual(curABal - prevABal, -usdt_amt), 'incorrect USDT amt' assert almostEqual(curBBal - prevBBal, -usdc_amt), 'incorrect USDC amt' assert curLPBal - prevLPBal == -lp_amt, 'incorrect LP amt' # spell assert usdt.balanceOf(uniswap_spell) == 0, 'non-zero spell USDT balance' assert usdc.balanceOf(uniswap_spell) == 0, 'non-zero spell USDC balance' assert lp.balanceOf(uniswap_spell) == 0, 'non-zero spell LP balance' # borrow same amount twice (with small interest accrued) assert usdtDebt >= borrow_usdt_amt * 2 # borrow same amount twice (with small interest accrued) assert usdcDebt >= borrow_usdc_amt * 2 # check balance and pool reserves assert curABal - prevABal - borrow_usdt_amt == - \ (curARes - prevARes), 'not all USDT tokens go to LP pool' assert curBBal - prevBBal - borrow_usdc_amt == - \ (curBRes - prevBRes), 'not all USDC tokens go to LP pool' ##################################################################################### # remove half liquidity from the same position print( '=========================================================================' ) print('Case 3.') prevABal = usdt.balanceOf(alice) prevBBal = usdc.balanceOf(alice) prevLPBal = lp.balanceOf(alice) prevLPBal_bank = lp.balanceOf(homora) prevLPBal_werc20 = lp.balanceOf(werc20) _, _, _, collSize = homora.getPositionInfo(position_id) lp_take_amt = collSize // 2 lp_want = 1 * 10**5 usdt_repay = MAX_INT usdc_repay = MAX_INT tx = homora.execute( position_id, uniswap_spell, uniswap_spell.removeLiquidity.encode_input( usdt, # token 0 usdc, # token 1 [ lp_take_amt, # take out LP lp_want, # withdraw LP to wallet usdt_repay, # repay USDT usdc_repay, # repay USDC 0, # repay LP 0, # min USDT 0 ], # min USDC ), {'from': alice}) curABal = usdt.balanceOf(alice) curBBal = usdc.balanceOf(alice) curLPBal = lp.balanceOf(alice) curLPBal_bank = lp.balanceOf(homora) curLPBal_werc20 = lp.balanceOf(werc20) print('spell lp balance', lp.balanceOf(uniswap_spell)) print('spell usdt balance', usdt.balanceOf(uniswap_spell)) print('spell usdc balance', usdc.balanceOf(uniswap_spell)) print('Alice delta A balance', curABal - prevABal) print('Alice delta B balance', curBBal - prevBBal) print('Alice delta LP balance', curLPBal - prevLPBal) print('remove liquidity gas', tx.gas_used) print('bank delta lp balance', curLPBal_bank - prevLPBal_bank) print('bank total lp balance', curLPBal_bank) _, _, _, usdtDebt, usdtDebtShare = homora.getBankInfo(usdt) _, _, _, usdcDebt, usdcDebtShare = homora.getBankInfo(usdc) print('bank usdt totalDebt', usdtDebt) print('bank usdt totalShare', usdtDebtShare) print('bank usdc totalDebt', usdcDebt) print('bank usdc totalShare', usdcDebtShare) print('LP want', lp_want) print('bank delta LP amount', curLPBal_bank - prevLPBal_bank) print('LP take amount', lp_take_amt) print('prev werc20 LP balance', prevLPBal_werc20) print('cur werc20 LP balance', curLPBal_werc20) print('coll size', collSize) # alice assert almostEqual(curLPBal - prevLPBal, lp_want), 'incorrect LP amt' # werc20 assert almostEqual(curLPBal_werc20 - prevLPBal_werc20, -lp_take_amt), 'incorrect werc20 LP amt' # spell assert usdt.balanceOf(uniswap_spell) == 0, 'non-zero spell USDT balance' assert usdc.balanceOf(uniswap_spell) == 0, 'non-zero spell USDC balance' assert lp.balanceOf(uniswap_spell) == 0, 'non-zero spell LP balance' # debt assert usdtDebt == 0, 'usdtDebt should be 0' assert usdcDebt == 0, 'usdcDebt should be 0' ##################################################################################### # remove remaining liquidity from the same position print( '=========================================================================' ) print('Case 4.') prevABal = usdt.balanceOf(alice) prevBBal = usdc.balanceOf(alice) prevLPBal = lp.balanceOf(alice) prevLPBal_bank = lp.balanceOf(homora) prevLPBal_werc20 = lp.balanceOf(werc20) _, _, _, collSize = homora.getPositionInfo(position_id) lp_take_amt = MAX_INT lp_want = 1 * 10**5 usdt_repay = MAX_INT usdc_repay = MAX_INT tx = homora.execute( position_id, uniswap_spell, uniswap_spell.removeLiquidity.encode_input( usdt, # token 0 usdc, # token 1 [ lp_take_amt, # take out LP lp_want, # withdraw LP to wallet usdt_repay, # repay USDT usdc_repay, # repay USDC 0, # repay LP 0, # min USDT 0 ], # min USDC ), {'from': alice}) curABal = usdt.balanceOf(alice) curBBal = usdc.balanceOf(alice) curLPBal = lp.balanceOf(alice) curLPBal_bank = lp.balanceOf(homora) curLPBal_werc20 = lp.balanceOf(werc20) print('spell lp balance', lp.balanceOf(uniswap_spell)) print('spell usdt balance', usdt.balanceOf(uniswap_spell)) print('spell usdc balance', usdc.balanceOf(uniswap_spell)) print('Alice delta A balance', curABal - prevABal) print('Alice delta B balance', curBBal - prevBBal) print('Alice delta LP balance', curLPBal - prevLPBal) print('remove liquidity gas', tx.gas_used) print('bank delta lp balance', curLPBal_bank - prevLPBal_bank) print('bank total lp balance', curLPBal_bank) _, _, _, usdtDebt, usdtDebtShare = homora.getBankInfo(usdt) _, _, _, usdcDebt, usdcDebtShare = homora.getBankInfo(usdc) print('bank usdt totalDebt', usdtDebt) print('bank usdt totalShare', usdtDebtShare) print('bank usdc totalDebt', usdcDebt) print('bank usdc totalShare', usdcDebtShare) print('LP want', lp_want) print('bank delta LP amount', curLPBal_bank - prevLPBal_bank) print('LP take amount', lp_take_amt) print('prev werc20 LP balance', prevLPBal_werc20) print('cur werc20 LP balance', curLPBal_werc20) print('coll size', collSize) # alice assert almostEqual(curLPBal - prevLPBal, lp_want), 'incorrect LP amt' # werc20 assert almostEqual(curLPBal_werc20 - prevLPBal_werc20, -collSize), 'incorrect werc20 LP amt' # spell assert usdt.balanceOf(uniswap_spell) == 0, 'non-zero spell USDT balance' assert usdc.balanceOf(uniswap_spell) == 0, 'non-zero spell USDC balance' assert lp.balanceOf(uniswap_spell) == 0, 'non-zero spell LP balance' # debt assert usdtDebt == 0, 'usdtDebt should be 0' assert usdcDebt == 0, 'usdcDebt should be 0' ##################################################################################### # add liquidity without borrowing (1x) print( '=========================================================================' ) print('Case 5.') prevABal = usdt.balanceOf(alice) prevBBal = usdc.balanceOf(alice) prevLPBal = lp.balanceOf(alice) prevLPBal_bank = lp.balanceOf(homora) prevLPBal_werc20 = lp.balanceOf(werc20) usdt_amt = 2000 * 10**6 # 2000 USDT usdc_amt = 3000 * 10**6 # 3000 USDC lp_amt = 0 borrow_usdt_amt = 0 borrow_usdc_amt = 0 prevBBal = usdc.balanceOf(alice) tx = homora.execute( 1, uniswap_spell, uniswap_spell.addLiquidity.encode_input( usdt, # token 0 usdc, # token 1 [ usdt_amt, # supply USDT usdc_amt, # supply USDC lp_amt, # supply LP borrow_usdt_amt, # borrow USDT borrow_usdc_amt, # borrow USDC 0, # borrow LP 0, # min USDT 0 ], # min USDC ), {'from': alice}) position_id = tx.return_value print('position_id', position_id) curABal = usdt.balanceOf(alice) curBBal = usdc.balanceOf(alice) curLPBal = lp.balanceOf(alice) curLPBal_bank = lp.balanceOf(homora) curLPBal_werc20 = lp.balanceOf(werc20) print('spell lp balance', lp.balanceOf(uniswap_spell)) print('Alice delta A balance', curABal - prevABal) print('Alice delta B balance', curBBal - prevBBal) print('Alice delta lp balance', curLPBal - prevLPBal) print('add liquidity gas', tx.gas_used) print('bank lp balance', curLPBal_bank) _, _, _, usdtDebt, usdtDebtShare = homora.getBankInfo(usdt) _, _, _, usdcDebt, usdcDebtShare = homora.getBankInfo(usdc) print('bank usdt totalDebt', usdtDebt) print('bank usdt totalShare', usdtDebtShare) print('bank usdc totalDebt', usdcDebt) print('bank usdc totalShare', usdcDebtShare) print('bank prev LP balance', prevLPBal_bank) print('bank cur LP balance', curLPBal_bank) print('werc20 prev LP balance', prevLPBal_werc20) print('werc20 cur LP balance', curLPBal_werc20) # alice assert almostEqual(curABal - prevABal, -usdt_amt), 'incorrect USDT amt' assert almostEqual(curBBal - prevBBal, -usdc_amt), 'incorrect USDC amt' assert almostEqual(curLPBal - prevLPBal, -lp_amt), 'incorrect LP amt' # spell assert usdt.balanceOf(uniswap_spell) == 0, 'non-zero spell USDT balance' assert usdc.balanceOf(uniswap_spell) == 0, 'non-zero spell USDC balance' assert lp.balanceOf(uniswap_spell) == 0, 'non-zero spell LP balance' # debt assert usdtDebt == borrow_usdt_amt assert usdcDebt == borrow_usdc_amt ##################################################################################### # remove all liquidity from the same position print( '=========================================================================' ) print('Case 6.') prevABal = usdt.balanceOf(alice) prevBBal = usdc.balanceOf(alice) prevLPBal = lp.balanceOf(alice) prevLPBal_bank = lp.balanceOf(homora) prevLPBal_werc20 = lp.balanceOf(werc20) _, _, _, collSize = homora.getPositionInfo(position_id) lp_take_amt = MAX_INT # max lp_want = 0 usdt_repay = 0 # max usdc_repay = 0 # max tx = homora.execute( position_id, uniswap_spell, uniswap_spell.removeLiquidity.encode_input( usdt, usdc, [ lp_take_amt, # take out LP lp_want, # withdraw LP to wallet usdt_repay, # repay USDT usdc_repay, # repay USDC 0, # repay LP 0, # min USDT 0 ], # min USDC ), {'from': alice}) curABal = usdt.balanceOf(alice) curBBal = usdc.balanceOf(alice) curLPBal = lp.balanceOf(alice) curLPBal_bank = lp.balanceOf(homora) curLPBal_werc20 = lp.balanceOf(werc20) print('spell lp balance', lp.balanceOf(uniswap_spell)) print('spell usdt balance', usdt.balanceOf(uniswap_spell)) print('spell usdc balance', usdc.balanceOf(uniswap_spell)) print('Alice delta A balance', curABal - prevABal) print('Alice delta B balance', curBBal - prevBBal) print('Alice delta LP balance', curLPBal - prevLPBal) print('remove liquidity gas', tx.gas_used) print('bank delta lp balance', curLPBal_bank - prevLPBal_bank) print('bank total lp balance', curLPBal_bank) _, _, _, usdtDebt, usdtDebtShare = homora.getBankInfo(usdt) _, _, _, usdcDebt, usdcDebtShare = homora.getBankInfo(usdc) print('bank usdt totalDebt', usdtDebt) print('bank usdt totalShare', usdtDebtShare) print('bank usdc totalDebt', usdcDebt) print('bank usdc totalShare', usdcDebtShare) print('LP want', lp_want) print('bank delta LP amount', curLPBal_bank - prevLPBal_bank) print('LP take amount', lp_take_amt) print('prev werc20 LP balance', prevLPBal_werc20) print('cur werc20 LP balance', curLPBal_werc20) print('coll size', collSize) # alice assert almostEqual(curLPBal - prevLPBal, lp_want), 'incorrect LP amt' # werc20 assert almostEqual(curLPBal_werc20 - prevLPBal_werc20, -collSize), 'incorrect werc20 LP amt' # spell assert usdt.balanceOf(uniswap_spell) == 0, 'non-zero spell USDT balance' assert usdc.balanceOf(uniswap_spell) == 0, 'non-zero spell USDC balance' assert lp.balanceOf(uniswap_spell) == 0, 'non-zero spell LP balance' # debt assert usdtDebt == 0, 'usdtDebt should be 0' assert usdcDebt == 0, 'usdcDebt should be 0' return tx
def main(): admin = accounts[0] alice = accounts[1] bob = accounts[2] usdt = interface.IERC20Ex('0xdac17f958d2ee523a2206206994597c13d831ec7') weth = interface.IERC20Ex('0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2') usdc = interface.IERC20Ex('0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48') lp = interface.IERC20Ex('0x06da0fd433C1A5d7a4faa01111c044910A184553') lp_usdc = interface.IERC20Ex('0x3041cbd36888becc7bbcbc0045e3b1f144466f5f') crusdt = interface.ICErc20('0x797AAB1ce7c01eB727ab980762bA88e7133d2157') crusdc = interface.ICErc20('0x44fbebd2f576670a6c33f6fc0b00aa8c5753b322') sushi = interface.IERC20('0x6b3595068778dd592e39a122f4f5a5cf09c90fe2') # sushiswap router router = interface.IUniswapV2Router02( '0xd9e1ce17f2641f24ae83637ab66a2cca9c378b9f') chef = accounts.at('0xc2edad668740f1aa35e4d8f227fb8e17dca888cd', force=True) wchef = WMasterChef.deploy(chef, {'from': admin}) werc20 = WERC20.deploy({'from': admin}) simple_oracle = SimpleOracle.deploy({'from': admin}) simple_oracle.setETHPx([usdt, weth, usdc], [2**112 // 700, 2**112, 2**112 // 700]) uniswap_oracle = UniswapV2Oracle.deploy(simple_oracle, {'from': admin}) core_oracle = CoreOracle.deploy({'from': admin}) oracle = ProxyOracle.deploy(core_oracle, {'from': admin}) oracle.setWhitelistERC1155([werc20, wchef], True, {'from': admin}) core_oracle.setRoute( [usdt, weth, lp, usdc, lp_usdc], [ simple_oracle, simple_oracle, uniswap_oracle, simple_oracle, uniswap_oracle ], {'from': admin}, ) oracle.setOracles( [usdt, weth, lp, usdc, lp_usdc], [ [10000, 10000, 10000], [10000, 10000, 10000], [10000, 10000, 10000], [10000, 10000, 10000], [10000, 10000, 10000], ], {'from': admin}, ) homora = HomoraBank.deploy({'from': admin}) homora.initialize(oracle, 1000, {'from': admin}) # 10% fee setup_bank_hack(homora) homora.addBank(usdt, crusdt, {'from': admin}) homora.addBank(usdc, crusdc, {'from': admin}) # setup initial funds to alice mint_tokens(usdt, alice) mint_tokens(weth, alice) mint_tokens(usdc, alice) # check alice's funds print(f'Alice usdt balance {usdt.balanceOf(alice)}') print(f'Alice weth balance {weth.balanceOf(alice)}') # Steal some LP from the staking pool mint_tokens(lp, alice) mint_tokens(lp, bob) # set approval usdt.approve(homora, 2**256 - 1, {'from': alice}) usdt.approve(crusdt, 2**256 - 1, {'from': alice}) usdc.approve(homora, 2**256 - 1, {'from': alice}) usdc.approve(crusdc, 2**256 - 1, {'from': alice}) weth.approve(homora, 2**256 - 1, {'from': alice}) lp.approve(homora, 2**256 - 1, {'from': alice}) lp.approve(chef, 2**256 - 1, {'from': bob}) sushiswap_spell = SushiswapSpellV1.deploy(homora, werc20, router, wchef, {'from': admin}) # first time call to reduce gas sushiswap_spell.getPair(weth, usdt, {'from': admin}) ##################################################################################### print( '=========================================================================' ) print('Case 1. add liquidity first time') prevABal = usdt.balanceOf(alice) prevBBal = weth.balanceOf(alice) prevLPBal = lp.balanceOf(alice) prevLPBal_bank = lp.balanceOf(homora) prevLPBal_chef = lp.balanceOf(chef) if interface.IUniswapV2Pair(lp).token0() == usdt: prevARes, prevBRes, _ = interface.IUniswapV2Pair(lp).getReserves() else: prevBRes, prevARes, _ = interface.IUniswapV2Pair(lp).getReserves() usdt_amt = 10 * 10**6 weth_amt = 10**18 lp_amt = 0 borrow_usdt_amt = 0 borrow_weth_amt = 0 pid = 0 tx = homora.execute( 0, sushiswap_spell, sushiswap_spell.addLiquidityWMasterChef.encode_input( usdt, # token 0 weth, # token 1 [ usdt_amt, # supply USDT weth_amt, # supply WETH lp_amt, # supply LP borrow_usdt_amt, # borrow USDT borrow_weth_amt, # borrow WETH 0, # borrow LP tokens 0, # min USDT 0 ], # min WETH pid, ), {'from': alice}) curABal = usdt.balanceOf(alice) curBBal = weth.balanceOf(alice) curLPBal = lp.balanceOf(alice) curLPBal_bank = lp.balanceOf(homora) curLPBal_chef = lp.balanceOf(chef) if interface.IUniswapV2Pair(lp).token0() == usdt: curARes, curBRes, _ = interface.IUniswapV2Pair(lp).getReserves() else: curBRes, curARes, _ = interface.IUniswapV2Pair(lp).getReserves() print('spell lp balance', lp.balanceOf(sushiswap_spell)) print('Alice delta A balance', curABal - prevABal) print('Alice delta B balance', curBBal - prevBBal) print('add liquidity gas', tx.gas_used) print('bank lp balance', curLPBal_bank) _, _, _, totalDebt, totalShare = homora.getBankInfo(usdt) print('bank usdt totalDebt', totalDebt) print('bank usdt totalShare', totalShare) print('bank prev LP balance', prevLPBal_bank) print('bank cur LP balance', curLPBal_bank) print('chef prev LP balance', prevLPBal_chef) print('chef cur LP balance', curLPBal_chef) print('prev usdt res', prevARes) print('cur usdt res', curARes) print('prev weth res', prevBRes) print('cur weth res', curBRes) # alice assert almostEqual(curABal - prevABal, -usdt_amt), 'incorrect USDT amt' assert almostEqual(curBBal - prevBBal, -weth_amt), 'incorrect WETH amt' assert curLPBal - prevLPBal == -lp_amt, 'incorrect LP amt' # spell assert usdt.balanceOf(sushiswap_spell) == 0, 'non-zero spell USDT balance' assert weth.balanceOf(sushiswap_spell) == 0, 'non-zero spell WETH balance' assert lp.balanceOf(sushiswap_spell) == 0, 'non-zero spell LP balance' assert totalDebt == borrow_usdt_amt # check balance and pool reserves assert curABal - prevABal - borrow_usdt_amt == - \ (curARes - prevARes), 'not all USDT tokens go to LP pool' assert almostEqual( curBBal - prevBBal - borrow_weth_amt, -(curBRes - prevBRes)), 'not all WETH tokens go to LP pool' _, _, collId, collSize = homora.getPositionInfo(1) print('collSize', collSize) # staking directly prevSushi = sushi.balanceOf(bob) pid = 0 print('bob lp balance', interface.IERC20Ex(lp).balanceOf(bob)) tx = interface.IMasterChef(chef).deposit(pid, collSize, {'from': bob}) chain.sleep(20000) prevAliceSushiBalance = sushi.balanceOf(alice) print('Alice sushi balance', prevAliceSushiBalance) ##################################################################################### print( '=========================================================================' ) print('Case 2. add liquidity (failed tx desired)') usdc_amt = 10 * 10**6 weth_amt = 10**18 lp_amt = 0 borrow_usdc_amt = 0 borrow_weth_amt = 0 pid = 0 try: tx = homora.execute( 1, sushiswap_spell, sushiswap_spell.addLiquidityWMasterChef.encode_input( usdc, # token 0 weth, # token 1 [ usdc_amt, # supply USDC weth_amt, # supply WETH lp_amt, # supply LP borrow_usdc_amt, # borrow USDC borrow_weth_amt, # borrow WETH 0, # borrow LP tokens 0, # min USDC 0 ], # min WETH pid, ), {'from': alice}) assert False, 'tx not fail' except VirtualMachineError: pass ##################################################################################### print( '=========================================================================' ) print('Case 3. remove liquidity (failed tx desired)') lp_take_amt = collSize lp_want = 0 usdc_repay = 0 weth_repay = 0 try: tx = homora.execute( 1, sushiswap_spell, sushiswap_spell.removeLiquidityWMasterChef.encode_input( usdc, # token 0 weth, # token 1 [ lp_take_amt, # take out LP tokens lp_want, # withdraw LP tokens to wallet usdc_repay, # repay USDC weth_repay, # repay WETH 0, # repay LP tokens 0, # min USDC 0 ], # min WETH ), {'from': alice}) assert False, 'tx not failed' except VirtualMachineError: pass ##################################################################################### print( '=========================================================================' ) print('Case 4. remove liquidity') prevABal = usdt.balanceOf(alice) prevBBal = weth.balanceOf(alice) prevLPBal = lp.balanceOf(alice) prevLPBal_bank = lp.balanceOf(homora) prevLPBal_chef = lp.balanceOf(chef) prevETHBal = alice.balance() if interface.IUniswapV2Pair(lp).token0() == usdt: prevARes, prevBRes, _ = interface.IUniswapV2Pair(lp).getReserves() else: prevBRes, prevARes, _ = interface.IUniswapV2Pair(lp).getReserves() lp_take_amt = collSize lp_want = 0 usdt_repay = 0 weth_repay = 0 pid = 0 tx = homora.execute( 1, sushiswap_spell, sushiswap_spell.removeLiquidityWMasterChef.encode_input( usdt, # token 0 weth, # token 1 [ lp_take_amt, # take out LP tokens lp_want, # withdraw LP tokens to wallet usdt_repay, # repay USDT weth_repay, # repay WETH 0, # repay LP tokens 0, # min USDT 0 ], # min WETH ), {'from': alice}) curABal = usdt.balanceOf(alice) curBBal = weth.balanceOf(alice) curLPBal = lp.balanceOf(alice) curLPBal_bank = lp.balanceOf(homora) curLPBal_chef = lp.balanceOf(chef) curETHBal = alice.balance() if interface.IUniswapV2Pair(lp).token0() == usdt: curARes, curBRes, _ = interface.IUniswapV2Pair(lp).getReserves() else: curBRes, curARes, _ = interface.IUniswapV2Pair(lp).getReserves() print('spell lp balance', lp.balanceOf(sushiswap_spell)) print('Alice delta A balance', curABal - prevABal) print('Alice delta B balance', curBBal - prevBBal) print('add liquidity gas', tx.gas_used) print('bank lp balance', curLPBal_bank) _, _, _, totalDebt, totalShare = homora.getBankInfo(usdt) print('bank usdt totalDebt', totalDebt) print('bank usdt totalShare', totalShare) print('bank prev LP balance', prevLPBal_bank) print('bank cur LP balance', curLPBal_bank) print('chef prev LP balance', prevLPBal_chef) print('chef cur LP balance', curLPBal_chef) print('prev usdt res', prevARes) print('cur usdt res', curARes) print('prev weth res', prevBRes) print('cur weth res', curBRes) # alice assert almostEqual(curBBal - prevBBal, 0), 'incorrect WETH amt' assert almostEqual(curLPBal - prevLPBal, lp_want), 'incorrect LP amt' # chef assert almostEqual(curLPBal_chef - prevLPBal_chef, -lp_take_amt), 'incorrect chef LP amt' # spell assert usdt.balanceOf(sushiswap_spell) == 0, 'non-zero spell USDT balance' assert weth.balanceOf(sushiswap_spell) == 0, 'non-zero spell WETH balance' assert lp.balanceOf(sushiswap_spell) == 0, 'non-zero spell LP balance' # check balance and pool reserves assert almostEqual( curABal - prevABal + usdt_repay, -(curARes - prevARes)), 'inconsistent USDT from withdraw' assert almostEqual(curBBal - prevBBal, 0), 'inconsistent WETH from withdraw' assert almostEqual(curETHBal - prevETHBal + weth_repay, -(curBRes - prevBRes)), 'inconsistent ETH from withdraw' curAliceSushiBalance = sushi.balanceOf(alice) print('Alice sushi balance', curAliceSushiBalance) receivedSushi = curAliceSushiBalance - prevAliceSushiBalance print('received sushi', receivedSushi) # check with staking directly pid = 0 tx = interface.IMasterChef(chef).withdraw(pid, collSize, {'from': bob}) receivedSushiFromStaking = sushi.balanceOf(bob) - prevSushi print('receivedSushiFromStaking', receivedSushiFromStaking) assert almostEqual(receivedSushi, receivedSushiFromStaking)
def main(): deployer = accounts.at('0xB593d82d53e2c187dc49673709a6E9f806cdC835', force=True) # deployer = accounts.load('gh') werc20 = WERC20.deploy({'from': deployer}) wmas = WMasterChef.deploy(MASTERCHEF, {'from': deployer}) wliq = WLiquidityGauge.deploy(CRV_REGISTRY, CRV_TOKEN, {'from': deployer}) wsindex = WStakingRewards.deploy( '0xB93b505Ed567982E2b6756177ddD23ab5745f309', '0x4d5ef58aAc27d99935E5b6B4A6778ff292059991', # UNI DPI-WETH '0x0954906da0Bf32d5479e25f46056d22f08464cab', # INDEX {'from': deployer}, ) wsperp = WStakingRewards.deploy( '0xb9840a4a8a671f79de3df3b812feeb38047ce552', '0xF54025aF2dc86809Be1153c1F20D77ADB7e8ecF4', # BAL PERP-USDC 80-20 '0xbC396689893D065F41bc2C6EcbeE5e0085233447', # PERP {'from': deployer}, ) kp3r_oracle = ERC20KP3ROracle.deploy(KP3R_NETWORK, {'from': deployer}) core_oracle = CoreOracle.deploy({'from': deployer}) uni_oracle = UniswapV2Oracle.deploy(core_oracle, {'from': deployer}) bal_oracle = BalancerPairOracle.deploy(core_oracle, {'from': deployer}) crv_oracle = CurveOracle.deploy(core_oracle, CRV_REGISTRY, {'from': deployer}) proxy_oracle = ProxyOracle.deploy(core_oracle, {'from': deployer}) core_oracle.setRoute([ '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', # ETH '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', # WETH '0x6b175474e89094c44da98b954eedeac495271d0f', # DAI '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', # USDC '0xdac17f958d2ee523a2206206994597c13d831ec7', # USDT '0x2260fac5e5542a773aa44fbcfedf7c193bc2c599', # WBTC '0x1494ca1f11d487c2bbe4543e90080aeba4ba3c2b', # DPI '0xbC396689893D065F41bc2C6EcbeE5e0085233447', # PERP '0xc011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f', # SNX '0xa478c2975ab1ea89e8196811f51a7b7ade33eb11', # UNI DAI-WETH '0x0d4a11d5eeaac28ec3f61d100daf4d40471f1852', # UNI WETH-USDT '0xb4e16d0168e52d35cacd2c6185b44281ec28c9dc', # UNI USDC-WETH '0xbb2b8038a1640196fbe3e38816f3e67cba72d940', # UNI WBTC-WETH '0x4d5ef58aac27d99935e5b6b4a6778ff292059991', # UNI DPI-WETH '0x06da0fd433c1a5d7a4faa01111c044910a184553', # SUSHI WETH-USDT '0x8b6e6e7b5b3801fed2cafd4b22b8a16c2f2db21a', # BAL WETH-DAI 80-20 '0xf54025af2dc86809be1153c1f20d77adb7e8ecf4', # BAL PERP-USDC 80-20 '0x6c3f90f043a72fa612cbac8115ee7e52bde6e490', # CRV 3-POOL ], [ kp3r_oracle, kp3r_oracle, kp3r_oracle, kp3r_oracle, kp3r_oracle, kp3r_oracle, kp3r_oracle, kp3r_oracle, kp3r_oracle, uni_oracle, uni_oracle, uni_oracle, uni_oracle, uni_oracle, uni_oracle, bal_oracle, bal_oracle, crv_oracle, ], {'from': deployer}) proxy_oracle.setOracles([ '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', # WETH '0x6b175474e89094c44da98b954eedeac495271d0f', # DAI '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', # USDC '0xdac17f958d2ee523a2206206994597c13d831ec7', # USDT '0x2260fac5e5542a773aa44fbcfedf7c193bc2c599', # WBTC '0x1494ca1f11d487c2bbe4543e90080aeba4ba3c2b', # DPI '0xbC396689893D065F41bc2C6EcbeE5e0085233447', # PERP '0xc011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f', # SNX '0xa478c2975ab1ea89e8196811f51a7b7ade33eb11', # UNI DAI-WETH '0x0d4a11d5eeaac28ec3f61d100daf4d40471f1852', # UNI WETH-USDT '0xb4e16d0168e52d35cacd2c6185b44281ec28c9dc', # UNI USDC-WETH '0xbb2b8038a1640196fbe3e38816f3e67cba72d940', # UNI WBTC-WETH '0x4d5ef58aac27d99935e5b6b4a6778ff292059991', # UNI DPI-WETH '0x06da0fd433c1a5d7a4faa01111c044910a184553', # SUSHI WETH-USDT '0x8b6e6e7b5b3801fed2cafd4b22b8a16c2f2db21a', # BAL WETH-DAI 80-20 '0xf54025af2dc86809be1153c1f20d77adb7e8ecf4', # BAL PERP-USDC 80-20 '0x6c3f90f043a72fa612cbac8115ee7e52bde6e490', # CRV 3-POOL ], [ [12500, 8000, 10250], [10500, 9500, 10250], [10500, 9500, 10250], [10500, 9500, 10250], [12500, 8000, 10250], [50000, 0, 10250], [50000, 0, 10250], [50000, 0, 10250], [50000, 8000, 10250], [50000, 8000, 10250], [50000, 8000, 10250], [50000, 8000, 10250], [50000, 6000, 10250], [50000, 8000, 10250], [50000, 8000, 10250], [50000, 0, 10250], [50000, 9500, 10250], ], {'from': deployer}) proxy_oracle.setWhitelistERC1155( [werc20, wmas, wliq, wsindex, wsperp], True, {'from': deployer}, ) bank = HomoraBank.at('0x5f5Cd91070960D13ee549C9CC47e7a4Cd00457bb') bank.setOracle(proxy_oracle, {'from': deployer}) wliq.registerGauge(0, 0, {'from': deployer}) uniswap_spell = UniswapV2SpellV1.deploy( bank, werc20, '0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D', {'from': deployer}, ) sushiswap_spell = SushiswapSpellV1.deploy( bank, werc20, '0xd9e1ce17f2641f24ae83637ab66a2cca9c378b9f', wmas, {'from': deployer}, ) balancer_spell = BalancerSpellV1.deploy( bank, werc20, '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', {'from': deployer}, ) curve_spell = CurveSpellV1.deploy( bank, werc20, '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', wliq, {'from': deployer}, ) # register 3pool crv_oracle.registerPool('0x6c3f90f043a72fa612cbac8115ee7e52bde6e490') print('DONE')
def main(): admin = accounts[0] alice = accounts[1] bob = accounts[2] usdt = interface.IERC20Ex('0xdac17f958d2ee523a2206206994597c13d831ec7') weth = interface.IERC20Ex('0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2') lp = interface.IERC20Ex('0x06da0fd433C1A5d7a4faa01111c044910A184553') crusdt = interface.ICErc20('0x797AAB1ce7c01eB727ab980762bA88e7133d2157') sushi = interface.IERC20('0x6b3595068778dd592e39a122f4f5a5cf09c90fe2') # sushiswap router router = interface.IUniswapV2Router02( '0xd9e1ce17f2641f24ae83637ab66a2cca9c378b9f') chef = accounts.at('0xc2edad668740f1aa35e4d8f227fb8e17dca888cd', force=True) wchef = WMasterChef.deploy(chef, {'from': admin}) werc20 = WERC20.deploy({'from': admin}) simple_oracle = SimpleOracle.deploy({'from': admin}) simple_oracle.setETHPx([usdt, weth], [2**112 // 700, 2**112]) uniswap_oracle = UniswapV2Oracle.deploy(simple_oracle, {'from': admin}) core_oracle = CoreOracle.deploy({'from': admin}) oracle = ProxyOracle.deploy(core_oracle, {'from': admin}) oracle.setWhitelistERC1155([werc20, wchef], True, {'from': admin}) core_oracle.setRoute( [usdt, weth, lp], [simple_oracle, simple_oracle, uniswap_oracle], {'from': admin}, ) oracle.setOracles( [usdt, weth, lp], [ [10000, 10000, 10000], [10000, 10000, 10000], [10000, 10000, 10000], ], {'from': admin}, ) homora = HomoraBank.deploy({'from': admin}) homora.initialize(oracle, 1000, {'from': admin}) # 10% fee setup_bank_hack(homora) homora.addBank(usdt, crusdt, {'from': admin}) # setup initial funds to alice mint_tokens(usdt, alice) mint_tokens(weth, alice) # check alice's funds print(f'Alice usdt balance {usdt.balanceOf(alice)}') print(f'Alice weth balance {weth.balanceOf(alice)}') # Steal some LP from the staking pool mint_tokens(lp, alice) mint_tokens(lp, bob) # set approval usdt.approve(homora, 2**256 - 1, {'from': alice}) usdt.approve(crusdt, 2**256 - 1, {'from': alice}) weth.approve(homora, 2**256 - 1, {'from': alice}) lp.approve(homora, 2**256 - 1, {'from': alice}) lp.approve(chef, 2**256 - 1, {'from': bob}) sushiswap_spell = SushiswapSpellV1.deploy(homora, werc20, router, wchef, {'from': admin}) # first time call to reduce gas sushiswap_spell.getPair(weth, usdt, {'from': admin}) # whitelist spell in bank homora.setWhitelistSpells([sushiswap_spell], [True], {'from': admin}) # whitelist lp in spell sushiswap_spell.setWhitelistLPTokens([lp], [True], {'from': admin}) ##################################################################################### print( '=========================================================================' ) print('Case 1. add liquidity') prevABal = usdt.balanceOf(alice) prevBBal = weth.balanceOf(alice) prevLPBal = lp.balanceOf(alice) prevLPBal_bank = lp.balanceOf(homora) prevLPBal_wchef = lp.balanceOf(wchef) if interface.IUniswapV2Pair(lp).token0() == usdt: prevARes, prevBRes, _ = interface.IUniswapV2Pair(lp).getReserves() else: prevBRes, prevARes, _ = interface.IUniswapV2Pair(lp).getReserves() usdt_amt = 10 * 10**6 weth_amt = 10**18 lp_amt = 0 borrow_usdt_amt = 0 borrow_weth_amt = 0 pid = 0 tx = homora.execute( 0, sushiswap_spell, sushiswap_spell.addLiquidityWMasterChef.encode_input( usdt, # token 0 weth, # token 1 [ usdt_amt, # supply USDT weth_amt, # supply WETH lp_amt, # supply LP borrow_usdt_amt, # borrow USDT borrow_weth_amt, # borrow WETH 0, # borrow LP tokens 0, # min USDT 0 ], # min WETH pid, ), {'from': alice}) curABal = usdt.balanceOf(alice) curBBal = weth.balanceOf(alice) curLPBal = lp.balanceOf(alice) curLPBal_bank = lp.balanceOf(homora) curLPBal_wchef = lp.balanceOf(wchef) if interface.IUniswapV2Pair(lp).token0() == usdt: curARes, curBRes, _ = interface.IUniswapV2Pair(lp).getReserves() else: curBRes, curARes, _ = interface.IUniswapV2Pair(lp).getReserves() print('spell lp balance', lp.balanceOf(sushiswap_spell)) print('Alice delta A balance', curABal - prevABal) print('Alice delta B balance', curBBal - prevBBal) print('add liquidity gas', tx.gas_used) print('bank lp balance', curLPBal_bank) _, _, _, totalDebt, totalShare = homora.getBankInfo(usdt) print('bank usdt totalDebt', totalDebt) print('bank usdt totalShare', totalShare) print('bank prev LP balance', prevLPBal_bank) print('bank cur LP balance', curLPBal_bank) print('wchef prev LP balance', prevLPBal_wchef) print('wchef cur LP balance', curLPBal_wchef) print('prev usdt res', prevARes) print('cur usdt res', curARes) print('prev weth res', prevBRes) print('cur weth res', curBRes) # alice assert almostEqual(curABal - prevABal, -usdt_amt), 'incorrect USDT amt' assert almostEqual(curBBal - prevBBal, -weth_amt), 'incorrect WETH amt' assert curLPBal - prevLPBal == -lp_amt, 'incorrect LP amt' # spell assert usdt.balanceOf(sushiswap_spell) == 0, 'non-zero spell USDT balance' assert weth.balanceOf(sushiswap_spell) == 0, 'non-zero spell WETH balance' assert lp.balanceOf(sushiswap_spell) == 0, 'non-zero spell LP balance' assert totalDebt == borrow_usdt_amt # check balance and pool reserves assert curABal - prevABal - borrow_usdt_amt == - \ (curARes - prevARes), 'not all USDT tokens go to LP pool' assert almostEqual( curBBal - prevBBal - borrow_weth_amt, -(curBRes - prevBRes)), 'not all WETH tokens go to LP pool' # ##################################################################################### print( '=========================================================================' ) print('Case 2. harvest first time') prevSushiBalance = sushi.balanceOf(alice) print('Alice SUSHI balance before harvest', prevSushiBalance) _, _, collId, collSize = homora.getPositionInfo(1) print('collSize', collSize) # staking directly prevSushi = sushi.balanceOf(bob) print('bob lp balance', interface.IERC20Ex(lp).balanceOf(bob)) pid = 0 tx = interface.IMasterChef(chef).deposit(pid, collSize, {'from': bob}) chain.mine(100) tx = homora.execute(1, sushiswap_spell, sushiswap_spell.harvestWMasterChef.encode_input(), {'from': alice}) print('tx gas used', tx.gas_used) curSushiBalance = sushi.balanceOf(alice) print('Alice SUSHI balance after harvest', curSushiBalance) receivedSushi = curSushiBalance - prevSushiBalance # check with staking directly pid = 0 tx = interface.IMasterChef(chef).withdraw(pid, collSize, {'from': bob}) receivedSushiFromStaking = sushi.balanceOf(bob) - prevSushi print('receivedSushiFromStaking', receivedSushiFromStaking) assert almostEqual(receivedSushi, receivedSushiFromStaking) # ##################################################################################### print( '=========================================================================' ) print('Case 3. harvest second time') prevSushiBalance = sushi.balanceOf(alice) print('Alice SUSHI balance before harvest', prevSushiBalance) prevSushi = sushi.balanceOf(bob) print('bob lp balance', interface.IERC20Ex(lp).balanceOf(bob)) # staking directly prevSushi = sushi.balanceOf(bob) print('bob lp balance', interface.IERC20Ex(lp).balanceOf(bob)) pid = 0 tx = interface.IMasterChef(chef).deposit(pid, collSize, {'from': bob}) chain.mine(100) tx = homora.execute(1, sushiswap_spell, sushiswap_spell.harvestWMasterChef.encode_input(), {'from': alice}) print('tx gas used', tx.gas_used) curSushiBalance = sushi.balanceOf(alice) print('Alice SUSHI balance after harvest', curSushiBalance) receivedSushi = curSushiBalance - prevSushiBalance # check with staking directly tx = interface.IMasterChef(chef).withdraw(pid, collSize, {'from': bob}) receivedSushiFromStaking = sushi.balanceOf(bob) - prevSushi print('receivedSushiFromStaking', receivedSushiFromStaking) assert almostEqual(receivedSushi, receivedSushiFromStaking)
def main(): admin = accounts[0] alice = accounts[1] usdt = interface.IERC20Ex('0xdAC17F958D2ee523a2206206994597C13D831ec7') weth = interface.IERC20Ex('0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2') lp = interface.IERC20Ex('0x0d4a11d5EEaaC28EC3F61d100daF4d40471f1852') crusdt = interface.ICErc20('0x797AAB1ce7c01eB727ab980762bA88e7133d2157') router = interface.IUniswapV2Router02( '0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D') werc20 = WERC20.deploy({'from': admin}) simple_oracle = SimpleOracle.deploy({'from': admin}) simple_oracle.setETHPx( [usdt, weth], [9011535487953795006625883219171279625142296, 2**112]) uniswap_oracle = UniswapV2Oracle.deploy(simple_oracle, {'from': admin}) oracle = ProxyOracle.deploy({'from': admin}) oracle.setWhitelistERC1155([werc20], True, {'from': admin}) oracle.setOracles( [ '0xdAC17F958D2ee523a2206206994597C13D831ec7', # USDT '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', # WETH '0x0d4a11d5EEaaC28EC3F61d100daF4d40471f1852', # USDT-WETH ], [ [simple_oracle, 10000, 10000, 10000], [simple_oracle, 10000, 10000, 10000], [uniswap_oracle, 10000, 10000, 10000], ], {'from': admin}, ) homora = HomoraBank.deploy({'from': admin}) homora.initialize(oracle, 1000, {'from': admin}) # 10% fee setup_bank_hack(homora) homora.addBank(usdt, crusdt, {'from': admin}) # setup initial funds 10^5 USDT + 10^4 WETH to alice setup_transfer( usdt, accounts.at('0xbe0eb53f46cd790cd13851d5eff43d12404d33e8', force=True), alice, 10**5 * 10**6) setup_transfer( weth, accounts.at('0x397ff1542f962076d0bfe58ea045ffa2d347aca0', force=True), alice, 10**4 * 10**18) # setup initial funds 10^6 USDT + 10^5 WETH to homora bank setup_transfer( usdt, accounts.at('0xbe0eb53f46cd790cd13851d5eff43d12404d33e8', force=True), homora, 10**6 * 10**6) setup_transfer( weth, accounts.at('0x397ff1542f962076d0bfe58ea045ffa2d347aca0', force=True), homora, 10**4 * 10**18) # check alice's funds print(f'Alice usdt balance {usdt.balanceOf(alice)}') print(f'Alice weth balance {weth.balanceOf(alice)}') # Steal some LP from the staking pool lp.transfer( alice, 1 * 10**17, { 'from': accounts.at('0x767ecb395def19ab8d1b2fcc89b3ddfbed28fd6b', force=True) }) lp.transfer( homora, 2 * 10**17, { 'from': accounts.at('0x767ecb395def19ab8d1b2fcc89b3ddfbed28fd6b', force=True) }) # set approval usdt.approve(homora, 2**256 - 1, {'from': alice}) usdt.approve(crusdt, 2**256 - 1, {'from': alice}) weth.approve(homora, 2**256 - 1, {'from': alice}) lp.approve(homora, 2**256 - 1, {'from': alice}) uniswap_spell = UniswapV2SpellV1.deploy(homora, werc20, router, {'from': admin}) # first time call to reduce gas uniswap_spell.getPair(weth, usdt, {'from': admin}) ##################################################################################### print( '=========================================================================' ) print('Case 1.') prevABal = usdt.balanceOf(alice) prevBBal = weth.balanceOf(alice) prevETHBal = alice.balance() prevLPBal = lp.balanceOf(alice) prevLPBal_bank = lp.balanceOf(homora) prevLPBal_werc20 = lp.balanceOf(werc20) if interface.IUniswapV2Pair(lp).token0() == usdt: prevARes, prevBRes, _ = interface.IUniswapV2Pair(lp).getReserves() else: prevBRes, prevARes, _ = interface.IUniswapV2Pair(lp).getReserves() usdt_amt = 400 * 10**6 weth_amt = 10**18 eth_amt = 10**18 lp_amt = 1 * 10**16 borrow_usdt_amt = 1000 * 10**6 borrow_weth_amt = 0 tx = homora.execute( 0, uniswap_spell, uniswap_spell.addLiquidity.encode_input( usdt, # token 0 weth, # token 1 [ usdt_amt, # supply USDT weth_amt, # supply WETH lp_amt, # supply LP borrow_usdt_amt, # borrow USDT borrow_weth_amt, # borrow WETH 0, # borrow LP tokens 0, # min USDT 0 ], # min WETH ), { 'from': alice, 'value': eth_amt }) position_id = tx.return_value print('position_id', position_id) curABal = usdt.balanceOf(alice) curBBal = weth.balanceOf(alice) curETHBal = alice.balance() curLPBal = lp.balanceOf(alice) curLPBal_bank = lp.balanceOf(homora) curLPBal_werc20 = lp.balanceOf(werc20) if interface.IUniswapV2Pair(lp).token0() == usdt: curARes, curBRes, _ = interface.IUniswapV2Pair(lp).getReserves() else: curBRes, curARes, _ = interface.IUniswapV2Pair(lp).getReserves() print('spell lp balance', lp.balanceOf(uniswap_spell)) print('Alice delta A balance', curABal - prevABal) print('Alice delta B balance', curBBal - prevBBal) print('add liquidity gas', tx.gas_used) print('bank lp balance', curLPBal_bank) _, _, _, totalDebt, totalShare = homora.getBankInfo(usdt) print('bank usdt totalDebt', totalDebt) print('bank usdt totalShare', totalShare) print('bank prev LP balance', prevLPBal_bank) print('bank cur LP balance', curLPBal_bank) print('werc20 prev LP balance', prevLPBal_werc20) print('werc20 cur LP balance', curLPBal_werc20) # alice assert almostEqual(curABal - prevABal, -usdt_amt), 'incorrect USDT amt' assert almostEqual(curBBal - prevBBal, -weth_amt), 'incorrect WETH amt' assert almostEqual(curETHBal - prevETHBal, -eth_amt), 'incorrect ETH amt' assert curLPBal - prevLPBal == -lp_amt, 'incorrect LP amt' # spell assert usdt.balanceOf(uniswap_spell) == 0, 'non-zero spell USDT balance' assert weth.balanceOf(uniswap_spell) == 0, 'non-zero spell WETH balance' assert uniswap_spell.balance() == 0, 'non-zero spell ETH balance' assert lp.balanceOf(uniswap_spell) == 0, 'non-zero spell LP balance' assert totalDebt == borrow_usdt_amt # check balance and pool reserves assert curABal - prevABal - borrow_usdt_amt == - \ (curARes - prevARes), 'not all USDT tokens go to LP pool' assert curBBal - prevBBal - borrow_weth_amt - eth_amt == - \ (curBRes - prevBRes), 'not all WETH tokens go to LP pool' ##################################################################################### print( '=========================================================================' ) print('Case 2.') # remove liquidity from the same position prevABal = usdt.balanceOf(alice) prevBBal = weth.balanceOf(alice) prevLPBal = lp.balanceOf(alice) prevLPBal_bank = lp.balanceOf(homora) prevLPBal_werc20 = lp.balanceOf(werc20) prevETHBal = alice.balance() if interface.IUniswapV2Pair(lp).token0() == usdt: prevARes, prevBRes, _ = interface.IUniswapV2Pair(lp).getReserves() else: prevBRes, prevARes, _ = interface.IUniswapV2Pair(lp).getReserves() lp_take_amt = 1 * 10**16 lp_want = 1 * 10**15 usdt_repay = 2**256 - 1 # max weth_repay = 0 real_usdt_repay = homora.borrowBalanceStored(position_id, usdt) tx = homora.execute( position_id, uniswap_spell, uniswap_spell.removeLiquidity.encode_input( usdt, # token 0 weth, # token 1 [ lp_take_amt, # take out LP tokens lp_want, # withdraw LP tokens to wallet usdt_repay, # repay USDT weth_repay, # repay WETH 0, # repay LP 0, # min USDT 0 ], # min WETH ), {'from': alice}) curABal = usdt.balanceOf(alice) curBBal = weth.balanceOf(alice) curLPBal = lp.balanceOf(alice) curLPBal_bank = lp.balanceOf(homora) curLPBal_werc20 = lp.balanceOf(werc20) curETHBal = alice.balance() if interface.IUniswapV2Pair(lp).token0() == usdt: curARes, curBRes, _ = interface.IUniswapV2Pair(lp).getReserves() else: curBRes, curARes, _ = interface.IUniswapV2Pair(lp).getReserves() print('spell lp balance', lp.balanceOf(uniswap_spell)) print('spell usdt balance', usdt.balanceOf(uniswap_spell)) print('spell weth balance', weth.balanceOf(uniswap_spell)) print('Alice delta A balance', curABal - prevABal) print('Alice delta B balance', curBBal - prevBBal) print('Alice delta LP balance', curLPBal - prevLPBal) print('remove liquidity gas', tx.gas_used) print('bank delta lp balance', curLPBal_bank - prevLPBal_bank) print('bank total lp balance', curLPBal_bank) _, _, _, totalDebt, totalShare = homora.getBankInfo(usdt) print('bank usdt totalDebt', totalDebt) print('bank usdt totalShare', totalShare) print('LP want', lp_want) print('bank delta LP amount', curLPBal_bank - prevLPBal_bank) print('LP take amount', lp_take_amt) print('prev werc20 LP balance', prevLPBal_werc20) print('cur werc20 LP balance', curLPBal_werc20) # alice assert almostEqual(curBBal - prevBBal, 0), 'incorrect WETH amt' assert almostEqual(curLPBal - prevLPBal, lp_want), 'incorrect LP amt' # werc20 assert almostEqual(curLPBal_werc20 - prevLPBal_werc20, -lp_take_amt), 'incorrect werc20 LP amt' # spell assert usdt.balanceOf(uniswap_spell) == 0, 'non-zero spell USDT balance' assert weth.balanceOf(uniswap_spell) == 0, 'non-zero spell WETH balance' assert uniswap_spell.balance() == 0, 'non-zero spell ETH balance' assert lp.balanceOf(uniswap_spell) == 0, 'non-zero spell LP balance' # check balance and pool reserves assert almostEqual( curABal - prevABal + real_usdt_repay, -(curARes - prevARes)), 'inconsistent USDT from withdraw' assert almostEqual(curBBal - prevBBal, 0), 'inconsistent WETH from withdraw' assert almostEqual(curETHBal - prevETHBal + weth_repay, -(curBRes - prevBRes)), 'inconsistent ETH from withdraw' return tx