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')

    weth = interface.IAny('0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2')
    dai = interface.IAny('0x6B175474E89094C44Da98b954EedeAC495271d0F')
    usdc = interface.IAny('0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48')
    usdt = interface.IAny('0xdAC17F958D2ee523a2206206994597C13D831ec7')

    werc20 = WERC20.at('0xe28D9dF7718b0b5Ba69E01073fE82254a9eD2F98')
    wmas = WMasterChef.at('0x373ae78a14577682591E088F2E78EF1417612c68')
    wliq = WLiquidityGauge.at('0xfdB4f97953150e47C8606758C13e70b5a789a7ec')
    wsindex = WStakingRewards.at('0x713df2DDDA9C7d7bDa98A9f8fCd82c06c50fbd90')
    wsperp = WStakingRewards.at('0xC4635854480ffF80F742645da0310e9e59795c63')

    # upgrade bank's implementation
    bank_impl = HomoraBank.deploy({'from': deployer})
    proxy_admin = Contract.from_explorer(
        '0x090eCE252cEc5998Db765073D07fac77b8e60CB2')
    bank = HomoraBank.at('0x5f5Cd91070960D13ee549C9CC47e7a4Cd00457bb')
    proxy_admin.upgrade(bank, bank_impl, {'from': deployer})

    # re-deploy spells
    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, weth,
                                            {'from': deployer})
    curve_spell = CurveSpellV1.deploy(bank, werc20, weth, wliq,
                                      {'from': deployer})

    # set whitelist spells in bank
    bank.setWhitelistSpells(
        [uniswap_spell, sushiswap_spell, balancer_spell, curve_spell],
        [True] * 4, {'from': deployer})

    # set whitelist tokens in bank
    bank.setWhitelistTokens([weth, dai, usdc, usdt], [True] * 4,
                            {'from': deployer})

    # set whitelist lp tokens in spells
    uniswap_spell.setWhitelistLPTokens(
        ['0xd3d2E2692501A5c9Ca623199D38826e513033a17'], [True],
        {'from': deployer})
    sushiswap_spell.setWhitelistLPTokens(
        ['0x795065dCc9f64b5614C407a6EFDC400DA6221FB0'], [True],
        {'from': deployer})
    balancer_spell.setWhitelistLPTokens(
        ['0xF54025aF2dc86809Be1153c1F20D77ADB7e8ecF4'], [True],
        {'from': deployer})
    curve_spell.setWhitelistLPTokens(
        ['0x6c3F90f043a72FA612cbac8115EE7e52BDe6E490'], [True],
        {'from': deployer})
