예제 #1
0
def main():
    token = Contract(REWARD_TOKEN_ADDRESS)
    seed_amount = 10 ** token.decimals()
    if token.balanceOf(REWARD_ADMIN) < seed_amount:
        raise ValueError("Reward admin must have at least 1 token to seed the contract for testing")

    # deploy the rewards contract - initially we set the reward period to one day so we
    # can seed a small amount for testing
    rewards = StakingRewards.deploy(
        OWNER,
        REWARD_ADMIN,
        token,
        STAKING_TOKEN_ADDRESS,
        86400,
        {'from': DEPLOYER, 'gas_price': gas_strategy}
    )

    # give infinite approval to the reward contract from the reward admin
    token.approve(rewards, 2**256-1, {'from': REWARD_ADMIN, 'gas_price': gas_strategy})

    # seed the contract with 1 token for initial testing
    rewards.notifyRewardAmount(seed_amount, {'from': REWARD_ADMIN, 'gas_price': gas_strategy})

    print(f"""Success!

StakingRewards deployed to: {rewards}
Owner: {OWNER}
Reward admin: {REWARD_ADMIN}

Please verify the source code on Etherscan here: https://etherscan.io/verifyContract?a={rewards}
Compiler version: 0.5.17
Optimization: ON
""")
예제 #2
0
def main():
    multi = MultiRewards.at(MULTIREWARDS_CONTRACT_ADDRESS)
    reward = Contract(REWARDTOKEN_CONTRACT_ADDRESS)

    # sanity check on the reward amount
    if REWARDS_AMOUNT < 10**reward.decimals():
        raise ValueError(
            "Reward amount is less than 1 token - are you sure this is correct?"
        )

    # ensure the reward admin has sufficient balance of the reward token
    if reward.balanceOf(REWARD_ADMIN) < REWARDS_AMOUNT:
        raise ValueError(
            "Rewards admin has insufficient balance to fund the contract")

    # ensure the reward contract has sufficient allowance to transfer the reward token
    if reward.allowance(REWARD_ADMIN, multi) < REWARDS_AMOUNT:
        reward.approve(multi, 2**256 - 1, {
            "from": REWARD_ADMIN,
            "gas_price": gas_strategy
        })

    # update the reward amount
    multi.notifyRewardAmount(reward, REWARDS_AMOUNT, {
        "from": REWARD_ADMIN,
        "gas_price": gas_strategy
    })

    print(
        f"Success! {REWARDS_AMOUNT/10**reward.decimals():.2f} {reward.symbol()} has been added"
    )
예제 #3
0
def main():
    d = shelve.open('addresses')
    mainnetERC20_addr = d['mainnetERC20']
    mainnetMediator_addr = d['mainnetMediator']
    DECIMALS = 10**18

    #approve
    mainnetERC20 = Contract(mainnetERC20_addr)
    mainnetERC20.approve(mainnetMediator_addr, 10000 * DECIMALS,
                         {"from": accounts[0]})

    #relay
    mainnetMediator = Contract(mainnetMediator_addr)
    mainnetMediator.relayTokens(accounts[0], 50 * DECIMALS,
                                {"from": accounts[0]})
예제 #4
0
def main():
    d = shelve.open('addresses')
    xdaiERC20_addr = d['xdaiERC20']
    xdaiMediator_addr = d['xdaiMediator']
    DECIMALS = 10**18

    #faucet
    xdaiMediator = Contract(xdaiMediator_addr)
    xdaiMediator.faucet({"from": accounts[0]})

    #approve
    xdaiERC20 = Contract(xdaiERC20_addr)
    xdaiERC20.approve(xdaiMediator_addr, 1000*DECIMALS, {"from": accounts[0]})

    #relay
    xdaiMediator.relayTokens(accounts[0], 100*DECIMALS, {"from": accounts[0]})
예제 #5
0
def test_hegic_strategy_infura(pm):
    hegic_liquidity = accounts.at(
        "0x736f85bf359e3e2db736d395ed8a4277123eeee1",
        force=True)  # Hegic: Liquidity M&U (lot's of hegic)

    rewards = accounts[2]
    gov = accounts[3]
    guardian = accounts[4]
    bob = accounts[5]
    alice = accounts[6]
    strategist = accounts[7]

    hegic = Contract("0x584bC13c7D411c00c01A62e8019472dE68768430", owner=gov)
    hegic.approve(hegic_liquidity, Wei("1000000 ether"),
                  {"from": hegic_liquidity})
    hegic.transferFrom(hegic_liquidity, gov, Wei("888000 ether"),
                       {"from": hegic_liquidity})

    Vault = pm(config["dependencies"][0]).Vault
    yHegic = Vault.deploy({"from": gov})
    yHegic.initialize(hegic, gov, rewards, "", "")
    yHegic.setDepositLimit(Wei("889000 ether"))

    # HEGIC ETH Staking lot (hlETH)
    hegicStaking = Contract("0x1Ef61E3E5676eC182EED6F052F8920fD49C7f69a",
                            owner=gov)

    # Sushiswap router v2
    uni = Contract("0xd9e1ce17f2641f24ae83637ab66a2cca9c378b9f", owner=gov)

    strategy = guardian.deploy(StrategyHegicETH, yHegic, hegic, hegicStaking,
                               uni)
    strategy.setStrategist(strategist)

    # 100% of the vault's depositLimit
    yHegic.addStrategy(strategy, 10_000, 0, 0, {"from": gov})

    hegic.approve(gov, Wei("1000000 ether"), {"from": gov})
    hegic.transferFrom(gov, bob, Wei("100000 ether"), {"from": gov})
    hegic.transferFrom(gov, alice, Wei("788000 ether"), {"from": gov})
    hegic.approve(yHegic, Wei("1000000 ether"), {"from": bob})
    hegic.approve(yHegic, Wei("1000000 ether"), {"from": alice})

    yHegic.deposit(Wei("100000 ether"), {"from": bob})
    yHegic.deposit(Wei("788000 ether"), {"from": alice})

    strategy.harvest()

    assert hegic.balanceOf(strategy) == 0
    assert hegicStaking.balanceOf(strategy) == 1

    hegicStaking.sendProfit({"value": Wei("1 ether"), "from": gov})
    strategy.harvest({"from": gov})

    # We should have made profit
    assert yHegic.pricePerShare() / 1e18 > 1
예제 #6
0
def test_asset_user_metadata(ironBankAdapter, accounts, oracle):
    sushi = Contract(sushiAddress)
    cySushi = Contract(cySushiAddress)
    whale = accounts.at(sushiWhaleAddress, force=True)
    MAX_UINT256 = 2**256 - 1
    sushi.approve(cySushi, MAX_UINT256, {"from": whale})
    sushi_bal = sushi.balanceOf(whale)
    cySushi.mint(sushi_bal, {"from": whale})
    assert sushi.balanceOf(whale) == 0
    assert cySushi.balanceOf(whale) > 0

    comptroller = Contract(comptrollerAddress)
    _, collateralFactor, _ = comptroller.markets(cySushiAddress)

    comptroller.enterMarkets([cySushi], {"from": whale})

    tokenAddress = cySushi.underlying()
    tokenPriceUsdc = ironBankAdapter.assetUnderlyingTokenPriceUsdc(cySushi)
    exchangeRate = cySushi.exchangeRateStored()
    supplyBalanceShares = cySushi.balanceOf(whale)
    supplyBalanceUnderlying = (supplyBalanceShares * exchangeRate) / 10**18
    supplyBalanceUsdc = oracle.getNormalizedValueUsdc(tokenAddress,
                                                      supplyBalanceUnderlying,
                                                      tokenPriceUsdc)

    borrowBalanceShares = cySushi.borrowBalanceStored(whale)
    borrowBalanceUsdc = oracle.getNormalizedValueUsdc(tokenAddress,
                                                      borrowBalanceShares,
                                                      tokenPriceUsdc)

    _, collateralBalanceShare, _, _ = cySushi.getAccountSnapshot(whale)
    collateralBalanceUnderlying = collateralBalanceShare * exchangeRate / 10**18

    collateralBalanceUsdc = oracle.getNormalizedValueUsdc(
        tokenAddress, collateralBalanceUnderlying, tokenPriceUsdc)

    borrowLimitUsdc = collateralBalanceUsdc * collateralFactor / 10**18

    asset_user_metadata = ironBankAdapter.assetUserMetadata(whale, cySushi)
    assert asset_user_metadata[0] == cySushi
    assert asset_user_metadata[1] == True
    assert asset_user_metadata[2] == supplyBalanceUsdc
    assert asset_user_metadata[3] == borrowBalanceUsdc
    assert asset_user_metadata[4] == collateralBalanceUsdc
    assert asset_user_metadata[5] == borrowLimitUsdc
