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})
Beispiel #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')
Beispiel #5
0
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
Beispiel #6
0
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')
    weth = interface.IERC20Ex('0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2')
    sushi = interface.IERC20Ex('0x6b3595068778dd592e39a122f4f5a5cf09c90fe2')

    lpusdt = interface.IERC20Ex(
        '0x06da0fd433c1a5d7a4faa01111c044910a184553')  # pid 0
    lpusdc = interface.IERC20Ex(
        '0x397ff1542f962076d0bfe58ea045ffa2d347aca0')  # pid 1

    chef = accounts.at('0xc2edad668740f1aa35e4d8f227fb8e17dca888cd',
                       force=True)
    wchef = WMasterChef.deploy(chef, {'from': admin})

    # set approval
    usdt.approve(wchef, 2**256 - 1, {'from': alice})
    usdc.approve(wchef, 2**256 - 1, {'from': alice})
    weth.approve(wchef, 2**256 - 1, {'from': alice})
    lpusdt.approve(wchef, 2**256 - 1, {'from': alice})
    lpusdc.approve(wchef, 2**256 - 1, {'from': alice})
    lpusdt.approve(chef, 2**256 - 1, {'from': alice})
    lpusdc.approve(chef, 2**256 - 1, {'from': alice})

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

    mint_tokens(lpusdt, alice)
    mint_tokens(lpusdc, alice)

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

    pid = 10
    sushiPerShare = 210
    encoded_id = wchef.encodeId(pid, sushiPerShare)
    print('encoded id', encoded_id)
    assert (encoded_id >> 240) == pid
    assert (encoded_id & ((1 << 240) - 1)) == sushiPerShare

    d_pid, d_sushiPerShare = wchef.decodeId(encoded_id)
    print('decoded pid', d_pid)
    print('decoded sushiPerShare', d_sushiPerShare)
    assert d_pid == pid
    assert d_sushiPerShare == sushiPerShare

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

    pid = 10
    sushiPerShare = 210
    id_num = wchef.encodeId(pid, sushiPerShare)
    lpToken = wchef.getUnderlyingToken(id_num)
    print('lpToken', lpToken)
    assert lpToken == '0xCb2286d9471cc185281c4f763d34A962ED212962'

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

    pid = 0
    amt = 10**10

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

    # mint
    tx = wchef.mint(pid, amt, {'from': alice})

    encoded_id = tx.return_value
    print('tx status', tx.status)
    print('encoded id', encoded_id)
    _, _, _, prevAccSushiPerShare = interface.IMasterChef(chef).poolInfo(0)
    print('prevAccSushiPerShare', prevAccSushiPerShare)
    print('alice wlpusdt balance', wchef.balanceOf(alice, encoded_id))
    assert tx.status == 1
    assert wchef.balanceOf(alice, encoded_id) == amt

    # burn exact
    prevSushiBalance = sushi.balanceOf(alice)
    tx = wchef.burn(encoded_id, amt, {'from': alice})
    _, _, _, newAccSushiPerShare = interface.IMasterChef(chef).poolInfo(0)
    print('tx status', tx.status)
    print('newAccSushiPerShare', newAccSushiPerShare)
    print('alice wlpusdt balance', wchef.balanceOf(alice, encoded_id))

    print('alice sushi balance', sushi.balanceOf(alice))
    receivedSushi = sushi.balanceOf(alice) - prevSushiBalance

    assert tx.status == 1
    assert wchef.balanceOf(alice, encoded_id) == 0  # remove all
    assert almostEqual(receivedSushi,
                       (newAccSushiPerShare - prevAccSushiPerShare) * amt //
                       10**12)

    # check reward same as staking directly
    prevSushi = sushi.balanceOf(alice)
    print('alice lpusdt balance', interface.IERC20Ex(lpusdt).balanceOf(alice))
    tx = interface.IMasterChef(chef).deposit(pid, amt, {'from': alice})
    tx = interface.IMasterChef(chef).withdraw(pid, amt, {'from': alice})
    receivedSushiFromChef = sushi.balanceOf(alice) - prevSushi
    print('receivedSushiFromChef', receivedSushiFromChef)
    assert almostEqual(receivedSushi, receivedSushiFromChef)

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

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

    pid = 0
    amt = 10**10

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

    # mint
    tx = wchef.mint(pid, amt, {'from': alice})

    encoded_id = tx.return_value
    print('tx status', tx.status)
    print('encoded id', encoded_id)
    _, _, _, prevAccSushiPerShare = interface.IMasterChef(chef).poolInfo(0)
    print('prevAccSushiPerShare', prevAccSushiPerShare)
    print('alice wlpusdt balance', wchef.balanceOf(alice, encoded_id))
    assert tx.status == 1
    assert wchef.balanceOf(alice, encoded_id) == amt

    # burn all
    prevSushiBalance = sushi.balanceOf(alice)
    tx = wchef.burn(encoded_id, 2**256 - 1, {'from': alice})
    _, _, _, newAccSushiPerShare = interface.IMasterChef(chef).poolInfo(0)
    print('tx status', tx.status)
    print('newAccSushiPerShare', newAccSushiPerShare)
    print('alice wlpusdt balance', wchef.balanceOf(alice, encoded_id))

    print('alice sushi balance', sushi.balanceOf(alice))
    receivedSushi = sushi.balanceOf(alice) - prevSushiBalance

    assert tx.status == 1
    assert wchef.balanceOf(alice, encoded_id) == 0  # remove all
    assert almostEqual(
        sushi.balanceOf(alice) - prevSushiBalance,
        (newAccSushiPerShare - prevAccSushiPerShare) * amt // 10**12)

    # check reward same as staking directly
    prevSushi = sushi.balanceOf(alice)
    print('alice lpusdt balance', interface.IERC20Ex(lpusdt).balanceOf(alice))
    tx = interface.IMasterChef(chef).deposit(pid, amt, {'from': alice})
    tx = interface.IMasterChef(chef).withdraw(pid, amt, {'from': alice})
    receivedSushiFromChef = sushi.balanceOf(alice) - prevSushi
    print('receivedSushiFromChef', receivedSushiFromChef)
    assert almostEqual(receivedSushi, receivedSushiFromChef)

    ######################################################################
    # check mint & burn (try more than available--revert, half, then remaining)
    print(
        '######################################################################'
    )
    print('Case 4.')

    pid = 0
    amt = 10**10

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

    # mint
    startSushiBalance = sushi.balanceOf(alice)
    tx = wchef.mint(pid, amt, {'from': alice})

    encoded_id = tx.return_value
    print('encoded id', encoded_id)
    _, _, _, prevAccSushiPerShare = interface.IMasterChef(chef).poolInfo(0)
    print('accSushiPerShare', prevAccSushiPerShare)
    assert tx.status == 1
    assert wchef.balanceOf(alice, encoded_id) == amt

    # burn too much (expected failed)
    prevSushiBalance = sushi.balanceOf(alice)
    _, _, _, prevAccSushiPerShare = interface.IMasterChef(chef).poolInfo(0)
    try:
        tx = wchef.burn(encoded_id, amt + 1, {'from': alice})
        assert tx.status == 0
    except:
        pass

    _, _, _, newAccSushiPerShare = interface.IMasterChef(chef).poolInfo(0)
    print('accSushiPerShare', newAccSushiPerShare)

    print('alice wlpusdt balance', wchef.balanceOf(alice, encoded_id))
    print('alice sushi balance', sushi.balanceOf(alice))
    assert prevSushiBalance == sushi.balanceOf(alice)
    assert wchef.balanceOf(alice, encoded_id) == amt

    # burn half
    prevSushiBalance = sushi.balanceOf(alice)
    _, _, _, prevAccSushiPerShare = interface.IMasterChef(chef).poolInfo(0)

    tx = wchef.burn(encoded_id, amt // 2, {'from': alice})
    _, _, _, newAccSushiPerShare = interface.IMasterChef(chef).poolInfo(0)
    print('accSushiPerShare', newAccSushiPerShare)

    print('alice wlpusdt balance', wchef.balanceOf(alice, encoded_id))
    print('alice sushi balance', sushi.balanceOf(alice))

    assert tx.status == 1
    assert almostEqual(
        sushi.balanceOf(alice) - prevSushiBalance,
        (newAccSushiPerShare - prevAccSushiPerShare) * amt // 2 // 10**12)
    assert almostEqual(wchef.balanceOf(alice, encoded_id), amt - amt // 2)

    # burn remaining
    prevSushiBalance = sushi.balanceOf(alice)

    tx = wchef.burn(encoded_id, 2**256 - 1, {'from': alice})
    _, _, _, newAccSushiPerShare = interface.IMasterChef(chef).poolInfo(0)
    print('accSushiPerShare', newAccSushiPerShare)

    print('alice wlpusdt balance', wchef.balanceOf(alice, encoded_id))
    print('alice sushi balance', sushi.balanceOf(alice))

    receivedSushi = sushi.balanceOf(alice) - prevSushiBalance

    assert tx.status == 1
    assert almostEqual(
        sushi.balanceOf(alice) - prevSushiBalance,
        (newAccSushiPerShare - prevAccSushiPerShare) * amt // 2 // 10**12)
    assert wchef.balanceOf(alice, encoded_id) == 0

    # check reward same as staking directly
    prevSushi = sushi.balanceOf(alice)
    print('alice lpusdt balance', interface.IERC20Ex(lpusdt).balanceOf(alice))
    tx = interface.IMasterChef(chef).deposit(pid, amt,
                                             {'from': alice})  # stake all
    tx = interface.IMasterChef(chef).withdraw(pid, amt // 2,
                                              {'from': alice})  # redeem half
    tx = interface.IMasterChef(chef).withdraw(
        pid, amt - amt // 2, {'from': alice})  # redeem remaining
    receivedSushiFromChef = sushi.balanceOf(alice) - prevSushi
    print('receivedSushiFromChef', receivedSushiFromChef)
    assert almostEqual(receivedSushi, receivedSushiFromChef)
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]
    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():
    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)
Beispiel #11
0
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')
Beispiel #12
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')