Exemple #3
0
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():
    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]
    bob = accounts[2]
    renbtc = interface.IERC20Ex('0xeb4c2781e4eba804ce9a9803c67d0893436bb27d')
    wbtc = interface.IERC20Ex('0x2260fac5e5542a773aa44fbcfedf7c193bc2c599')
    eurs = interface.IERC20Ex('0xdB25f211AB05b1c97D595516F45794528a807ad8')
    seur = interface.IERC20Ex('0xD71eCFF9342A5Ced620049e616c5035F1dB98620')

    lp = interface.IERC20Ex('0x49849C98ae39Fff122806C06791Fa73784FB3675')
    pool = interface.ICurvePool('0x93054188d876f558f4a66B2EF1d97d16eDf0895B')
    lp_eurs = interface.IERC20Ex('0x194eBd173F6cDacE046C53eACcE9B953F28411d1')
    pool_eurs = interface.ICurvePool(
        '0x0Ce6a5fF5217e38315f87032CF90686C96627CAA')
    registry = interface.ICurveRegistry(
        '0x7d86446ddb609ed0f5f8684acf30380a356b2b4c')

    crrenbtc = MockCErc20.deploy(renbtc, {'from': admin})
    crwbtc = MockCErc20.deploy(wbtc, {'from': admin})
    creurs = MockCErc20.deploy(eurs, {'from': admin})
    crseur = MockCErc20.deploy(seur, {'from': admin})

    gauge = accounts.at('0xB1F2cdeC61db658F091671F5f199635aEF202CAC',
                        force=True)
    wgauge = WLiquidityGauge.deploy(
        registry, '0xD533a949740bb3306d119CC777fa900bA034cd52',
        {'from': admin})
    crv = interface.IERC20Ex(wgauge.crv())

    werc20 = WERC20.deploy({'from': admin})

    simple_oracle = SimpleOracle.deploy({'from': admin})
    simple_oracle.setETHPx(
        [renbtc, wbtc, eurs, seur],
        [2**112 * 30, 2**112 * 30, 2**112 // 700, 2**112 // 700])

    curve_oracle = CurveOracle.deploy(simple_oracle, registry, {'from': admin})
    curve_oracle.registerPool(lp)  # update pool info
    curve_oracle.registerPool(lp_eurs)  # update pool info

    core_oracle = CoreOracle.deploy({'from': admin})
    oracle = ProxyOracle.deploy(core_oracle, {'from': admin})
    oracle.setWhitelistERC1155([werc20, wgauge], True, {'from': admin})
    core_oracle.setRoute(
        [renbtc, wbtc, lp, eurs, seur, lp_eurs],
        [
            simple_oracle, simple_oracle, curve_oracle, simple_oracle,
            simple_oracle, curve_oracle
        ],
        {'from': admin},
    )
    oracle.setOracles(
        [renbtc, wbtc, lp, eurs, seur, lp_eurs],
        [
            [10000, 10000, 10000],
            [10000, 10000, 10000],
            [10000, 10000, 10000],
            [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(renbtc, crrenbtc, {'from': admin})
    homora.addBank(wbtc, crwbtc, {'from': admin})
    homora.addBank(eurs, creurs, {'from': admin})
    homora.addBank(seur, crseur, {'from': admin})

    # setup initial funds to alice
    mint_tokens(renbtc, alice)
    mint_tokens(wbtc, alice)
    mint_tokens(eurs, alice)
    mint_tokens(seur, alice)

    mint_tokens(wbtc, crwbtc)

    # check alice's funds
    print(f'Alice renbtc balance {renbtc.balanceOf(alice)}')
    print(f'Alice wbtc balance {wbtc.balanceOf(alice)}')
    print(f'Alice eurs balance {eurs.balanceOf(alice)}')
    print(f'Alice seur balance {seur.balanceOf(alice)}')

    # steal some LP from the staking pool
    mint_tokens(lp, alice)
    mint_tokens(lp, bob)
    mint_tokens(lp_eurs, alice)

    # set approval
    renbtc.approve(homora, 2**256 - 1, {'from': alice})
    renbtc.approve(crrenbtc, 2**256 - 1, {'from': alice})
    wbtc.approve(homora, 2**256 - 1, {'from': alice})
    wbtc.approve(crwbtc, 2**256 - 1, {'from': alice})

    eurs.approve(homora, 2**256 - 1, {'from': alice})
    eurs.approve(creurs, 2**256 - 1, {'from': alice})
    seur.approve(homora, 2**256 - 1, {'from': alice})
    seur.approve(crseur, 2**256 - 1, {'from': alice})

    lp.approve(homora, 2**256 - 1, {'from': alice})
    lp.approve(gauge, 2**256 - 1, {'from': bob})
    lp_eurs.approve(homora, 2**256 - 1, {'from': alice})

    curve_spell = CurveSpellV1.deploy(
        homora, werc20, '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', wgauge,
        {'from': admin})

    # register gauge
    wgauge.registerGauge(9, 0)
    wgauge.registerGauge(23, 0)

    # set up pools
    curve_spell.getPool(lp)
    curve_spell.getPool(lp_eurs)

    # first time call to reduce gas
    curve_spell.ensureApproveN(lp, 2, {'from': admin})
    curve_spell.ensureApproveN(lp_eurs, 2, {'from': admin})

    # whitelist spell in bank
    homora.setWhitelistSpells([curve_spell], [True], {'from': admin})

    # whitelist lp in spell
    curve_spell.setWhitelistLPTokens([lp, lp_eurs], [True, True],
                                     {'from': admin})

    #####################################################################################

    print(
        '========================================================================='
    )
    print('Case 1.')

    prevABal = renbtc.balanceOf(alice)
    prevBBal = wbtc.balanceOf(alice)
    prevLPBal = lp.balanceOf(alice)
    prevLPBal_bank = lp.balanceOf(homora)
    prevLPBal_gauge = lp.balanceOf(gauge)

    renbtc_amt = 1 * 10**7
    wbtc_amt = 1 * 10**7
    lp_amt = 10**13
    borrow_renbtc_amt = 0
    borrow_wbtc_amt = 0
    borrow_lp_amt = 0
    minLPMint = 0

    pid = 9
    gid = 0

    tx = homora.execute(
        0,
        curve_spell,
        curve_spell.addLiquidity2.encode_input(
            lp,  # LP
            [renbtc_amt, wbtc_amt],  # supply tokens
            lp_amt,  # supply LP
            [borrow_renbtc_amt, borrow_wbtc_amt],  # borrow tokens
            borrow_lp_amt,  # borrow LP
            minLPMint,  # min LP mint
            pid,
            gid),
        {'from': alice})

    curABal = renbtc.balanceOf(alice)
    curBBal = wbtc.balanceOf(alice)
    curLPBal = lp.balanceOf(alice)
    curLPBal_bank = lp.balanceOf(homora)
    curLPBal_gauge = lp.balanceOf(gauge)

    print('spell lp balance', lp.balanceOf(curve_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)

    _, _, _, renbtcDebt, renbtcDebtShare = homora.getBankInfo(renbtc)
    _, _, _, wbtcDebt, wbtcDebtShare = homora.getBankInfo(wbtc)

    print('bank renbtc totalDebt', renbtcDebt)
    print('bank renbtc totalShare', renbtcDebtShare)

    print('bank wbtc totalDebt', wbtcDebt)
    print('bank wbtc totalShare', wbtcDebtShare)

    print('bank prev LP balance', prevLPBal_bank)
    print('bank cur LP balance', curLPBal_bank)

    print('gauge prev LP balance', prevLPBal_gauge)
    print('gauge cur LP balance', curLPBal_gauge)

    # alice
    assert almostEqual(curABal - prevABal, -renbtc_amt), 'incorrect renbtc amt'
    assert almostEqual(curBBal - prevBBal, -wbtc_amt), 'incorrect wbtc amt'
    assert almostEqual(curLPBal - prevLPBal, -lp_amt), 'incorrect LP amt'

    # spell
    assert renbtc.balanceOf(curve_spell) == 0, 'non-zero spell renbtc balance'
    assert wbtc.balanceOf(curve_spell) == 0, 'non-zero spell wbtc balance'
    assert lp.balanceOf(curve_spell) == 0, 'non-zero spell LP balance'

    # debt
    assert renbtcDebt == borrow_renbtc_amt
    assert wbtcDebt == borrow_wbtc_amt

    _, _, collId, collSize = homora.getPositionInfo(1)
    print('collSize', collSize)

    # staking directly
    prevCrv = crv.balanceOf(bob)
    print('bob lp balance', interface.IERC20Ex(lp).balanceOf(bob))
    pid, gid = 9, 0
    gauge, _ = wgauge.gauges(pid, gid)
    print('gauge address', gauge)
    tx = interface.ILiquidityGauge(gauge).deposit(collSize, {'from': bob})

    chain.sleep(20000)

    prevAliceCrvBalance = crv.balanceOf(alice)
    print('Alice crv balance', prevAliceCrvBalance)

    # #####################################################################################

    print(
        '========================================================================='
    )
    print('Case 2. add liquidity (failed tx desired)')

    eurs_amt = 1 * 10**3
    seur_amt = 1 * 10**3
    lp_amt = 0
    borrow_eurs_amt = 0
    borrow_seur_amt = 0
    borrow_lp_amt = 0
    minLPMint = 0

    pid = 9
    gid = 0

    try:
        tx = homora.execute(
            1,
            curve_spell,
            curve_spell.addLiquidity2.encode_input(
                lp_eurs,  # lp_eurs
                [eurs_amt, seur_amt],  # supply tokens
                lp_amt,  # supply LP
                [borrow_eurs_amt, borrow_seur_amt],  # borrow tokens
                borrow_lp_amt,  # borrow LP
                minLPMint,  # min LP mint
                pid,
                gid),
            {'from': alice})
        assert False, 'tx should fail'
    except VirtualMachineError:
        pass

    # #####################################################################################

    print(
        '========================================================================='
    )
    print('Case 3. add liquidity (failed tx desired)')

    eurs_amt = 1 * 10**3
    seur_amt = 1 * 10**3
    lp_amt = 0
    borrow_eurs_amt = 0
    borrow_seur_amt = 0
    borrow_lp_amt = 0
    minLPMint = 0

    pid = 23
    gid = 0

    try:
        tx = homora.execute(
            1,
            curve_spell,
            curve_spell.addLiquidity2.encode_input(
                lp_eurs,  # lp_eurs
                [eurs_amt, seur_amt],  # supply tokens
                lp_amt,  # supply LP
                [borrow_eurs_amt, borrow_seur_amt],  # borrow tokens
                borrow_lp_amt,  # borrow LP
                minLPMint,  # min LP mint
                pid,
                gid),
            {'from': alice})
        assert False, 'tx should fail'
    except VirtualMachineError:
        pass

    # #####################################################################################

    print(
        '========================================================================='
    )
    print('Case 4. remove liquidity (failed tx desired)')

    lp_take_amt = 2**256 - 1  # max
    lp_want = 1 * 10**17
    eurs_repay = 2**256 - 1  # max
    seur_repay = 2**256 - 1  # max
    lp_repay = 0

    try:
        tx = homora.execute(
            1,
            curve_spell,
            curve_spell.removeLiquidity2.encode_input(
                lp_eurs,  # lp_eurs token
                lp_take_amt,  # LP amount to take out
                lp_want,  # LP amount to withdraw to wallet
                [eurs_repay, seur_repay],  # repay amounts
                lp_repay,  # repay LP amount
                [0, 0]  # min amounts
            ),
            {'from': alice})
        assert False, 'tx should revert'
    except VirtualMachineError:
        pass

    # #####################################################################################

    print(
        '========================================================================='
    )
    print('Case 5. remove liquidity')

    # remove liquidity from the same position
    prevABal = renbtc.balanceOf(alice)
    prevBBal = wbtc.balanceOf(alice)
    prevLPBal = lp.balanceOf(alice)
    prevLPBal_bank = lp.balanceOf(homora)
    prevLPBal_gauge = lp.balanceOf(gauge)

    _, _, _, collSize = homora.getPositionInfo(1)

    lp_take_amt = 2**256 - 1  # max
    lp_want = 1 * 10**12
    renbtc_repay = 2**256 - 1  # max
    wbtc_repay = 2**256 - 1  # max
    lp_repay = 0

    tx = homora.execute(
        1,
        curve_spell,
        curve_spell.removeLiquidity2.encode_input(
            lp,  # LP token
            lp_take_amt,  # LP amount to take out
            lp_want,  # LP amount to withdraw to wallet
            [renbtc_repay, wbtc_repay],  # repay amounts
            lp_repay,  # repay LP amount
            [0, 0]  # min amounts
        ),
        {'from': alice})

    curABal = renbtc.balanceOf(alice)
    curBBal = wbtc.balanceOf(alice)
    curLPBal = lp.balanceOf(alice)
    curLPBal_bank = lp.balanceOf(homora)
    curLPBal_gauge = lp.balanceOf(gauge)

    print('spell lp balance', lp.balanceOf(curve_spell))
    print('spell renbtc balance', renbtc.balanceOf(curve_spell))
    print('spell wbtc balance', wbtc.balanceOf(curve_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)

    _, _, _, renbtcDebt, renbtcDebtShare = homora.getBankInfo(renbtc)
    _, _, _, wbtcDebt, wbtcDebtShare = homora.getBankInfo(wbtc)
    print('bank renbtc totalDebt', renbtcDebt)
    print('bank renbtc totalDebt', renbtcDebt)

    print('bank wbtc totalShare', wbtcDebtShare)
    print('bank wbtc totalShare', wbtcDebtShare)

    print('LP want', lp_want)

    print('bank delta LP amount', curLPBal_bank - prevLPBal_bank)
    print('LP take amount', lp_take_amt)

    print('prev gauge LP balance', prevLPBal_gauge)
    print('cur gauge LP balance', curLPBal_gauge)

    print('coll size', collSize)

    # alice
    assert almostEqual(curLPBal - prevLPBal, lp_want), 'incorrect LP amt'

    # gauge
    assert almostEqual(curLPBal_gauge - prevLPBal_gauge,
                       -collSize), 'incorrect gauge LP amt'

    # spell
    assert renbtc.balanceOf(curve_spell) == 0, 'non-zero spell renbtc balance'
    assert wbtc.balanceOf(curve_spell) == 0, 'non-zero spell wbtc balance'
    assert lp.balanceOf(curve_spell) == 0, 'non-zero spell LP balance'

    # debt
    assert wbtcDebt == 0, 'wbtcDebt should be 0'
    assert renbtcDebt == 0, 'renbtcDebt should be 0'

    curAliceCrvBalance = crv.balanceOf(alice)
    print('Alice crv balance', curAliceCrvBalance)
    receivedCrv = curAliceCrvBalance - prevAliceCrvBalance
    print('received crv', receivedCrv)

    # check with staking directly
    minter = interface.ILiquidityGaugeMinter(
        interface.ILiquidityGauge(gauge).minter())
    print('minter', minter)
    tx = minter.mint(gauge, {'from': bob})
    print('tx status', tx.status)
    tx = interface.ILiquidityGauge(gauge).withdraw(collSize, {'from': bob})
    receivedCrvFromGauge = crv.balanceOf(bob) - prevCrv
    print('receivedCrvFromGauge', receivedCrvFromGauge)
    assert almostEqual(receivedCrv, receivedCrvFromGauge)

    return tx
Exemple #6
0
def main():
    admin = accounts[0]

    alice = accounts[1]
    bob = accounts[2]
    dai = interface.IERC20Ex('0x6B175474E89094C44Da98b954EedeAC495271d0F')
    usdc = interface.IERC20Ex('0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48')
    usdt = interface.IERC20Ex('0xdAC17F958D2ee523a2206206994597C13D831ec7')
    susd = interface.IERC20Ex('0x57ab1ec28d129707052df4df418d58a2d46d5f51')

    ydai = interface.IERC20Ex('0xC2cB1040220768554cf699b0d863A3cd4324ce32')
    yusdc = interface.IERC20Ex('0x26EA744E5B887E5205727f55dFBE8685e3b21951')
    yusdt = interface.IERC20Ex('0xE6354ed5bC4b393a5Aad09f21c46E101e692d447')
    ybusd = interface.IERC20Ex('0x04bC0Ab673d88aE9dbC9DA2380cB6B79C4BCa9aE')

    lp = interface.IERC20Ex('0xC25a3A3b969415c80451098fa907EC722572917F')
    pool = interface.ICurvePool('0xA5407eAE9Ba41422680e2e00537571bcC53efBfD')
    lp_busd = interface.IERC20Ex('0x3B3Ac5386837Dc563660FB6a0937DFAa5924333B')
    pool_busd = interface.ICurvePool(
        '0x79a8C46DeA5aDa233ABaFFD40F3A0A2B1e5A4F27')
    registry = interface.ICurveRegistry(
        '0x7d86446ddb609ed0f5f8684acf30380a356b2b4c')

    crdai = interface.ICErc20('0x92B767185fB3B04F881e3aC8e5B0662a027A1D9f')
    crusdc = interface.ICErc20('0x44fbebd2f576670a6c33f6fc0b00aa8c5753b322')
    crusdt = interface.ICErc20('0x797AAB1ce7c01eB727ab980762bA88e7133d2157')
    crsusd = MockCErc20.deploy(susd, {'from': admin})
    crydai = MockCErc20.deploy(ydai, {'from': admin})
    cryusdc = MockCErc20.deploy(yusdc, {'from': admin})
    cryusdt = MockCErc20.deploy(yusdt, {'from': admin})
    crybusd = MockCErc20.deploy(ybusd, {'from': admin})

    gauge = accounts.at('0xA90996896660DEcC6E997655E065b23788857849',
                        force=True)
    wgauge = WLiquidityGauge.deploy(
        registry, '0xD533a949740bb3306d119CC777fa900bA034cd52',
        {'from': admin})
    crv = interface.IERC20Ex(wgauge.crv())

    werc20 = WERC20.deploy({'from': admin})

    simple_oracle = SimpleOracle.deploy({'from': admin})
    simple_oracle.setETHPx(
        [dai, usdt, usdc, susd, ydai, yusdc, yusdt, ybusd], [
            2**112 // 700, 2**112 * 10**12 // 700, 2**112 * 10**12 // 700,
            2**112 // 700, 2**112 // 700, 2**112 * 10**12 // 700,
            2**112 * 10**12 // 700, 2**112 // 700
        ])

    curve_oracle = CurveOracle.deploy(simple_oracle, registry, {'from': admin})
    curve_oracle.registerPool(lp)  # update pool info
    curve_oracle.registerPool(lp_busd)  # update pool info

    core_oracle = CoreOracle.deploy({'from': admin})
    oracle = ProxyOracle.deploy(core_oracle, {'from': admin})
    oracle.setWhitelistERC1155([werc20, wgauge], True, {'from': admin})
    core_oracle.setRoute(
        [
            dai,
            usdc,
            usdt,
            susd,
            lp,
            ydai,
            yusdc,
            yusdt,
            ybusd,
            lp_busd,
        ],
        [
            simple_oracle, simple_oracle, simple_oracle, simple_oracle,
            curve_oracle, simple_oracle, simple_oracle, simple_oracle,
            simple_oracle, curve_oracle
        ],
        {'from': admin},
    )

    oracle.setOracles(
        [dai, usdc, usdt, susd, lp, ydai, yusdc, yusdt, ybusd, lp_busd],
        [
            [10000, 10000, 10000],
            [10000, 10000, 10000],
            [10000, 10000, 10000],
            [10000, 10000, 10000],
            [10000, 10000, 10000],
            [10000, 10000, 10000],
            [10000, 10000, 10000],
            [10000, 10000, 10000],
            [10000, 10000, 10000],
            [10000, 10000, 10000],
        ],
        {'from': admin},
    )

    # initialize
    homora = HomoraBank.deploy({'from': admin})
    print('donator ether', accounts[5].balance())
    homora.initialize(oracle, 1000, {'from': admin})  # 10% fee
    setup_bank_hack(homora)

    # add bank
    homora.addBank(dai, crdai, {'from': admin})
    homora.addBank(usdc, crusdc, {'from': admin})
    homora.addBank(usdt, crusdt, {'from': admin})
    homora.addBank(susd, crsusd, {'from': admin})
    homora.addBank(ydai, crydai, {'from': admin})
    homora.addBank(yusdc, cryusdc, {'from': admin})
    homora.addBank(yusdt, cryusdt, {'from': admin})
    homora.addBank(ybusd, crybusd, {'from': admin})

    # setup initial funds to alice
    mint_tokens(
        dai,
        alice,
    )
    mint_tokens(usdc, alice)
    mint_tokens(usdt, alice)
    mint_tokens(susd, alice)

    mint_tokens(ydai, alice)
    mint_tokens(yusdc, alice)
    mint_tokens(yusdt, alice)
    mint_tokens(ybusd, alice)

    # check alice's funds
    print(f'Alice dai balance {dai.balanceOf(alice)}')
    print(f'Alice usdc balance {usdc.balanceOf(alice)}')
    print(f'Alice usdt balance {usdt.balanceOf(alice)}')
    print(f'Alice susd balance {susd.balanceOf(alice)}')
    print(f'Alice ydai balance {ydai.balanceOf(alice)}')
    print(f'Alice yusdc balance {yusdc.balanceOf(alice)}')
    print(f'Alice yusdt balance {yusdt.balanceOf(alice)}')
    print(f'Alice ybusd balance {ybusd.balanceOf(alice)}')

    # steal some LP from the staking pool
    mint_tokens(lp, alice)
    mint_tokens(lp, bob)
    mint_tokens(lp_busd, alice)

    # set approval
    dai.approve(homora, 2**256 - 1, {'from': alice})
    dai.approve(crdai, 2**256 - 1, {'from': alice})
    usdc.approve(homora, 2**256 - 1, {'from': alice})
    usdc.approve(crusdc, 2**256 - 1, {'from': alice})
    usdt.approve(homora, 2**256 - 1, {'from': alice})
    usdt.approve(crusdt, 2**256 - 1, {'from': alice})
    susd.approve(homora, 2**256 - 1, {'from': alice})
    susd.approve(crsusd, 2**256 - 1, {'from': alice})

    ydai.approve(homora, 2**256 - 1, {'from': alice})
    ydai.approve(crydai, 2**256 - 1, {'from': alice})
    yusdc.approve(homora, 2**256 - 1, {'from': alice})
    yusdc.approve(cryusdc, 2**256 - 1, {'from': alice})
    yusdt.approve(homora, 2**256 - 1, {'from': alice})
    yusdt.approve(cryusdt, 2**256 - 1, {'from': alice})
    ybusd.approve(homora, 2**256 - 1, {'from': alice})
    ybusd.approve(crybusd, 2**256 - 1, {'from': alice})

    lp.approve(homora, 2**256 - 1, {'from': alice})
    lp.approve(gauge, 2**256 - 1, {'from': bob})
    lp_busd.approve(homora, 2**256 - 1, {'from': alice})

    curve_spell = CurveSpellV1.deploy(
        homora, werc20, '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', wgauge,
        {'from': admin})

    # register gauge
    wgauge.registerGauge(12, 0)
    wgauge.registerGauge(1, 0)

    # set up pools
    curve_spell.getPool(lp)
    curve_spell.getPool(lp_busd)

    # first time call to reduce gas
    curve_spell.ensureApproveN(lp, 4, {'from': admin})
    curve_spell.ensureApproveN(lp_busd, 4, {'from': admin})

    # whitelist spell in bank
    homora.setWhitelistSpells([curve_spell], [True], {'from': admin})

    # whitelist token in bank
    homora.setWhitelistTokens([dai, usdt, usdc, susd],
                              [True, True, True, True], {'from': admin})

    # whitelist lp in spell
    curve_spell.setWhitelistLPTokens([lp], [True], {'from': admin})

    #####################################################################################

    print(
        '========================================================================='
    )
    print('Case 1.')

    prevABal = dai.balanceOf(alice)
    prevBBal = usdc.balanceOf(alice)
    prevCBal = usdt.balanceOf(alice)
    prevDBal = susd.balanceOf(alice)
    prevLPBal = lp.balanceOf(alice)
    prevLPBal_bank = lp.balanceOf(homora)
    prevLPBal_gauge = lp.balanceOf(gauge)

    dai_amt = 200 * 10**18
    usdc_amt = 1000 * 10**6
    usdt_amt = 1000 * 10**6
    susd_amt = 1000 * 10**18
    lp_amt = 0
    borrow_dai_amt = 10 * 10**18
    borrow_usdc_amt = 10**6
    borrow_usdt_amt = 0
    borrow_susd_amt = 0
    borrow_lp_amt = 0
    minLPMint = 0

    pid = 12
    gid = 0

    tx = homora.execute(
        0,
        curve_spell,
        curve_spell.addLiquidity4.encode_input(
            lp,  # LP
            [dai_amt, usdc_amt, usdt_amt, susd_amt],  # supply tokens
            lp_amt,  # supply LP
            [
                borrow_dai_amt, borrow_usdc_amt, borrow_usdt_amt,
                borrow_susd_amt
            ],  # borrow tokens
            borrow_lp_amt,  # borrow LP
            minLPMint,  # min LP mint
            pid,
            gid),
        {'from': alice})

    curABal = dai.balanceOf(alice)
    curBBal = usdc.balanceOf(alice)
    curCBal = usdt.balanceOf(alice)
    curDBal = susd.balanceOf(alice)
    curLPBal = lp.balanceOf(alice)
    curLPBal_bank = lp.balanceOf(homora)
    curLPBal_gauge = lp.balanceOf(gauge)

    print('spell lp balance', lp.balanceOf(curve_spell))
    print('Alice delta A balance', curABal - prevABal)
    print('Alice delta B balance', curBBal - prevBBal)
    print('Alice delta C balance', curCBal - prevCBal)
    print('add liquidity gas', tx.gas_used)
    print('bank lp balance', curLPBal_bank)

    _, _, _, daiDebt, daiDebtShare = homora.getBankInfo(dai)
    _, _, _, usdcDebt, usdcDebtShare = homora.getBankInfo(usdc)
    _, _, _, usdtDebt, usdtDebtShare = homora.getBankInfo(usdt)
    _, _, _, susdDebt, susdDebtShare = homora.getBankInfo(susd)

    print('bank dai totalDebt', daiDebt)
    print('bank dai totalShare', daiDebtShare)

    print('bank usdt totalDebt', usdtDebt)
    print('bank usdt totalShare', usdtDebtShare)

    print('bank usdc totalDebt', usdcDebt)
    print('bank usdc totalShare', usdcDebtShare)

    print('bank susd totalDebt', susdDebt)
    print('bank susd totalShare', susdDebtShare)

    print('bank prev LP balance', prevLPBal_bank)
    print('bank cur LP balance', curLPBal_bank)

    print('gauge prev LP balance', prevLPBal_gauge)
    print('gauge cur LP balance', curLPBal_gauge)

    # alice
    assert almostEqual(curABal - prevABal, -dai_amt), 'incorrect DAI amt'
    assert almostEqual(curBBal - prevBBal, -usdc_amt), 'incorrect USDC amt'
    assert almostEqual(curCBal - prevCBal, -usdt_amt), 'incorrect USDT amt'
    assert almostEqual(curDBal - prevDBal, -susd_amt), 'incorrect SUSD amt'
    assert almostEqual(curLPBal - prevLPBal, -lp_amt), 'incorrect LP amt'

    # spell
    assert dai.balanceOf(curve_spell) == 0, 'non-zero spell DAI balance'
    assert usdc.balanceOf(curve_spell) == 0, 'non-zero spell USDC balance'
    assert usdt.balanceOf(curve_spell) == 0, 'non-zero spell USDT balance'
    assert susd.balanceOf(curve_spell) == 0, 'non-zero spell SUSD balance'
    assert lp.balanceOf(curve_spell) == 0, 'non-zero spell LP balance'

    # debt
    assert daiDebt == borrow_dai_amt
    assert usdcDebt == borrow_usdc_amt
    assert usdtDebt == borrow_usdt_amt
    assert susdDebt == borrow_susd_amt

    # #####################################################################################

    print(
        '========================================================================='
    )
    print('Case 2. harvest first time')

    prevCRVBalance = crv.balanceOf(alice)
    print('Alice CRV balance before harvest', prevCRVBalance)
    _, _, collId, collSize = homora.getPositionInfo(1)
    print('collSize', collSize)

    # staking directly
    prevCrv = crv.balanceOf(bob)
    print('bob lp balance', interface.IERC20Ex(lp).balanceOf(bob))
    pid, gid = 12, 0
    gauge, _ = wgauge.gauges(pid, gid)
    tx = interface.ILiquidityGauge(gauge).deposit(collSize, {'from': bob})

    chain.sleep(20000)

    tx = homora.execute(1, curve_spell, curve_spell.harvest.encode_input(),
                        {'from': alice})

    print('tx gas used', tx.gas_used)

    curCRVBalance = crv.balanceOf(alice)
    print('Alice CRV balance after harvest', curCRVBalance)
    receivedCrv = curCRVBalance - prevCRVBalance

    # check with staking directly
    minter = interface.ILiquidityGaugeMinter(
        interface.ILiquidityGauge(gauge).minter())
    print('minter', minter)
    tx = minter.mint(gauge, {'from': bob})
    print('tx status', tx.status)
    tx = interface.ILiquidityGauge(gauge).withdraw(collSize, {'from': bob})
    receivedCrvFromGauge = crv.balanceOf(bob) - prevCrv
    print('receivedCrvFromGauge', receivedCrvFromGauge)
    assert almostEqual(receivedCrv, receivedCrvFromGauge)

    # #####################################################################################

    print(
        '========================================================================='
    )
    print('Case 3. harvest second time')

    prevCRVBalance = crv.balanceOf(alice)
    print('Alice CRV balance before harvest', prevCRVBalance)
    _, _, collId, collSize = homora.getPositionInfo(1)
    print('collSize', collSize)

    # staking directly
    prevCrv = crv.balanceOf(bob)
    print('bob lp balance', interface.IERC20Ex(lp).balanceOf(bob))
    pid, gid = 12, 0
    gauge, _ = wgauge.gauges(pid, gid)
    tx = interface.ILiquidityGauge(gauge).deposit(collSize, {'from': bob})

    chain.sleep(20000)

    tx = homora.execute(1, curve_spell, curve_spell.harvest.encode_input(),
                        {'from': alice})

    print('tx gas used', tx.gas_used)

    curCRVBalance = crv.balanceOf(alice)
    print('Alice CRV balance after harvest', curCRVBalance)
    receivedCrv = curCRVBalance - prevCRVBalance

    # check with staking directly
    minter = interface.ILiquidityGaugeMinter(
        interface.ILiquidityGauge(gauge).minter())
    print('minter', minter)
    tx = minter.mint(gauge, {'from': bob})
    print('tx status', tx.status)
    tx = interface.ILiquidityGauge(gauge).withdraw(collSize, {'from': bob})
    receivedCrvFromGauge = crv.balanceOf(bob) - prevCrv
    print('receivedCrvFromGauge', receivedCrvFromGauge)
    assert almostEqual(receivedCrv, receivedCrvFromGauge)

    return tx
Exemple #7
0
def main():
    admin = accounts[0]

    alice = accounts[1]
    bob = accounts[2]
    dai = interface.IERC20Ex('0x6B175474E89094C44Da98b954EedeAC495271d0F')
    usdc = interface.IERC20Ex('0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48')
    usdt = interface.IERC20Ex('0xdAC17F958D2ee523a2206206994597C13D831ec7')
    adai = interface.IERC20Ex('0x028171bCA77440897B824Ca71D1c56caC55b68A3')
    ausdc = interface.IERC20Ex('0xBcca60bB61934080951369a648Fb03DF4F96263C')
    ausdt = interface.IERC20Ex('0x3Ed3B47Dd13EC9a98b44e6204A523E766B225811')

    lp = interface.IERC20Ex('0x6c3f90f043a72fa612cbac8115ee7e52bde6e490')
    pool = interface.ICurvePool('0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7')
    lp_aave = interface.IERC20Ex('0xFd2a8fA60Abd58Efe3EeE34dd494cD491dC14900')
    pool_aave = interface.ICurvePool(
        '0xDeBF20617708857ebe4F679508E7b7863a8A8EeE')
    registry = interface.ICurveRegistry(
        '0x7d86446ddb609ed0f5f8684acf30380a356b2b4c')

    crdai = interface.ICErc20('0x92B767185fB3B04F881e3aC8e5B0662a027A1D9f')
    crusdc = interface.ICErc20('0x44fbebd2f576670a6c33f6fc0b00aa8c5753b322')
    crusdt = interface.ICErc20('0x797AAB1ce7c01eB727ab980762bA88e7133d2157')
    cradai = MockCErc20.deploy(adai, {'from': admin})
    crausdc = MockCErc20.deploy(ausdc, {'from': admin})
    crausdt = MockCErc20.deploy(ausdt, {'from': admin})

    gauge = accounts.at('0xbFcF63294aD7105dEa65aA58F8AE5BE2D9d0952A',
                        force=True)
    wgauge = WLiquidityGauge.deploy(
        registry, '0xD533a949740bb3306d119CC777fa900bA034cd52',
        {'from': admin})
    crv = interface.IERC20Ex(wgauge.crv())

    werc20 = WERC20.deploy({'from': admin})

    simple_oracle = SimpleOracle.deploy({'from': admin})
    simple_oracle.setETHPx([dai, usdt, usdc, adai, ausdc, ausdt], [
        2**112 // 700, 2**112 // 700, 2**112 // 700, 2**112 // 700,
        2**112 // 700, 2**112 // 700
    ])

    curve_oracle = CurveOracle.deploy(simple_oracle, registry, {'from': admin})
    curve_oracle.registerPool(lp)  # update pool info
    curve_oracle.registerPool(lp_aave)  # update pool info

    core_oracle = CoreOracle.deploy({'from': admin})
    oracle = ProxyOracle.deploy(core_oracle, {'from': admin})
    oracle.setWhitelistERC1155([werc20, wgauge], True, {'from': admin})
    core_oracle.setRoute(
        [dai, usdc, usdt, lp, adai, ausdc, ausdt, lp_aave],
        [
            simple_oracle, simple_oracle, simple_oracle, curve_oracle,
            simple_oracle, simple_oracle, simple_oracle, curve_oracle
        ],
        {'from': admin},
    )

    oracle.setOracles(
        [dai, usdc, usdt, lp, adai, ausdc, ausdt, lp_aave],
        [
            [10000, 10000, 10000],
            [10000, 10000, 10000],
            [10000, 10000, 10000],
            [10000, 10000, 10000],
            [10000, 10000, 10000],
            [10000, 10000, 10000],
            [10000, 10000, 10000],
            [10000, 10000, 10000],
        ],
        {'from': admin},
    )

    # initialize
    homora = HomoraBank.deploy({'from': admin})
    print('donator ether', accounts[5].balance())
    homora.initialize(oracle, 1000, {'from': admin})  # 10% fee
    setup_bank_hack(homora)

    # add bank
    homora.addBank(dai, crdai, {'from': admin})
    homora.addBank(usdc, crusdc, {'from': admin})
    homora.addBank(usdt, crusdt, {'from': admin})
    homora.addBank(adai, cradai, {'from': admin})
    homora.addBank(ausdc, crausdc, {'from': admin})
    homora.addBank(ausdt, crausdt, {'from': admin})

    # setup initial funds 10^6 USDT + 10^6 USDC + 10^6 DAI to alice
    mint_tokens(
        dai,
        alice,
    )
    mint_tokens(usdc, alice)
    mint_tokens(usdt, alice)
    mint_tokens(adai, alice)
    mint_tokens(ausdc, alice)
    mint_tokens(ausdt, alice)

    # check alice's funds
    print(f'Alice dai balance {dai.balanceOf(alice)}')
    print(f'Alice usdc balance {usdc.balanceOf(alice)}')
    print(f'Alice usdt balance {usdt.balanceOf(alice)}')
    print(f'Alice adai balance {adai.balanceOf(alice)}')
    print(f'Alice ausdc balance {ausdc.balanceOf(alice)}')
    print(f'Alice ausdt balance {ausdt.balanceOf(alice)}')

    # steal some LP from the staking pool
    mint_tokens(lp, alice)
    mint_tokens(lp, bob)
    mint_tokens(lp_aave, alice)

    # set approval
    dai.approve(homora, 2**256 - 1, {'from': alice})
    dai.approve(crdai, 2**256 - 1, {'from': alice})
    usdc.approve(homora, 2**256 - 1, {'from': alice})
    usdc.approve(crusdc, 2**256 - 1, {'from': alice})
    usdt.approve(homora, 2**256 - 1, {'from': alice})
    usdt.approve(crusdt, 2**256 - 1, {'from': alice})

    adai.approve(homora, 2**256 - 1, {'from': alice})
    adai.approve(cradai, 2**256 - 1, {'from': alice})
    ausdc.approve(homora, 2**256 - 1, {'from': alice})
    ausdc.approve(crausdc, 2**256 - 1, {'from': alice})
    ausdt.approve(homora, 2**256 - 1, {'from': alice})
    ausdt.approve(crausdt, 2**256 - 1, {'from': alice})

    lp.approve(homora, 2**256 - 1, {'from': alice})
    lp.approve(gauge, 2**256 - 1, {'from': bob})
    lp_aave.approve(homora, 2**256 - 1, {'from': alice})

    curve_spell = CurveSpellV1.deploy(
        homora, werc20, '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', wgauge,
        {'from': admin})

    # register gauge
    wgauge.registerGauge(0, 0)
    wgauge.registerGauge(25, 0)

    # set up pools
    curve_spell.getPool(lp)
    curve_spell.getPool(lp_aave)

    # first time call to reduce gas
    curve_spell.ensureApproveN(lp, 3, {'from': admin})
    curve_spell.ensureApproveN(lp_aave, 3, {'from': admin})

    #####################################################################################

    print(
        '========================================================================='
    )
    print('Case 1.')

    prevABal = dai.balanceOf(alice)
    prevBBal = usdc.balanceOf(alice)
    prevCBal = usdt.balanceOf(alice)
    prevLPBal = lp.balanceOf(alice)
    prevLPBal_bank = lp.balanceOf(homora)
    prevLPBal_gauge = lp.balanceOf(gauge)

    dai_amt = 200 * 10**18
    usdc_amt = 500 * 10**6
    usdt_amt = 400 * 10**6
    lp_amt = 1 * 10**18
    borrow_dai_amt = 0
    borrow_usdc_amt = 20 * 10**6
    borrow_usdt_amt = 0
    borrow_lp_amt = 0
    minLPMint = 0

    pid = 0
    gid = 0

    tx = homora.execute(
        0,
        curve_spell,
        curve_spell.addLiquidity3.encode_input(
            lp,  # LP
            [dai_amt, usdc_amt, usdt_amt],  # supply tokens
            lp_amt,  # supply LP
            [borrow_dai_amt, borrow_usdc_amt, borrow_usdt_amt
             ],  # borrow tokens
            borrow_lp_amt,  # borrow LP
            minLPMint,  # min LP mint
            pid,
            gid),
        {'from': alice})

    curABal = dai.balanceOf(alice)
    curBBal = usdc.balanceOf(alice)
    curCBal = usdt.balanceOf(alice)
    curLPBal = lp.balanceOf(alice)
    curLPBal_bank = lp.balanceOf(homora)
    curLPBal_gauge = lp.balanceOf(gauge)

    print('spell lp balance', lp.balanceOf(curve_spell))
    print('Alice delta A balance', curABal - prevABal)
    print('Alice delta B balance', curBBal - prevBBal)
    print('Alice delta C balance', curCBal - prevCBal)
    print('add liquidity gas', tx.gas_used)
    print('bank lp balance', curLPBal_bank)

    _, _, _, daiDebt, daiDebtShare = homora.getBankInfo(dai)
    _, _, _, usdcDebt, usdcDebtShare = homora.getBankInfo(usdc)
    _, _, _, usdtDebt, usdtDebtShare = homora.getBankInfo(usdt)
    _, _, _, lpDebt, usdcDebtShare = homora.getBankInfo(usdc)

    print('bank dai totalDebt', daiDebt)
    print('bank dai totalShare', daiDebtShare)

    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('gauge prev LP balance', prevLPBal_gauge)
    print('gauge cur LP balance', curLPBal_gauge)

    # alice
    assert almostEqual(curABal - prevABal, -dai_amt), 'incorrect DAI amt'
    assert almostEqual(curBBal - prevBBal, -usdc_amt), 'incorrect USDC amt'
    assert almostEqual(curCBal - prevCBal, -usdt_amt), 'incorrect USDT amt'
    assert almostEqual(curLPBal - prevLPBal, -lp_amt), 'incorrect LP amt'

    # spell
    assert dai.balanceOf(curve_spell) == 0, 'non-zero spell DAI balance'
    assert usdc.balanceOf(curve_spell) == 0, 'non-zero spell USDC balance'
    assert usdt.balanceOf(curve_spell) == 0, 'non-zero spell USDT balance'
    assert lp.balanceOf(curve_spell) == 0, 'non-zero spell LP balance'

    # debt
    assert daiDebt == borrow_dai_amt
    assert usdcDebt == borrow_usdc_amt
    assert usdtDebt == borrow_usdt_amt

    _, _, collId, collSize = homora.getPositionInfo(1)
    print('collSize', collSize)

    # staking directly
    prevCrv = crv.balanceOf(bob)
    print('bob lp balance', interface.IERC20Ex(lp).balanceOf(bob))
    pid, gid = 0, 0
    gauge, _ = wgauge.gauges(pid, gid)
    tx = interface.ILiquidityGauge(gauge).deposit(collSize, {'from': bob})

    chain.sleep(20000)

    prevAliceCrvBalance = crv.balanceOf(alice)
    print('Alice crv balance', prevAliceCrvBalance)

    # #####################################################################################

    print(
        '========================================================================='
    )
    print('Case 2. add liquidity (failed tx desired)')

    adai_amt = 200 * 10**18
    ausdc_amt = 500 * 10**6
    ausdt_amt = 400 * 10**6
    lp_amt = 0
    borrow_adai_amt = 0
    borrow_ausdc_amt = 0
    borrow_ausdt_amt = 0
    borrow_lp_amt = 0
    minLPMint = 0

    pid = 0
    gid = 0

    try:
        tx = homora.execute(
            1,
            curve_spell,
            curve_spell.addLiquidity3.encode_input(
                lp_aave,  # LP_aave
                [adai_amt, ausdc_amt, ausdt_amt],  # supply tokens
                lp_amt,  # supply LP
                [borrow_adai_amt, borrow_ausdc_amt, borrow_ausdt_amt
                 ],  # borrow tokens
                borrow_lp_amt,  # borrow LP
                minLPMint,  # min LP mint
                pid,
                gid),
            {'from': alice})
        assert False, 'tx should fail'
    except VirtualMachineError:
        pass

    # #####################################################################################

    print(
        '========================================================================='
    )
    print('Case 3. add liquidity (failed tx desired)')

    adai_amt = 200 * 10**18
    ausdc_amt = 500 * 10**6
    ausdt_amt = 400 * 10**6
    lp_amt = 0
    borrow_adai_amt = 0
    borrow_ausdc_amt = 0
    borrow_ausdt_amt = 0
    borrow_lp_amt = 0
    minLPMint = 0

    pid = 25
    gid = 0

    try:
        tx = homora.execute(
            1,
            curve_spell,
            curve_spell.addLiquidity3.encode_input(
                lp_aave,  # LP_aave
                [adai_amt, ausdc_amt, ausdt_amt],  # supply tokens
                lp_amt,  # supply LP
                [borrow_adai_amt, borrow_ausdc_amt, borrow_ausdt_amt
                 ],  # borrow tokens
                borrow_lp_amt,  # borrow LP
                minLPMint,  # min LP mint
                pid,
                gid),
            {'from': alice})
        assert False, 'tx should fail'
    except VirtualMachineError:
        pass

    # #####################################################################################

    print(
        '========================================================================='
    )
    print('Case 4. remove liquidity (failed tx desired)')

    lp_take_amt = 2**256 - 1  # max
    lp_want = 1 * 10**17
    adai_repay = 2**256 - 1  # max
    ausdc_repay = 2**256 - 1  # max
    ausdt_repay = 2**256 - 1  # max
    lp_repay = 0

    try:
        tx = homora.execute(
            1,
            curve_spell,
            curve_spell.removeLiquidity3.encode_input(
                lp_aave,  # LP_aave token
                lp_take_amt,  # LP amount to take out
                lp_want,  # LP amount to withdraw to wallet
                [adai_repay, ausdc_repay, ausdt_repay],  # repay amounts
                lp_repay,  # repay LP amount
                [0, 0, 0]  # min amounts
            ),
            {'from': alice})
        assert False, 'tx should revert'
    except VirtualMachineError:
        pass

    # #####################################################################################

    print(
        '========================================================================='
    )
    print('Case 5. remove liqudiity')

    # remove liquidity from the same position
    prevABal = dai.balanceOf(alice)
    prevBBal = usdc.balanceOf(alice)
    prevCBal = usdt.balanceOf(alice)
    prevLPBal = lp.balanceOf(alice)
    prevLPBal_bank = lp.balanceOf(homora)
    prevLPBal_gauge = lp.balanceOf(gauge)

    _, _, _, collSize = homora.getPositionInfo(1)

    lp_take_amt = 2**256 - 1  # max
    lp_want = 1 * 10**17
    dai_repay = 2**256 - 1  # max
    usdc_repay = 2**256 - 1  # max
    usdt_repay = 2**256 - 1  # max
    lp_repay = 0

    tx = homora.execute(
        1,
        curve_spell,
        curve_spell.removeLiquidity3.encode_input(
            lp,  # LP token
            lp_take_amt,  # LP amount to take out
            lp_want,  # LP amount to withdraw to wallet
            [dai_repay, usdc_repay, usdt_repay],  # repay amounts
            lp_repay,  # repay LP amount
            [0, 0, 0]  # min amounts
        ),
        {'from': alice})

    curABal = dai.balanceOf(alice)
    curBBal = usdc.balanceOf(alice)
    curCBal = usdt.balanceOf(alice)
    curLPBal = lp.balanceOf(alice)
    curLPBal_bank = lp.balanceOf(homora)
    curLPBal_gauge = lp.balanceOf(gauge)

    print('spell lp balance', lp.balanceOf(curve_spell))
    print('spell dai balance', dai.balanceOf(curve_spell))
    print('spell usdc balance', usdc.balanceOf(curve_spell))
    print('spell usdt balance', usdt.balanceOf(curve_spell))
    print('Alice delta A balance', curABal - prevABal)
    print('Alice delta B balance', curBBal - prevBBal)
    print('Alice delta C balance', curCBal - prevCBal)
    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)

    _, _, _, daiDebt, daiDebtShare = homora.getBankInfo(dai)
    _, _, _, usdcDebt, usdcDebtShare = homora.getBankInfo(usdc)
    _, _, _, usdtDebt, usdtDebtShare = homora.getBankInfo(usdt)
    print('bank dai totalDebt', daiDebt)
    print('bank dai totalDebt', daiDebt)

    print('bank usdc totalShare', usdcDebtShare)
    print('bank usdc totalShare', usdcDebtShare)

    print('bank usdt totalDebt', usdtDebt)
    print('bank usdt totalShare', usdtDebtShare)

    print('LP want', lp_want)

    print('bank delta LP amount', curLPBal_bank - prevLPBal_bank)
    print('LP take amount', lp_take_amt)

    print('prev gauge LP balance', prevLPBal_gauge)
    print('cur gauge LP balance', curLPBal_gauge)

    print('coll size', collSize)

    # alice
    assert almostEqual(curLPBal - prevLPBal, lp_want), 'incorrect LP amt'

    # gauge
    assert almostEqual(curLPBal_gauge - prevLPBal_gauge,
                       -collSize), 'incorrect gauge LP amt'

    # spell
    assert dai.balanceOf(curve_spell) == 0, 'non-zero spell DAI balance'
    assert usdc.balanceOf(curve_spell) == 0, 'non-zero spell USDC balance'
    assert usdt.balanceOf(curve_spell) == 0, 'non-zero spell USDT balance'
    assert lp.balanceOf(curve_spell) == 0, 'non-zero spell LP balance'

    # debt
    assert usdcDebt == 0, 'usdcDebt should be 0'
    assert daiDebt == 0, 'daiDebt should be 0'
    assert usdtDebt == 0, 'usdtDebt should be 0'

    curAliceCrvBalance = crv.balanceOf(alice)
    print('Alice crv balance', curAliceCrvBalance)
    receivedCrv = curAliceCrvBalance - prevAliceCrvBalance
    print('received crv', receivedCrv)

    # check with staking directly
    minter = interface.ILiquidityGaugeMinter(
        interface.ILiquidityGauge(gauge).minter())
    print('minter', minter)
    tx = minter.mint(gauge, {'from': bob})
    print('tx status', tx.status)
    tx = interface.ILiquidityGauge(gauge).withdraw(collSize, {'from': bob})
    receivedCrvFromGauge = crv.balanceOf(bob) - prevCrv
    print('receivedCrvFromGauge', receivedCrvFromGauge)
    assert almostEqual(receivedCrv, receivedCrvFromGauge)

    return tx
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():
    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')
Exemple #10
0
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():
    admin = accounts[0]

    alice = accounts[1]
    bob = accounts[2]

    dai = interface.IERC20Ex('0x6B175474E89094C44Da98b954EedeAC495271d0F')
    usdc = interface.IERC20Ex('0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48')
    usdt = interface.IERC20Ex('0xdAC17F958D2ee523a2206206994597C13D831ec7')
    wbtc = interface.IERC20Ex('0x2260fac5e5542a773aa44fbcfedf7c193bc2c599')
    renbtc = interface.IERC20Ex('0xeb4c2781e4eba804ce9a9803c67d0893436bb27d')
    crv = interface.IERC20Ex('0xD533a949740bb3306d119CC777fa900bA034cd52')

    lp_3pool = interface.IERC20Ex('0x6c3f90f043a72fa612cbac8115ee7e52bde6e490')
    lp_btc = interface.IERC20Ex('0x49849c98ae39fff122806c06791fa73784fb3675')
    pool_3pool = interface.ICurvePool(
        '0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7')
    pool_btc = interface.ICurvePool(
        '0x93054188d876f558f4a66B2EF1d97d16eDf0895B')
    registry = interface.ICurveRegistry(
        '0x7d86446ddb609ed0f5f8684acf30380a356b2b4c')

    gauge = accounts.at('0xbFcF63294aD7105dEa65aA58F8AE5BE2D9d0952A',
                        force=True)
    wgauge = WLiquidityGauge.deploy(
        registry, '0xD533a949740bb3306d119CC777fa900bA034cd52',
        {'from': admin})

    # set approval
    dai.approve(wgauge, 2**256 - 1, {'from': alice})
    usdc.approve(wgauge, 2**256 - 1, {'from': alice})
    usdt.approve(wgauge, 2**256 - 1, {'from': alice})
    renbtc.approve(wgauge, 2**256 - 1, {'from': alice})
    wbtc.approve(wgauge, 2**256 - 1, {'from': alice})
    lp_3pool.approve(wgauge, 2**256 - 1, {'from': alice})
    lp_3pool.approve(gauge, 2**256 - 1, {'from': alice})
    lp_btc.approve(wgauge, 2**256 - 1, {'from': alice})
    lp_btc.approve(gauge, 2**256 - 1, {'from': alice})

    dai.approve(wgauge, 2**256 - 1, {'from': bob})
    usdc.approve(wgauge, 2**256 - 1, {'from': bob})
    usdt.approve(wgauge, 2**256 - 1, {'from': bob})
    renbtc.approve(wgauge, 2**256 - 1, {'from': bob})
    wbtc.approve(wgauge, 2**256 - 1, {'from': bob})
    lp_3pool.approve(wgauge, 2**256 - 1, {'from': bob})
    lp_3pool.approve(gauge, 2**256 - 1, {'from': bob})
    lp_btc.approve(wgauge, 2**256 - 1, {'from': bob})
    lp_btc.approve(gauge, 2**256 - 1, {'from': bob})

    # setup initial funds to alice
    mint_tokens(dai, alice)
    mint_tokens(usdc, alice)
    mint_tokens(usdt, alice)
    mint_tokens(renbtc, alice)
    mint_tokens(wbtc, alice)

    mint_tokens(dai, bob)
    mint_tokens(usdc, bob)
    mint_tokens(usdt, bob)
    mint_tokens(renbtc, bob)
    mint_tokens(wbtc, bob)

    # steal some LP from the staking pool
    mint_tokens(lp_3pool, alice)
    mint_tokens(lp_btc, alice)

    mint_tokens(lp_3pool, bob)
    mint_tokens(lp_btc, bob)

    # register gauges
    wgauge.registerGauge(0, 0, {'from': admin})
    wgauge.registerGauge(9, 0, {'from': admin})

    ######################################################################
    # Check encoding and decoding ids
    print(
        '######################################################################'
    )
    print('Case 1.')

    # check 3pool
    pid = 0
    gid = 0
    crvPerShare = 210
    encoded_id = wgauge.encodeId(pid, gid, crvPerShare)
    print('encoded id', encoded_id)
    assert (encoded_id >> 248) == pid
    assert (encoded_id >> 240) & ((1 << 8) - 1) == gid
    assert (encoded_id & ((1 << 240) - 1)) == crvPerShare

    d_pid, d_gid, d_crvPerShare = wgauge.decodeId(encoded_id)
    print('decoded pid', d_pid)
    print('decoded gid', d_gid)
    print('decoded crvPerShare', d_crvPerShare)
    assert d_pid == pid
    assert d_gid == gid
    assert d_crvPerShare == crvPerShare

    # check renbtc pool
    pid = 9
    gid = 0
    crvPerShare = 100
    encoded_id = wgauge.encodeId(pid, gid, crvPerShare)
    print('encoded id', encoded_id)
    assert (encoded_id >> 248) == pid
    assert (encoded_id >> 240) & ((1 << 8) - 1) == gid
    assert (encoded_id & ((1 << 240) - 1)) == crvPerShare

    d_pid, d_gid, d_crvPerShare = wgauge.decodeId(encoded_id)
    print('decoded pid', d_pid)
    print('decoded gid', d_gid)
    print('decoded crvPerShare', d_crvPerShare)
    assert d_pid == pid
    assert d_gid == gid
    assert d_crvPerShare == crvPerShare

    ######################################################################
    # check getUnderlyingToken

    pid = 0
    gid = 0
    crvPerShare = 200
    id_num = wgauge.encodeId(pid, gid, crvPerShare)
    lpToken = wgauge.getUnderlyingToken(id_num)
    print('lpToken', lpToken)
    assert lpToken == lp_3pool

    pid = 9
    gid = 0
    crvPerShare = 100
    id_num = wgauge.encodeId(pid, gid, crvPerShare)
    lpToken = wgauge.getUnderlyingToken(id_num)
    print('lpToken', lpToken)
    assert lpToken == lp_btc

    ######################################################################
    # check mint & burn
    print(
        '######################################################################'
    )
    print('Case 2.')

    pid = 0
    gid = 0
    amt = 10**18

    print('alice lp 3pool balance', lp_3pool.balanceOf(alice))

    # mint
    tx = wgauge.mint(pid, gid, amt, {'from': alice})
    encoded_id = tx.return_value
    print('tx status', tx.status)
    print('encoded id', encoded_id)
    gauge, prevAccCrvPerShare = wgauge.gauges(pid, gid)
    print('gauge', gauge)
    print('prevAccCrvPerShare', prevAccCrvPerShare)
    print('alice wlp_3pool balance', wgauge.balanceOf(alice, encoded_id))
    assert tx.status == 1
    assert wgauge.balanceOf(alice, encoded_id) == amt

    chain.sleep(20000)

    # burn exact
    prevCrvBalance = crv.balanceOf(alice)
    tx = wgauge.burn(encoded_id, amt, {'from': alice})

    print('tx status', tx.status)
    print('alice wlp_3pool balance', wgauge.balanceOf(alice, encoded_id))

    print('alice crv balance', crv.balanceOf(alice))
    receivedCrv = crv.balanceOf(alice) - prevCrvBalance

    assert tx.status == 1
    assert tx.return_value == pid
    assert wgauge.balanceOf(alice, encoded_id) == 0  # remove all

    # check reward same as staking directly
    prevCrv = crv.balanceOf(alice)
    print('alice lp_3pool balance',
          interface.IERC20Ex(lp_3pool).balanceOf(alice))
    gauge, _ = wgauge.gauges(pid, gid)
    tx = interface.ILiquidityGauge(gauge).deposit(amt, {'from': alice})
    chain.sleep(20000)
    minter = interface.ILiquidityGaugeMinter(
        interface.ILiquidityGauge(gauge).minter())
    print('minter', minter)
    tx = minter.mint(gauge, {'from': alice})
    print('tx status', tx.status)
    tx = interface.ILiquidityGauge(gauge).withdraw(amt, {'from': alice})
    receivedCrvFromGauge = crv.balanceOf(alice) - prevCrv
    print('receivedCrvFromGauge', receivedCrvFromGauge)
    assert almostEqual(receivedCrv, receivedCrvFromGauge)

    ######################################################################
    # check mint & burn max_int

    print(
        '######################################################################'
    )
    print('Case 3.')

    pid = 0
    gid = 0
    amt = 10**18

    print('alice lp 3pool balance', lp_3pool.balanceOf(alice))

    # mint alice
    tx = wgauge.mint(pid, gid, amt, {'from': alice})
    encoded_id = tx.return_value
    print('tx status', tx.status)
    print('encoded id', encoded_id)
    gauge, prevAccCrvPerShare = wgauge.gauges(pid, gid)
    print('gauge', gauge)
    print('prevAccCrvPerShare', prevAccCrvPerShare)
    print('alice wlp_3pool balance', wgauge.balanceOf(alice, encoded_id))
    assert tx.status == 1
    assert wgauge.balanceOf(alice, encoded_id) == amt

    # mint bob
    prevCrvBob = crv.balanceOf(bob)
    print('bob lp_3pool balance', interface.IERC20Ex(lp_3pool).balanceOf(bob))
    gauge, _ = wgauge.gauges(pid, gid)
    tx = interface.ILiquidityGauge(gauge).deposit(amt, {'from': bob})

    chain.sleep(10000)

    # burn max_int alice
    prevCrvBalance = crv.balanceOf(alice)
    tx = wgauge.burn(encoded_id, 2**256 - 1, {'from': alice})

    print('tx status', tx.status)
    print('alice wlp_3pool balance', wgauge.balanceOf(alice, encoded_id))

    print('alice crv balance', crv.balanceOf(alice))
    receivedCrv = crv.balanceOf(alice) - prevCrvBalance

    assert tx.status == 1
    assert tx.return_value == pid
    assert wgauge.balanceOf(alice, encoded_id) == 0  # remove all

    # burn all bob
    minter = interface.ILiquidityGaugeMinter(
        interface.ILiquidityGauge(gauge).minter())
    print('minter', minter)
    tx = minter.mint(gauge, {'from': bob})
    print('tx status', tx.status)
    tx = interface.ILiquidityGauge(gauge).withdraw(amt, {'from': bob})
    receivedCrvFromGauge = crv.balanceOf(bob) - prevCrvBob

    print('receivedCrv', receivedCrv)
    print('receivedCrvFromGauge', receivedCrvFromGauge)
    assert almostEqual(receivedCrv, receivedCrvFromGauge)

    ######################################################################
    # check mint & burn (try more than available--revert, half, then remaining)

    print(
        '######################################################################'
    )
    print('Case 4.')

    pid = 0
    gid = 0
    amt = 10**18

    print('alice lp 3pool balance', lp_3pool.balanceOf(alice))

    # mint alice
    tx = wgauge.mint(pid, gid, amt, {'from': alice})
    encoded_id = tx.return_value
    print('tx status', tx.status)
    print('encoded id', encoded_id)
    gauge, prevAccCrvPerShare = wgauge.gauges(pid, gid)
    print('gauge', gauge)
    print('prevAccCrvPerShare', prevAccCrvPerShare)
    print('alice wlp_3pool balance', wgauge.balanceOf(alice, encoded_id))
    assert tx.status == 1
    assert wgauge.balanceOf(alice, encoded_id) == amt

    # mint bob
    prevCrvBob = crv.balanceOf(bob)
    print('bob lp_3pool balance', interface.IERC20Ex(lp_3pool).balanceOf(bob))
    gauge, _ = wgauge.gauges(pid, gid)
    tx = interface.ILiquidityGauge(gauge).deposit(amt, {'from': bob})

    chain.sleep(10000)

    # burn too much (expected failed)
    prevCrvBalance = crv.balanceOf(alice)
    try:
        tx = wgauge.burn(encoded_id, amt + 1, {'from': alice})
        assert tx.status == 0
    except:
        pass

    print('alice wlpusdt balance', wgauge.balanceOf(alice, encoded_id))
    print('alice crv balance', crv.balanceOf(alice))
    assert prevCrvBalance == crv.balanceOf(alice)
    assert wgauge.balanceOf(alice, encoded_id) == amt

    # burn half alice
    prevCrvBalance = crv.balanceOf(alice)
    tx = wgauge.burn(encoded_id, amt // 2, {'from': alice})

    print('tx status', tx.status)
    print('alice wlp_3pool balance', wgauge.balanceOf(alice, encoded_id))
    print('amt - amt//2', amt - amt // 2)

    print('alice crv balance', crv.balanceOf(alice))

    assert tx.status == 1
    assert tx.return_value == pid
    assert wgauge.balanceOf(alice, encoded_id) == amt - amt // 2  # remove half

    # burn half bob
    minter = interface.ILiquidityGaugeMinter(
        interface.ILiquidityGauge(gauge).minter())
    print('minter', minter)
    tx = minter.mint(gauge, {'from': bob})
    print('tx status', tx.status)
    tx = interface.ILiquidityGauge(gauge).withdraw(amt // 2, {'from': bob})

    chain.sleep(10000)

    # burn remaining alice
    tx = wgauge.burn(encoded_id, 2**256 - 1, {'from': alice})

    print('tx status', tx.status)
    print('alice wlp_3pool balance', wgauge.balanceOf(alice, encoded_id))

    print('alice crv balance', crv.balanceOf(alice))
    receivedCrv = crv.balanceOf(alice) - prevCrvBalance

    assert tx.status == 1
    assert tx.return_value == pid

    # burn remaining bob
    tx = minter.mint(gauge, {'from': bob})
    print('tx status', tx.status)
    tx = interface.ILiquidityGauge(gauge).withdraw(amt - amt // 2,
                                                   {'from': bob})
    receivedCrvFromGauge = crv.balanceOf(bob) - prevCrvBob

    print('receivedCrv alice', receivedCrv)
    print('receivedCrvFromGauge bob', receivedCrvFromGauge)

    assert wgauge.balanceOf(alice, encoded_id) == 0  # remove all

    # check reward same as staking directly
    assert almostEqual(receivedCrv, receivedCrvFromGauge)