예제 #7
0
def main():
    rewards = StakingRewards.at(REWARDS_CONTRACT_ADDRESS)
    token = Contract(rewards.rewardsToken())

    # sanity check on the reward amount
    if REWARDS_AMOUNT < 10**token.decimals():
        raise ValueError(
            "Reward amount is less than 1 token - are you sure this is correct?"
        )

    # ensure the reward admin has sufficient balance of the reward token
    if token.balanceOf(REWARD_ADMIN) < REWARDS_AMOUNT:
        raise ValueError(
            "Rewards admin has insufficient balance to fund the contract")

    # check the reward duration and modify if needed
    if rewards.rewardsDuration() != REWARDS_DURATION:
        remaining_time = rewards.periodFinish() - chain[-1].timestamp
        if remaining_time > 0:
            raise ValueError(
                "Current reward period must finish before the period duration can be modified, "
                f"try again in {datetime.timedelta(seconds=remaining_time)}")
        rewards.setRewardsDuration(REWARDS_DURATION, {'from': OWNER})

    # ensure the reward contract has sufficient allowance to transfer the reward token
    if token.allowance(REWARD_ADMIN, rewards) < REWARDS_AMOUNT:
        token.approve(rewards, 2**256 - 1, {
            'from': REWARD_ADMIN,
            'gas_price': gas_strategy
        })

    # update the reward amount
    rewards.notifyRewardAmount(REWARDS_AMOUNT, {
        'from': REWARD_ADMIN,
        'gas_price': gas_strategy
    })

    print(
        f"Success! {REWARDS_AMOUNT/10**token.decimals():.2f} {token.symbol()} has been added to "
        f"the rewards contract, to be distributed over {REWARDS_DURATION/86400:.1f} days."
    )
예제 #8
0
def test_zap(accounts, ZapYvecrv):
    whale = accounts.at("0xbe0eb53f46cd790cd13851d5eff43d12404d33e8",
                        force=True)
    zap = whale.deploy(ZapYvecrv)
    vault_ecrv_live = Contract(zap.yVault())
    vault_ecrv_live.approve(zap, 2**256 - 1, {"from": whale})

    print("")
    print("Zap In 100 ETH actuals")
    print("----------------------------")

    zap.zapIn(0, {"from": whale, "value": Wei("100 ether")})
    yvTokens = vault_ecrv_live.balanceOf(whale)
    yvTokensPretty = yvTokens / Wei("1 ether")
    print(f"Zap in: {yvTokensPretty} yveCRV")

    startingEthBalance = whale.balance()
    zap.zapOut(yvTokens, 0, {"from": whale})
    zappedOutEth = whale.balance() - startingEthBalance
    zappedOutEthPretty = zappedOutEth / Wei("1 ether")
    print(f"Zap out: {zappedOutEthPretty} ETH")
예제 #9
0
def test_assets_user_metadata(ironBankAdapter, accounts, oracle):
    # sushi and cySuchi
    sushi = Contract(sushiAddress)
    cySushi = Contract(cySushiAddress)
    whale = accounts.at(sushiWhaleAddress, force=True)
    MAX_UINT256 = 2**256 - 1
    sushi.approve(cySushi, MAX_UINT256, {"from": whale})
    sushi_bal = sushi.balanceOf(whale)
    cySushi.mint(sushi_bal, {"from": whale})
    assert sushi.balanceOf(whale) == 0
    assert cySushi.balanceOf(whale) > 0

    # yfi and cyYfi
    yfi = Contract(yfiAddress)
    cyYfi = Contract(cyYfiAddress)
    whale = accounts.at(sushiWhaleAddress, force=True)
    MAX_UINT256 = 2**256 - 1
    yfi.approve(cyYfi, MAX_UINT256, {"from": whale})
    yfi_bal = yfi.balanceOf(whale)
    cyYfi.mint(yfi_bal, {"from": whale})
    assert yfi.balanceOf(whale) == 0
    assert cyYfi.balanceOf(whale) > 0

    comptroller = Contract(comptrollerAddress)
    _, sushiCollateralFactor, _ = comptroller.markets(cySushiAddress)
    _, yfiCollateralFactor, _ = comptroller.markets(cyYfiAddress)

    comptroller.enterMarkets([cySushi, cyYfi], {"from": whale})

    # sushi
    sushiTokenAddress = cySushi.underlying()
    sushiPriceUsdc = ironBankAdapter.assetUnderlyingTokenPriceUsdc(cySushi)
    sushiExchangeRate = cySushi.exchangeRateStored()
    sushiSupplyBalShares = cySushi.balanceOf(whale)
    sushiSupplyBalUnderlying = (sushiSupplyBalShares *
                                sushiExchangeRate) / 10**18
    sushiSupplyBalUsdc = oracle.getNormalizedValueUsdc(
        sushiTokenAddress, sushiSupplyBalUnderlying, sushiPriceUsdc)

    sushiBorrowBalShares = cySushi.borrowBalanceStored(whale)
    sushiBorrowBalUsdc = oracle.getNormalizedValueUsdc(sushiTokenAddress,
                                                       sushiBorrowBalShares,
                                                       sushiPriceUsdc)

    _, sushiCollateralBalShare, _, _ = cySushi.getAccountSnapshot(whale)
    sushiCollateralBalUnderlying = (sushiCollateralBalShare *
                                    sushiExchangeRate / 10**18)

    sushiCollateralBalUsdc = oracle.getNormalizedValueUsdc(
        sushiTokenAddress, sushiCollateralBalUnderlying, sushiPriceUsdc)

    sushiBorrowLimitUsdc = sushiCollateralBalUsdc * sushiCollateralFactor / 10**18

    # yfi
    yfiTokenAddress = ironBankAdapter.assetUnderlyingTokenAddress(cyYfi)
    yfiPriceUsdc = ironBankAdapter.assetUnderlyingTokenPriceUsdc(cyYfi)
    yfiExchangeRate = cyYfi.exchangeRateStored()
    yfiSupplyBalShares = cyYfi.balanceOf(whale)
    yfiSupplyBalUnderlying = (yfiSupplyBalShares * yfiExchangeRate) / 10**18
    yfiSupplyBalUsdc = oracle.getNormalizedValueUsdc(yfiTokenAddress,
                                                     yfiSupplyBalUnderlying,
                                                     yfiPriceUsdc)

    yfiBorrowBalShares = cyYfi.borrowBalanceStored(whale)
    yfiBorrowBalUsdc = oracle.getNormalizedValueUsdc(yfiTokenAddress,
                                                     yfiBorrowBalShares,
                                                     yfiPriceUsdc)

    _, yfiCollateralBalShare, _, _ = cyYfi.getAccountSnapshot(whale)
    yfiCollateralBalUnderlying = yfiCollateralBalShare * yfiExchangeRate / 10**18

    yfiCollateralBalUsdc = oracle.getNormalizedValueUsdc(
        yfiTokenAddress, yfiCollateralBalUnderlying, yfiPriceUsdc)

    yfiBorrowLimitUsdc = yfiCollateralBalUsdc * yfiCollateralFactor / 10**18

    asset_user_metadata = ironBankAdapter.assetsUserMetadata(
        whale, [cySushi, cyYfi])
    assert asset_user_metadata[0][0] == cySushi
    assert asset_user_metadata[0][1] == True
    assert asset_user_metadata[0][2] == sushiSupplyBalUsdc
    assert asset_user_metadata[0][3] == sushiBorrowBalUsdc
    assert asset_user_metadata[0][4] == sushiCollateralBalUsdc
    assert asset_user_metadata[0][5] == sushiBorrowLimitUsdc

    assert asset_user_metadata[1][0] == cyYfi
    assert asset_user_metadata[1][1] == True
    assert asset_user_metadata[1][2] == yfiSupplyBalUsdc
    assert asset_user_metadata[1][3] == yfiBorrowBalUsdc
    assert asset_user_metadata[1][4] == yfiCollateralBalUsdc
    assert asset_user_metadata[1][5] == yfiBorrowLimitUsdc
예제 #10
0
def test_migration(pm, chain):
    dai_liquidity = accounts.at("0xbebc44782c7db0a1a60cb6fe97d0b483032ff1c7",
                                force=True)  # using curve pool (lots of dai)

    rewards = accounts[2]
    gov = accounts[3]
    guardian = accounts[4]
    bob = accounts[5]
    alice = accounts[6]
    strategist = accounts[7]
    tinytim = accounts[8]

    dai = Contract("0x6b175474e89094c44da98b954eedeac495271d0f",
                   owner=gov)  # DAI token

    dai.approve(dai_liquidity, Wei("1000000 ether"), {"from": dai_liquidity})
    dai.transferFrom(dai_liquidity, gov, Wei("10000 ether"),
                     {"from": dai_liquidity})

    # config yvDAI vault.
    Vault = pm(config["dependencies"][0]).Vault
    yUSDT3 = gov.deploy(Vault, dai, gov, rewards, "", "")

    threePool = Contract("0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7",
                         owner=gov)  # crv3 pool address (threePool)
    crv3 = Contract("0x6c3F90f043a72FA612cbac8115EE7e52BDe6E490",
                    owner=gov)  # crv3 token address (threePool)
    yCRV3 = Contract("0x9cA85572E6A3EbF24dEDd195623F188735A5179f",
                     owner=gov)  # crv3 vault (threePool)
    # uni = Contract.from_explorer(
    #  "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D", owner=gov
    # )  # UNI router v2

    strategy = guardian.deploy(StrategyDAI3Pool, yUSDT3, dai, threePool, yCRV3,
                               crv3)
    strategy.setStrategist(strategist)

    yUSDT3.addStrategy(strategy, Wei("1000000000 ether"), 2**256 - 1, 50,
                       {"from": gov})

    dai.approve(gov, Wei("1000000 ether"), {"from": gov})
    dai.transferFrom(gov, bob, Wei("1000 ether"), {"from": gov})
    dai.transferFrom(gov, alice, Wei("4000 ether"), {"from": gov})
    dai.transferFrom(gov, tinytim, Wei("10 ether"), {"from": gov})
    dai.approve(yUSDT3, Wei("1000000 ether"), {"from": bob})
    dai.approve(yUSDT3, Wei("1000000 ether"), {"from": alice})
    dai.approve(yUSDT3, Wei("1000000 ether"), {"from": tinytim})
    crv3.approve(gov, Wei("1000000 ether"), {"from": gov})
    yUSDT3.approve(gov, Wei("1000000 ether"), {"from": gov})
    crv3.approve(yCRV3, Wei("1000000 ether"), {"from": gov})
    dai.approve(threePool, Wei("1000000 ether"), {"from": gov})

    # users deposit to vault
    yUSDT3.deposit(Wei("1000 ether"), {"from": bob})
    yUSDT3.deposit(Wei("4000 ether"), {"from": alice})
    yUSDT3.deposit(Wei("10 ether"), {"from": tinytim})

    # a = dai.balanceOf(address(bob))
    # b = dai.balanceOf(address(alice))

    # print(a)
    # print(b)

    chain.mine(1)

    strategy.harvest({"from": gov})

    newstrategy = guardian.deploy(StrategyDAI2, yUSDT3, dai, threePool, yCRV3,
                                  crv3)
    newstrategy.setStrategist(strategist)

    yUSDT3.migrateStrategy(strategy, newstrategy, {"from": gov})

    assert yCRV3.balanceOf(strategy) == 0
    assert yCRV3.balanceOf(newstrategy) > 0

    pass
def test_operation(pm, chain):
    wbtc_liquidity = accounts.at("0x93054188d876f558f4a66b2ef1d97d16edf0895b",
                                 force=True)  # using curve pool (lots of wbtc)

    sbtc_liquidity = accounts.at("0x13c1542a468319688b89e323fe9a3be3a90ebb27",
                                 force=True)  # synthetix (lots of sbtc)

    rewards = accounts[2]
    gov = accounts[3]
    guardian = accounts[4]
    bob = accounts[5]
    alice = accounts[6]
    strategist = accounts[7]
    tinytim = accounts[8]

    wbtc = Contract("0x2260fac5e5542a773aa44fbcfedf7c193bc2c599",
                    owner=gov)  # wbtc token

    wbtc.approve(wbtc_liquidity, Wei("1000000 ether"),
                 {"from": wbtc_liquidity})
    wbtc.transferFrom(wbtc_liquidity, gov, 3000000000,
                      {"from": wbtc_liquidity})

    sbtc = Contract("0x075b1bb99792c9E1041bA13afEf80C91a1e70fB3",
                    owner=gov)  # sbtcCRV token address (threePool)

    sbtc.approve(sbtc_liquidity, Wei("1000000 ether"),
                 {"from": sbtc_liquidity})
    sbtc.transferFrom(sbtc_liquidity, gov, Wei("100 ether"),
                      {"from": sbtc_liquidity})

    # config vault.
    Vault = pm(config["dependencies"][0]).Vault
    yUSDT3 = Vault.deploy({"from": gov})
    yUSDT3.initialize(wbtc, gov, rewards, "", "")
    yUSDT3.setDepositLimit(Wei("1000000 ether"))

    sbtcPool = Contract("0x7fC77b5c7614E1533320Ea6DDc2Eb61fa00A9714",
                        owner=gov)  # sbtcCRV pool address (threePool)
    ysBTC = Contract("0x7Ff566E1d69DEfF32a7b244aE7276b9f90e9D0f6",
                     owner=gov)  # sbtc vault (threePool)
    crv3Strat = Contract("0x6D6c1AD13A5000148Aa087E7CbFb53D402c81341",
                         owner=gov)  # crv3 strat (threePool)
    crv3StratOwner = Contract("0xd0aC37E3524F295D141d3839d5ed5F26A40b589D",
                              owner=gov)  # crv3 stratOwner (threePool)
    # uni = Contract.from_explorer(
    #  "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D", owner=gov
    # )  # UNI router v2

    strategy = guardian.deploy(StrategyWBTCsBTCv2, yUSDT3, wbtc, sbtcPool,
                               ysBTC, sbtc)
    strategy.setStrategist(strategist)

    yUSDT3.addStrategy(strategy, 10_000, 0, 0, {"from": gov})

    wbtc.approve(gov, Wei("1000000 ether"), {"from": gov})
    wbtc.transferFrom(gov, bob, 100000000, {"from": gov})
    wbtc.transferFrom(gov, alice, 1000000000, {"from": gov})
    wbtc.transferFrom(gov, tinytim, 1000000, {"from": gov})
    wbtc.approve(yUSDT3, Wei("1000000 ether"), {"from": bob})
    wbtc.approve(yUSDT3, Wei("1000000 ether"), {"from": alice})
    wbtc.approve(yUSDT3, Wei("1000000 ether"), {"from": tinytim})
    sbtc.approve(gov, Wei("1000000 ether"), {"from": gov})
    yUSDT3.approve(gov, Wei("1000000 ether"), {"from": gov})
    sbtc.approve(ysBTC, Wei("1000000 ether"), {"from": gov})
    wbtc.approve(sbtcPool, Wei("1000000 ether"), {"from": gov})

    wbtc.approve(sbtcPool, Wei("1000000 ether"), {"from": gov})
    # depositing DAI to generate crv3 tokens.
    #crv3.approve(crv3_liquidity, Wei("1000000 ether"), {"from": crv3_liquidity})
    #threePool.add_liquidity([0, 200000000000, 0], 0, {"from": gov})
    #giving Gov some shares to mimic profit
    #yCRV3.depositAll({"from": gov})

    # users deposit to vault
    yUSDT3.deposit(100000000, {"from": bob})
    yUSDT3.deposit(1000000000, {"from": alice})
    yUSDT3.deposit(1000000, {"from": tinytim})

    chain.mine(1)

    strategy.harvest({"from": gov})

    strategy.harvest({"from": gov})

    assert ysBTC.balanceOf(strategy) > 0
    chain.sleep(3600 * 24 * 7 * 10)
    chain.mine(1)
    a = yUSDT3.pricePerShare()

    # small profit
    #yCRV3.approve(gov, Wei("1000000 ether"), {"from": gov})
    #yCRV3.transferFrom(gov, strategy, Wei("5000 ether"), {"from": gov})
    t = ysBTC.getPricePerFullShare()
    c = strategy.estimatedTotalAssets()
    crv3Strat.harvest({"from": crv3StratOwner})
    s = ysBTC.getPricePerFullShare()
    d = strategy.estimatedTotalAssets()
    assert t < s
    assert d > c

    assert yUSDT3.strategies(strategy).dict()['totalDebt'] < d

    #wbtc.transferFrom(gov, strategy, 500000000, {"from": gov})
    #strategy.harvest({"from": gov})
    #chain.mine(1)
    strategy.harvest({"from": gov})
    chain.mine(1)

    b = yUSDT3.pricePerShare()

    # debt rises faster than profit based on the mainnet fork due to a very low ~1.5% APY on this curve pool at the moment.
    # as long as b!= a, then it is tracking profit/losses value/debt as these values diverge
    assert b != a

    #withdrawals have a slippage protection parameter, defaults to 1 = 0.01%.
    #overwriting here to be 0.75%, to account for slippage + 0.5% v1 vault withdrawal fee.
    #d = yUSDT3.balanceOf(alice)

    c = yUSDT3.balanceOf(alice)

    yUSDT3.withdraw(c, alice, 75, {"from": alice})

    assert wbtc.balanceOf(alice) > 0
    assert wbtc.balanceOf(bob) == 0
    assert ysBTC.balanceOf(strategy) > 0

    d = yUSDT3.balanceOf(bob)
    yUSDT3.withdraw(d, bob, 75, {"from": bob})

    assert wbtc.balanceOf(bob) > 0

    e = yUSDT3.balanceOf(tinytim)
    yUSDT3.withdraw(e, tinytim, 75, {"from": tinytim})

    assert wbtc.balanceOf(tinytim) > 0

    # We should have made profit
    assert yUSDT3.pricePerShare() > 1

    pass
예제 #12
0
def test_operation(pm, chain):
    dai_liquidity = accounts.at("0xbebc44782c7db0a1a60cb6fe97d0b483032ff1c7",
                                force=True)  # using curve pool (lots of dai)

    crv3_liquidity = accounts.at("0x6c3F90f043a72FA612cbac8115EE7e52BDe6E490",
                                 force=True)  # yearn treasury (lots of crv3)

    crv_liquidity = accounts.at(
        "0xD533a949740bb3306d119CC777fa900bA034cd52",
        force=True)  # using curve vesting (lots of crv)

    weth_liquidity = accounts.at("0x2F0b23f53734252Bda2277357e97e1517d6B042A",
                                 force=True)  # using MKR (lots of weth)

    rewards = accounts[2]
    gov = accounts[3]
    guardian = accounts[4]
    bob = accounts[5]
    alice = accounts[6]
    strategist = accounts[7]
    tinytim = accounts[8]
    proxy = accounts[9]

    # dai approval
    dai = Contract("0x6b175474e89094c44da98b954eedeac495271d0f",
                   owner=gov)  # DAI token

    dai.approve(dai_liquidity, Wei("1000000 ether"), {"from": dai_liquidity})
    dai.transferFrom(dai_liquidity, gov, Wei("300000 ether"),
                     {"from": dai_liquidity})

    threePool = Contract("0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7",
                         owner=gov)  # crv3 pool address (threePool)
    #yCRV3 = Contract(
    #    "0x9cA85572E6A3EbF24dEDd195623F188735A5179f", owner=gov
    #)  # crv3 vault (threePool)
    unirouter = Contract.from_explorer(
        "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D",
        owner=gov)  # UNI router v2
    proxy = Contract.from_explorer(
        "0xc17adf949f524213a540609c386035d7d685b16f",
        owner=gov)  # StrategyProxy

    gauge = Contract.from_explorer(
        "0xbFcF63294aD7105dEa65aA58F8AE5BE2D9d0952A",
        owner=gov)  # threePool gauge

    govProxy = Contract.from_explorer(
        "0xFEB4acf3df3cDEA7399794D0869ef76A6EfAff52",
        owner=gov)  # threePool gauge

    dai.approve(threePool, Wei("1000000 ether"), {"from": gov})

    #crv3 approval
    crv3 = Contract("0x6c3F90f043a72FA612cbac8115EE7e52BDe6E490",
                    owner=gov)  # crv3 token address (threePool token)

    #depositing DAI to generate crv3 tokens.
    crv3.approve(crv3_liquidity, Wei("1000000 ether"),
                 {"from": crv3_liquidity})
    threePool.add_liquidity([Wei("200000 ether"), 0, 0], 0, {"from": gov})

    #crv approval
    crv = Contract("0xD533a949740bb3306d119CC777fa900bA034cd52",
                   owner=gov)  # crv token address (DAO token)

    crv.approve(crv_liquidity, Wei("1000000 ether"), {"from": crv_liquidity})
    crv.transferFrom(crv_liquidity, gov, Wei("10000 ether"),
                     {"from": crv_liquidity})

    #weth approval
    weth = Contract("0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
                    owner=gov)  # weth token address

    weth.approve(weth_liquidity, Wei("1000000 ether"),
                 {"from": weth_liquidity})
    weth.transferFrom(weth_liquidity, gov, Wei("10000 ether"),
                      {"from": weth_liquidity})

    # config yvCRV3 vault.
    Vault = pm(config["dependencies"][0]).Vault
    yCRV3 = Vault.deploy({"from": gov})
    yCRV3.initialize(crv3, gov, rewards, "", "")
    yCRV3.setDepositLimit(Wei("1000000 ether"))

    strategy = guardian.deploy(Strategy3Poolv2, yCRV3, dai, threePool, crv3,
                               crv, unirouter, weth, proxy, gauge)
    strategy.setStrategist(strategist)

    yCRV3.addStrategy(strategy, 10_000, 0, 0, {"from": gov})

    #setup for crv3
    crv3.approve(gov, Wei("1000000 ether"), {"from": gov})
    crv3.transferFrom(gov, bob, Wei("1000 ether"), {"from": gov})
    crv3.transferFrom(gov, alice, Wei("4000 ether"), {"from": gov})
    crv3.transferFrom(gov, tinytim, Wei("10 ether"), {"from": gov})
    crv3.approve(yCRV3, Wei("1000000 ether"), {"from": bob})
    crv3.approve(yCRV3, Wei("1000000 ether"), {"from": alice})
    crv3.approve(yCRV3, Wei("1000000 ether"), {"from": tinytim})
    #setup for dai
    dai.approve(gov, Wei("1000000 ether"), {"from": gov})
    dai.approve(threePool, Wei("1000000 ether"), {"from": gov})
    dai.approve(threePool, Wei("1000000 ether"), {"from": strategy})
    #setup for crv
    crv.approve(gov, Wei("1000000 ether"), {"from": gov})
    #setup for weth
    weth.approve(gov, Wei("1000000 ether"), {"from": gov})

    proxy.approveStrategy(strategy, {"from": govProxy, "gas limit": 120000000})

    # users deposit to vault
    yCRV3.deposit(Wei("1000 ether"), {"from": bob})
    yCRV3.deposit(Wei("4000 ether"), {"from": alice})
    yCRV3.deposit(Wei("10 ether"), {"from": tinytim})

    chain.mine(1)

    assert crv3.balanceOf(yCRV3) > 1
    assert crv3.balanceOf(alice) == 0
    assert yCRV3.balanceOf(alice) > 0

    a = yCRV3.pricePerShare()

    strategy.harvest({"from": gov})
    chain.mine(10)

    crv3.transferFrom(gov, yCRV3, Wei("1000 ether"), {"from": gov})
    strategy.harvest({"from": gov})
    chain.mine(10)

    assert crv3.balanceOf(strategy) == 0

    # there's already crv3 from the existing strategy. It will be counted as profit.
    b = yCRV3.pricePerShare()

    assert b > a

    #crv sent to strategy to mimic profit
    crv.transferFrom(gov, strategy, Wei("10000 ether"), {"from": gov})
    chain.mine(1)
    strategy.harvest({"from": gov})
    chain.mine(1)
    #second harvest to move crv3 back to strategy and increase strat debt
    strategy.harvest({"from": gov})
    chain.mine(1)

    assert crv.balanceOf(strategy) == 0

    c = yCRV3.pricePerShare()

    assert c > b

    yCRV3.withdraw({"from": alice})

    assert crv3.balanceOf(alice) > 0
    assert crv3.balanceOf(strategy) == 0
    assert crv3.balanceOf(bob) == 0

    yCRV3.withdraw({"from": bob})

    assert crv3.balanceOf(bob) > 0
    assert crv3.balanceOf(strategy) == 0

    yCRV3.withdraw({"from": tinytim})

    assert crv3.balanceOf(tinytim) > 0
    assert crv3.balanceOf(strategy) == 0

    pass
예제 #13
0
def test_operation(pm, chain):
    wbtc_liquidity = accounts.at("0x93054188d876f558f4a66b2ef1d97d16edf0895b",
                                 force=True)  # using curve pool (lots of wbtc)

    sbtc_liquidity = accounts.at("0x13c1542a468319688b89e323fe9a3be3a90ebb27",
                                 force=True)  # synthetix (lots of sbtc)

    rewards = accounts[2]
    gov = accounts[3]
    guardian = accounts[4]
    bob = accounts[5]
    alice = accounts[6]
    strategist = accounts[7]
    tinytim = accounts[8]

    wbtc = Contract("0x2260fac5e5542a773aa44fbcfedf7c193bc2c599",
                    owner=gov)  # wbtc token

    wbtc.approve(wbtc_liquidity, Wei("1000000 ether"),
                 {"from": wbtc_liquidity})
    wbtc.transferFrom(wbtc_liquidity, gov, 3000000000,
                      {"from": wbtc_liquidity})

    sbtc = Contract("0x075b1bb99792c9E1041bA13afEf80C91a1e70fB3",
                    owner=gov)  # sbtcCRV token address (threePool)

    sbtc.approve(sbtc_liquidity, Wei("1000000 ether"),
                 {"from": sbtc_liquidity})
    sbtc.transferFrom(sbtc_liquidity, gov, Wei("100 ether"),
                      {"from": sbtc_liquidity})

    # config vault.
    Vault = pm(config["dependencies"][0]).Vault
    yUSDT3 = Vault.deploy({"from": gov})
    yUSDT3.initialize(wbtc, gov, rewards, "", "")
    yUSDT3.setDepositLimit(Wei("1000000 ether"))

    sbtcPool = Contract("0x7fC77b5c7614E1533320Ea6DDc2Eb61fa00A9714",
                        owner=gov)  # sbtcCRV pool address (threePool)
    ysBTC = Contract("0x7Ff566E1d69DEfF32a7b244aE7276b9f90e9D0f6",
                     owner=gov)  # sbtc vault (threePool)
    #crv3Strat = Contract(
    #    "0xC59601F0CC49baa266891b7fc63d2D5FE097A79D", owner=gov
    #)  # crv3 strat (threePool)
    #crv3StratOwner = Contract(
    #    "0xd0aC37E3524F295D141d3839d5ed5F26A40b589D", owner=gov
    #)  # crv3 stratOwner (threePool)
    # uni = Contract.from_explorer(
    #  "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D", owner=gov
    # )  # UNI router v2

    strategy = guardian.deploy(StrategyWBTCsBTCv2, yUSDT3, wbtc, sbtcPool,
                               ysBTC, sbtc)
    strategy.setStrategist(strategist)

    yUSDT3.addStrategy(strategy, 10_000, 0, 0, {"from": gov})

    wbtc.approve(gov, Wei("1000000 ether"), {"from": gov})
    wbtc.transferFrom(gov, bob, 100000000, {"from": gov})
    wbtc.transferFrom(gov, alice, 1000000000, {"from": gov})
    wbtc.transferFrom(gov, tinytim, 1000000, {"from": gov})
    wbtc.approve(yUSDT3, Wei("1000000 ether"), {"from": bob})
    wbtc.approve(yUSDT3, Wei("1000000 ether"), {"from": alice})
    wbtc.approve(yUSDT3, Wei("1000000 ether"), {"from": tinytim})
    sbtc.approve(gov, Wei("1000000 ether"), {"from": gov})
    yUSDT3.approve(gov, Wei("1000000 ether"), {"from": gov})
    sbtc.approve(ysBTC, Wei("1000000 ether"), {"from": gov})
    wbtc.approve(sbtcPool, Wei("1000000 ether"), {"from": gov})

    wbtc.approve(sbtcPool, Wei("1000000 ether"), {"from": gov})
    # depositing DAI to generate crv3 tokens.
    #crv3.approve(crv3_liquidity, Wei("1000000 ether"), {"from": crv3_liquidity})
    #threePool.add_liquidity([0, 200000000000, 0], 0, {"from": gov})
    #giving Gov some shares to mimic profit
    #yCRV3.depositAll({"from": gov})

    # users deposit to vault
    yUSDT3.deposit(100000000, {"from": bob})
    yUSDT3.deposit(1000000000, {"from": alice})
    yUSDT3.deposit(1000000, {"from": tinytim})

    chain.mine(1)

    strategy.harvest({"from": gov})
    chain.mine(1)

    strategy.setEmergencyExit({"from": gov})
    strategy.harvest({"from": gov})
    chain.mine(1)

    assert wbtc.balanceOf(yUSDT3) > 0
    assert wbtc.balanceOf(strategy) < (1e8)
    assert ysBTC.balanceOf(strategy) < (1e18)

    yUSDT3.withdraw({"from": alice})

    assert wbtc.balanceOf(alice) > 0
    assert wbtc.balanceOf(strategy) < (1e8)
    assert wbtc.balanceOf(yUSDT3) > 0
    assert wbtc.balanceOf(bob) == 0

    yUSDT3.withdraw({"from": bob})

    assert wbtc.balanceOf(bob) > 0
    assert wbtc.balanceOf(strategy) < (1e8)

    yUSDT3.withdraw({"from": tinytim})
    assert wbtc.balanceOf(tinytim) > 0

    pass
def test_operation(pm, chain):
    dai_liquidity = accounts.at("0xbebc44782c7db0a1a60cb6fe97d0b483032ff1c7",
                                force=True)  # using curve pool (lots of dai)

    crv3_liquidity = accounts.at("0x6c3F90f043a72FA612cbac8115EE7e52BDe6E490",
                                 force=True)  # yearn treasury (lots of crv3)

    #altCRV_liquidity = accounts.at(
    #    "0x907ebd0ddfd74fdaa1abb8a7e2294475e179a9ea", force=True
    #)  # giant amount

    rewards = accounts[2]
    gov = accounts[3]
    guardian = accounts[4]
    bob = accounts[5]
    alice = accounts[6]
    strategist = accounts[7]
    tinytim = accounts[8]

    dai = Contract("0x6b175474e89094c44da98b954eedeac495271d0f",
                   owner=gov)  # DAI token

    dai.approve(dai_liquidity, Wei("1000000 ether"), {"from": dai_liquidity})
    dai.transferFrom(dai_liquidity, gov, Wei("300000 ether"),
                     {"from": dai_liquidity})

    crv3 = Contract("0x6c3F90f043a72FA612cbac8115EE7e52BDe6E490",
                    owner=gov)  # crv3 token address (threePool)

    altCRV = Contract("0xD2967f45c4f384DEEa880F807Be904762a3DeA07",
                      owner=gov)  # altCRV token (gUSDCrv)

    crv3.approve(crv3_liquidity, Wei("1000000 ether"),
                 {"from": crv3_liquidity})
    crv3.transferFrom(crv3_liquidity, gov, Wei("100 ether"),
                      {"from": crv3_liquidity})

    #altCRV.approve(altCRV_liquidity, Wei("1000000 ether"), {"from": altCRV_liquidity})
    #altCRV.transferFrom(altCRV_liquidity, gov, Wei("1000 ether"), {"from": altCRV_liquidity})

    # config dai vault.
    Vault = pm(config["dependencies"][0]).Vault
    yDAI = Vault.deploy({"from": gov})
    yDAI.initialize(dai, gov, rewards, "", "", {"from": gov})
    yDAI.setDepositLimit(Wei("1000000 ether"))

    threePool = Contract("0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7",
                         owner=gov)  # crv3 pool address (threePool)
    altCrvPool = Contract("0x4f062658EaAF2C1ccf8C8e36D6824CDf41167956",
                          owner=gov)  # atlCrvPool pool address (gusdCrv)
    targetVault = Contract("0xcC7E70A958917cCe67B4B87a8C30E6297451aE98",
                           owner=gov)  # target vault (gusdCrv)
    targetVaultStrat = Contract("0xD42eC70A590C6bc11e9995314fdbA45B4f74FABb",
                                owner=gov)  # targetVault strat (gusd)
    targetVaultStratOwner = Contract(
        "0xFEB4acf3df3cDEA7399794D0869ef76A6EfAff52",
        owner=gov)  # targetVault stratOwner (threePool)

    strategy = guardian.deploy(StrategyDAImUSDv2, yDAI, dai, threePool,
                               targetVault, crv3, altCRV, altCrvPool)
    strategy.setStrategist(strategist)

    yDAI.addStrategy(strategy, 10_000, 0, 0, {"from": gov})

    dai.approve(gov, Wei("1000000 ether"), {"from": gov})
    dai.transferFrom(gov, bob, Wei("1000 ether"), {"from": gov})
    dai.transferFrom(gov, alice, Wei("4000 ether"), {"from": gov})
    dai.transferFrom(gov, tinytim, Wei("10 ether"), {"from": gov})
    dai.approve(yDAI, Wei("1000000 ether"), {"from": bob})
    dai.approve(yDAI, Wei("1000000 ether"), {"from": alice})
    dai.approve(yDAI, Wei("1000000 ether"), {"from": tinytim})
    crv3.approve(gov, Wei("1000000 ether"), {"from": gov})
    yDAI.approve(gov, Wei("1000000 ether"), {"from": gov})
    targetVault.approve(gov, Wei("1000000 ether"), {"from": gov})
    altCRV.approve(gov, Wei("1000000 ether"), {"from": gov})
    dai.approve(threePool, Wei("1000000 ether"), {"from": gov})
    crv3.approve(altCrvPool, Wei("1000000 ether"), {"from": gov})

    targetVaultStrat.setStrategistReward(0, {"from": targetVaultStratOwner})
    targetVaultStrat.setTreasuryFee(0, {"from": targetVaultStratOwner})
    targetVaultStrat.setWithdrawalFee(0, {"from": targetVaultStratOwner})

    # users deposit to vault
    yDAI.deposit(Wei("1000 ether"), {"from": bob})
    yDAI.deposit(Wei("4000 ether"), {"from": alice})
    yDAI.deposit(Wei("10 ether"), {"from": tinytim})

    a = yDAI.pricePerShare()

    chain.mine(1)

    strategy.harvest({"from": gov})

    assert targetVault.balanceOf(strategy) > 0
    chain.sleep(3600 * 24 * 7 * 10)
    chain.mine(1)
    a = yDAI.pricePerShare()

    # small profit
    t = targetVault.getPricePerFullShare()
    c = strategy.estimatedTotalAssets()
    targetVaultStrat.harvest({"from": targetVaultStratOwner})
    s = targetVault.getPricePerFullShare()
    d = strategy.estimatedTotalAssets()
    assert t < s
    assert d > c

    assert yDAI.strategies(strategy).dict()['totalDebt'] < d

    strategy.harvest({"from": gov})
    chain.mine(1)

    b = yDAI.pricePerShare()

    assert b > a

    #withdrawals have a slippage protection parameter, defaults to 1 = 0.01%.
    #overwriting here to be 1.5%, to account for slippage from multiple hops.
    #slippage also counts "beneficial" slippage, such as DAI being overweight in these pools
    #d = yUSDT3.balanceOf(alice)

    c = yDAI.balanceOf(alice)

    yDAI.withdraw(c, alice, 150, {"from": alice})

    assert dai.balanceOf(alice) > 0
    assert dai.balanceOf(strategy) == 0
    assert dai.balanceOf(bob) == 0
    assert targetVault.balanceOf(strategy) > 0

    d = yDAI.balanceOf(bob)
    yDAI.withdraw(d, bob, 150, {"from": bob})

    assert dai.balanceOf(bob) > 0
    assert dai.balanceOf(strategy) == 0

    e = yDAI.balanceOf(tinytim)
    yDAI.withdraw(e, tinytim, 150, {"from": tinytim})

    assert dai.balanceOf(tinytim) > 0
    assert dai.balanceOf(strategy) == 0

    # We should have made profit
    assert yDAI.pricePerShare() > 1

    #print("\ntinytim", dai.balanceOf(tinytim)/1e18)
    #print("\nbob", dai.balanceOf(bob)/1e18)
    #print("\nalice", dai.balanceOf(alice)/1e18)
    #print("\nvault", targetVault.balanceOf(strategy)/1e18)

    assert 1 == 2

    pass
예제 #15
0
def test_asset_positions_of(ironBankAdapter, accounts):

    weth = Contract(wethAddress)
    cyWeth = Contract(cyWethAddress)
    user = accounts.at(userAddress, force=True)
    MAX_UINT256 = 2**256 - 1
    weth.approve(cyWeth, MAX_UINT256, {"from": user})
    weth_bal = weth.balanceOf(userAddress)
    cyWeth.mint(weth_bal, {"from": user})

    comptroller = Contract(comptrollerAddress)

    comptroller.enterMarkets([cyWeth], {"from": user})

    cyWeth = Contract(cyWethAddress)
    cyWethTokenAddress = ironBankAdapter.assetUnderlyingTokenAddress(
        cyWethAddress)
    cyWethTokenPrice = ironBankAdapter.assetUnderlyingTokenPriceUsdc(
        cyWethAddress)
    decimal = cyWeth.decimals()

    userSupplyBalanceShares = cyWeth.balanceOf(userAddress)
    userBorrowBalanceShares = cyWeth.borrowBalanceStored(userAddress)
    assert userSupplyBalanceShares > 0
    assert userBorrowBalanceShares > 0

    exchangeRate = cyWeth.exchangeRateStored()

    userSupplyBalanceUnderlying = userSupplyBalanceShares * exchangeRate / 10**18

    positions = ironBankAdapter.assetPositionsOf(userAddress, cyWethAddress)
    assert userSupplyBalanceUnderlying > 0
    # print(positions)
    supplyPosition = positions[0]

    # basic info test
    assetId = supplyPosition[0]
    tokenId = supplyPosition[1]
    typeId = supplyPosition[2]
    balance = supplyPosition[3]
    # print(assetId, tokenId, typeId, balance)
    assert assetId == cyWethAddress
    assert tokenId == cyWethTokenAddress
    assert typeId == "LEND"
    assert balance == userSupplyBalanceShares

    # Test token allowances
    tokenAllowances = supplyPosition[5]
    owner = tokenAllowances[0][0]
    spender = tokenAllowances[0][1]
    allowance = tokenAllowances[0][2]
    assert owner == userAddress
    assert spender == cyWethAddress
    assert allowance > 0

    # Test account borrow balance
    userBorrowedCyTokenBalance = userBorrowBalanceShares * 10**18 / exchangeRate

    borrowPosition = positions[1]

    # basic info test
    assetId = borrowPosition[0]
    tokenId = borrowPosition[1]
    typeId = borrowPosition[2]
    balance = borrowPosition[3]
    # print(assetId, tokenId, typeId, balance)
    assert assetId == cyWethAddress
    assert tokenId == cyWethTokenAddress
    assert typeId == "BORROW"
    assert balance == userBorrowedCyTokenBalance

    # Test token allowances
    tokenAllowances = borrowPosition[5]
    owner = tokenAllowances[0][0]
    spender = tokenAllowances[0][1]
    allowance = tokenAllowances[0][2]
    assert owner == userAddress
    assert spender == cyWethAddress
    assert allowance > 0
예제 #16
0
def test_operation(pm, chain):
    dai_liquidity = accounts.at("0xbebc44782c7db0a1a60cb6fe97d0b483032ff1c7",
                                force=True)  # using curve pool (lots of dai)

    crv3_liquidity = accounts.at("0x6c3F90f043a72FA612cbac8115EE7e52BDe6E490",
                                 force=True)  # yearn treasury (lots of crv3)

    altCRV_liquidity = accounts.at(
        "0xe6e6e25efda5f69687aa9914f8d750c523a1d261",
        force=True)  # giant amount

    rewards = accounts[2]
    gov = accounts[3]
    guardian = accounts[4]
    bob = accounts[5]
    alice = accounts[6]
    strategist = accounts[7]
    tinytim = accounts[8]

    dai = Contract("0x6b175474e89094c44da98b954eedeac495271d0f",
                   owner=gov)  # DAI token

    dai.approve(dai_liquidity, Wei("1000000 ether"), {"from": dai_liquidity})
    dai.transferFrom(dai_liquidity, gov, Wei("300000 ether"),
                     {"from": dai_liquidity})

    crv3 = Contract("0x6c3F90f043a72FA612cbac8115EE7e52BDe6E490",
                    owner=gov)  # crv3 token address (threePool)

    altCRV = Contract("0x1AEf73d49Dedc4b1778d0706583995958Dc862e6",
                      owner=gov)  # altCRV token (mUSDCrv)

    crv3.approve(crv3_liquidity, Wei("1000000 ether"),
                 {"from": crv3_liquidity})
    crv3.transferFrom(crv3_liquidity, gov, Wei("100 ether"),
                      {"from": crv3_liquidity})

    altCRV.approve(altCRV_liquidity, Wei("1000000 ether"),
                   {"from": altCRV_liquidity})
    altCRV.transferFrom(altCRV_liquidity, gov, Wei("1000 ether"),
                        {"from": altCRV_liquidity})

    # config dai vault.
    Vault = pm(config["dependencies"][0]).Vault
    yDAI = Vault.deploy({"from": gov})
    yDAI.initialize(dai, gov, rewards, "", "", {"from": gov})
    yDAI.setDepositLimit(Wei("1000000 ether"))

    threePool = Contract("0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7",
                         owner=gov)  # crv3 pool address (threePool)
    altCrvPool = Contract("0x8474DdbE98F5aA3179B3B3F5942D724aFcdec9f6",
                          owner=gov)  # atlCrvPool pool address (musdCrv)
    targetVault = Contract("0x0FCDAeDFb8A7DfDa2e9838564c5A1665d856AFDF",
                           owner=gov)  # target vault (musdCrv)
    targetVaultStrat = Contract("0xBA0c07BBE9C22a1ee33FE988Ea3763f21D0909a0",
                                owner=gov)  # targetVault strat (threePool)
    targetVaultStratOwner = Contract(
        "0xFEB4acf3df3cDEA7399794D0869ef76A6EfAff52",
        owner=gov)  # targetVault stratOwner (threePool)

    strategy = guardian.deploy(StrategyDAImUSDv2, yDAI, dai, threePool,
                               targetVault, crv3, altCRV, altCrvPool)
    strategy.setStrategist(strategist)

    yDAI.addStrategy(strategy, 10_000, 0, 0, {"from": gov})

    dai.approve(gov, Wei("1000000 ether"), {"from": gov})
    dai.transferFrom(gov, bob, Wei("1000 ether"), {"from": gov})
    dai.transferFrom(gov, alice, Wei("4000 ether"), {"from": gov})
    dai.transferFrom(gov, tinytim, Wei("10 ether"), {"from": gov})
    dai.approve(yDAI, Wei("1000000 ether"), {"from": bob})
    dai.approve(yDAI, Wei("1000000 ether"), {"from": alice})
    dai.approve(yDAI, Wei("1000000 ether"), {"from": tinytim})
    crv3.approve(gov, Wei("1000000 ether"), {"from": gov})
    yDAI.approve(gov, Wei("1000000 ether"), {"from": gov})
    targetVault.approve(gov, Wei("1000000 ether"), {"from": gov})
    altCRV.approve(gov, Wei("1000000 ether"), {"from": gov})
    dai.approve(threePool, Wei("1000000 ether"), {"from": gov})
    crv3.approve(altCrvPool, Wei("1000000 ether"), {"from": gov})

    targetVaultStrat.setStrategistReward(0, {"from": targetVaultStratOwner})
    targetVaultStrat.setTreasuryFee(0, {"from": targetVaultStratOwner})
    targetVaultStrat.setWithdrawalFee(0, {"from": targetVaultStratOwner})

    # users deposit to vault
    yDAI.deposit(Wei("1000 ether"), {"from": bob})
    yDAI.deposit(Wei("4000 ether"), {"from": alice})
    yDAI.deposit(Wei("10 ether"), {"from": tinytim})

    a = yDAI.pricePerShare()

    chain.mine(1)

    strategy.harvest({"from": gov})

    assert targetVault.balanceOf(strategy) > 0
    chain.sleep(3600 * 24 * 7 * 10)
    chain.mine(1)
    a = yDAI.pricePerShare()

    # small profit
    t = targetVault.getPricePerFullShare()
    c = strategy.estimatedTotalAssets()
    targetVaultStrat.harvest({"from": targetVaultStratOwner})
    s = targetVault.getPricePerFullShare()
    d = strategy.estimatedTotalAssets()
    assert t < s
    assert d > c

    assert yDAI.strategies(strategy).dict()['totalDebt'] < d

    strategy.harvest({"from": gov})
    chain.mine(1)

    b = yDAI.pricePerShare()

    assert b > a

    #withdrawals have a slippage protection parameter, defaults to 1 = 0.01%.
    #overwriting here to be 1.5%, to account for slippage from multiple hops.
    #slippage also counts "beneficial" slippage, such as DAI being overweight in these pools
    #d = yUSDT3.balanceOf(alice)

    c = yDAI.balanceOf(alice)

    yDAI.withdraw(c, alice, 150, {"from": alice})

    assert dai.balanceOf(alice) > 0
    assert dai.balanceOf(strategy) == 0
    assert dai.balanceOf(bob) == 0
    assert targetVault.balanceOf(strategy) > 0

    d = yDAI.balanceOf(bob)
    yDAI.withdraw(d, bob, 150, {"from": bob})

    assert dai.balanceOf(bob) > 0
    assert dai.balanceOf(strategy) == 0

    e = yDAI.balanceOf(tinytim)
    yDAI.withdraw(e, tinytim, 150, {"from": tinytim})

    assert dai.balanceOf(tinytim) > 0
    assert dai.balanceOf(strategy) == 0

    # We should have made profit
    assert yDAI.pricePerShare() > 1

    #print("\ntinytim", dai.balanceOf(tinytim)/1e18)
    #print("\nbob", dai.balanceOf(bob)/1e18)
    #print("\nalice", dai.balanceOf(alice)/1e18)
    #print("\nvault", targetVault.balanceOf(strategy)/1e18)

    pass
def test_operation(pm, chain):
    dai_liquidity = accounts.at("0xbebc44782c7db0a1a60cb6fe97d0b483032ff1c7",
                                force=True)  # using curve pool (lots of dai)

    crv3_liquidity = accounts.at("0x6c3F90f043a72FA612cbac8115EE7e52BDe6E490",
                                 force=True)  # yearn treasury (lots of crv3)

    altCRV_liquidity = accounts.at(
        "0xe6e6e25efda5f69687aa9914f8d750c523a1d261",
        force=True)  # giant amount

    rewards = accounts[2]
    gov = accounts[3]
    guardian = accounts[4]
    bob = accounts[5]
    alice = accounts[6]
    strategist = accounts[7]
    tinytim = accounts[8]

    dai = Contract("0x6b175474e89094c44da98b954eedeac495271d0f",
                   owner=gov)  # DAI token

    dai.approve(dai_liquidity, Wei("1000000 ether"), {"from": dai_liquidity})
    dai.transferFrom(dai_liquidity, gov, Wei("300000 ether"),
                     {"from": dai_liquidity})

    crv3 = Contract("0x6c3F90f043a72FA612cbac8115EE7e52BDe6E490",
                    owner=gov)  # crv3 token address (threePool)

    altCRV = Contract("0x1AEf73d49Dedc4b1778d0706583995958Dc862e6",
                      owner=gov)  # altCRV token (mUSDCrv)

    crv3.approve(crv3_liquidity, Wei("1000000 ether"),
                 {"from": crv3_liquidity})
    crv3.transferFrom(crv3_liquidity, gov, Wei("100 ether"),
                      {"from": crv3_liquidity})

    altCRV.approve(altCRV_liquidity, Wei("1000000 ether"),
                   {"from": altCRV_liquidity})
    altCRV.transferFrom(altCRV_liquidity, gov, Wei("1000 ether"),
                        {"from": altCRV_liquidity})

    # config dai vault.
    Vault = pm(config["dependencies"][0]).Vault
    yDAI = Vault.deploy({"from": gov})
    yDAI.initialize(dai, gov, rewards, "", "", {"from": gov})
    yDAI.setDepositLimit(Wei("1000000 ether"))

    threePool = Contract("0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7",
                         owner=gov)  # crv3 pool address (threePool)
    altCrvPool = Contract("0x8474DdbE98F5aA3179B3B3F5942D724aFcdec9f6",
                          owner=gov)  # atlCrvPool pool address (musdCrv)
    targetVault = Contract("0x0FCDAeDFb8A7DfDa2e9838564c5A1665d856AFDF",
                           owner=gov)  # target vault (musdCrv)
    targetVaultStrat = Contract("0xBA0c07BBE9C22a1ee33FE988Ea3763f21D0909a0",
                                owner=gov)  # targetVault strat (threePool)
    targetVaultStratOwner = Contract(
        "0xFEB4acf3df3cDEA7399794D0869ef76A6EfAff52",
        owner=gov)  # targetVault stratOwner (threePool)

    strategy = guardian.deploy(StrategyDAImUSDv2, yDAI, dai, threePool,
                               targetVault, crv3, altCRV, altCrvPool)
    strategy.setStrategist(strategist)

    yDAI.addStrategy(strategy, 10_000, 0, 0, {"from": gov})

    dai.approve(gov, Wei("1000000 ether"), {"from": gov})
    dai.transferFrom(gov, bob, Wei("1000 ether"), {"from": gov})
    dai.transferFrom(gov, alice, Wei("4000 ether"), {"from": gov})
    dai.transferFrom(gov, tinytim, Wei("10 ether"), {"from": gov})
    dai.approve(yDAI, Wei("1000000 ether"), {"from": bob})
    dai.approve(yDAI, Wei("1000000 ether"), {"from": alice})
    dai.approve(yDAI, Wei("1000000 ether"), {"from": tinytim})
    crv3.approve(gov, Wei("1000000 ether"), {"from": gov})
    yDAI.approve(gov, Wei("1000000 ether"), {"from": gov})
    targetVault.approve(gov, Wei("1000000 ether"), {"from": gov})
    altCRV.approve(gov, Wei("1000000 ether"), {"from": gov})
    dai.approve(threePool, Wei("1000000 ether"), {"from": gov})
    crv3.approve(altCrvPool, Wei("1000000 ether"), {"from": gov})

    targetVaultStrat.setStrategistReward(0, {"from": targetVaultStratOwner})
    targetVaultStrat.setTreasuryFee(0, {"from": targetVaultStratOwner})
    targetVaultStrat.setWithdrawalFee(0, {"from": targetVaultStratOwner})

    # users deposit to vault
    yDAI.deposit(Wei("1000 ether"), {"from": bob})
    yDAI.deposit(Wei("4000 ether"), {"from": alice})
    yDAI.deposit(Wei("10 ether"), {"from": tinytim})

    a = yDAI.pricePerShare()

    chain.mine(1)

    strategy.harvest({"from": gov})

    newstrategy = guardian.deploy(StrategyDAImUSDv2, yDAI, dai, threePool,
                                  targetVault, crv3, altCRV, altCrvPool)
    newstrategy.setStrategist(strategist)

    yDAI.migrateStrategy(strategy, newstrategy, {"from": gov})

    assert targetVault.balanceOf(strategy) == 0
    assert targetVault.balanceOf(newstrategy) > 0

    pass