Exemple #1
0
def deploy_part_one(admin, confs=1, deployments_json=None):
    token = ERC20CRV.deploy("Curve DAO Token", "CRV", 18, {
        "from": admin,
        "required_confs": confs
    })
    voting_escrow = VotingEscrow.deploy(
        token,
        "Vote-escrowed CRV",
        "veCRV",
        "veCRV_1.0.0",
        {
            "from": admin,
            "required_confs": confs
        },
    )
    deployments = {
        "ERC20CRV": token.address,
        "VotingEscrow": voting_escrow.address,
    }
    if deployments_json is not None:
        with open(deployments_json, "w") as fp:
            json.dump(deployments, fp)
        print(f"Deployment addresses saved to {deployments_json}")

    return token, voting_escrow
def development():
    """
    Vest tokens in a development environment and validate the result.
    """
    token = ERC20CRV.deploy("Curve DAO Token", "CRV", 18,
                            {"from": accounts[0]})
    vesting_escrow, vested_amounts = vest_tokens(accounts[0], token, 1)
    sanity_check(token, vesting_escrow, vested_amounts)
def live_part_two():
    admin, _ = config.get_live_admin()
    with open(config.DEPLOYMENTS_JSON) as fp:
        deployments = json.load(fp)
    token = ERC20CRV.at(deployments['ERC20CRV'])
    voting_escrow = VotingEscrow.at(deployments['VotingEscrow'])

    deploy_part_two(admin, token, voting_escrow, config.REQUIRED_CONFIRMATIONS,
                    config.DEPLOYMENTS_JSON)
Exemple #4
0
def main():
    accounts.from_mnemonic(SEED)
    admin = accounts[0]


    token = ERC20CRV.deploy("Curve DAO Token", "CRV", 18, {'from': admin, 'required_confs': confs})
    voting_escrow = VotingEscrow.deploy(
        token, "Vote-escrowed CRV", "veCRV", "veCRV_1.0.0", {'from': admin, 'required_confs': confs}
    )


    coin_a = ERC20.deploy("Coin A", "USDA", 18, {'from': admin, 'required_confs': confs})
    coin_b = ERC20.deploy("Coin B", "USDB", 18, {'from': admin, 'required_confs': confs})
    coin_a._mint_for_testing(10 ** 9 * 10 ** 18, {'from': admin, 'required_confs': confs})
    coin_b._mint_for_testing(10 ** 9 * 10 ** 18, {'from': admin, 'required_confs': confs})

    lp_token = ERC20LP.deploy("Some pool", "cPool", 18, 0, {'from': admin, 'required_confs': confs})
    pool = CurvePool.deploy([coin_a, coin_b], lp_token, 100, 4 * 10 ** 6, {'from': admin, 'required_confs': confs})
    lp_token.set_minter(pool, {'from': admin, 'required_confs': confs})

    coin_a.approve(pool, "1000000000000000000000", {'from': admin})
    coin_b.approve(pool, "1000000000000000000000", {'from': admin})
    pool.add_liquidity(["100000000000000", "200000000000000"], 0, {'from': admin})

    contract = CurveRewards.deploy(lp_token, coin_a, {'from': accounts[0], 'required_confs': confs})
    contract.setRewardDistribution(accounts[0], {'from': accounts[0], 'required_confs': confs})
    registry = Registry.deploy([ZERO_ADDRESS] * 4, {'from': admin, 'required_confs': confs})

    coin_a.transfer(contract, 100e18, {'from': accounts[0], 'required_confs': confs})

    liquidity_gauge_rewards = LiquidityGaugeReward.deploy(lp_token, '0xbE45e0E4a72aEbF9D08F93E64701964d2CC4cF96', contract, coin_a, {'from': admin, 'required_confs': confs})

    for account in DISTRIBUTION_ADDRESSES:
        coin_a.transfer(account, DISTRIBUTION_AMOUNT, {'from': admin, 'required_confs': confs})
        coin_b.transfer(account, DISTRIBUTION_AMOUNT, {'from': admin, 'required_confs': confs})

    pool.commit_transfer_ownership(ARAGON_AGENT, {'from': admin, 'required_confs': confs})
    pool.apply_transfer_ownership({'from': admin, 'required_confs': confs})
    registry.commit_transfer_ownership(ARAGON_AGENT, {'from': admin, 'required_confs': confs})
    registry.apply_transfer_ownership({'from': admin, 'required_confs': confs})

    gauge_controller = GaugeController.deploy(token, voting_escrow, {'from': admin, 'required_confs': confs})
    minter = Minter.deploy(token, gauge_controller, {'from': admin, 'required_confs': confs})
    liquidity_gauge = LiquidityGauge.deploy(lp_token, minter, {'from': admin, 'required_confs': confs})

    token.set_minter(minter, {'from': admin, 'required_confs': confs})
    gauge_controller.add_type(b'Liquidity', {'from': admin, 'required_confs': confs})
    gauge_controller.change_type_weight(0, 10 ** 18, {'from': admin, 'required_confs': confs})
    gauge_controller.add_gauge(liquidity_gauge, 0, 10 ** 18, {'from': admin, 'required_confs': confs})

    gauge_controller.commit_transfer_ownership(ARAGON_AGENT, {'from': admin, 'required_confs': confs})
    gauge_controller.apply_transfer_ownership({'from': admin, 'required_confs': confs})
    voting_escrow.commit_transfer_ownership(ARAGON_AGENT, {'from': admin, 'required_confs': confs})
    voting_escrow.apply_transfer_ownership({'from': admin, 'required_confs': confs})

    PoolProxy.deploy({'from': admin, 'required_confs': confs})
def development():
    """
    Vest tokens in a development environment.

    * Deploy the DAO token
    * Run the main deployment and distribution logic
    * Perform a sanity check to confirm balances and total supply are as expected
    """
    token = ERC20CRV.deploy("Curve DAO Token", "CRV", 18, {'from': accounts[0]})
    vesting_escrow, vested_amounts = vest_tokens(accounts[0], accounts[1:5], token, 1)
    sanity_check(vesting_escrow, vested_amounts)
Exemple #6
0
def transfer_ownership(admin,
                       new_admin,
                       gauge_controller,
                       voting_escrow,
                       pool_proxy,
                       erc20crv,
                       confs=1):
    gauge_controller = GaugeController.at(gauge_controller)
    voting_escrow = VotingEscrow.at(voting_escrow)
    pool_proxy = PoolProxy.at(pool_proxy)
    erc20crv = ERC20CRV.at(erc20crv)

    gauge_controller.commit_transfer_ownership(new_admin, {
        'from': admin,
        'required_confs': confs
    })
    gauge_controller.apply_transfer_ownership({
        'from': admin,
        'required_confs': confs
    })

    voting_escrow.commit_transfer_ownership(new_admin, {
        'from': admin,
        'required_confs': confs
    })
    voting_escrow.apply_transfer_ownership({
        'from': admin,
        'required_confs': confs
    })

    pool_proxy.commit_set_admins(new_admin, new_admin, new_admin, {
        'from': admin,
        'required_confs': confs
    })
    pool_proxy.apply_set_admins({'from': admin, 'required_confs': confs})

    erc20crv.set_admin(new_admin, {'from': admin, 'required_confs': confs})
def vest_tokens(admin, funding_admins, token_address, confs):
    start_idx = len(history)

    # get token Contract object
    token = ERC20CRV.at(token_address)

    # deploy vesting contract
    start_time = token.future_epoch_time_write.call()

    vesting_escrow = VestingEscrow.deploy(
        token,
        start_time,
        start_time + VESTING_PERIOD,
        False,
        funding_admins,
        {
            "from": admin,
            "required_confs": confs
        },
    )
    _log_tx(
        txid=vesting_escrow.tx.txid,
        fn_name="VestingEscrow.deploy",
        contract_address=vesting_escrow.address,
    )

    # load vesting data from json
    with open(config.LP_VESTING_JSON) as fp:
        vested_pct = {k.lower(): Decimal(v) for k, v in json.load(fp).items()}

    for addr in BLACKLIST:
        if addr.lower() in vested_pct:
            del vested_pct[addr]

    # calculate absolute amounts to be distributed
    initial_total = sum(int(v * TOTAL_AMOUNT) for v in vested_pct.values())
    adjustment_pct = Decimal(TOTAL_AMOUNT) / initial_total
    vested_amounts = sorted(
        ([k, int(v * TOTAL_AMOUNT * adjustment_pct)]
         for k, v in vested_pct.items()),
        key=lambda k: k[1],
        reverse=True,
    )

    if vested_amounts[-1][1] < 0:
        raise ValueError(
            f"'{config.LP_VESTING_JSON}' contains negative amounts!")

    vested_amounts = [i for i in vested_amounts if i[1]]

    # floats -> int, we expect to be ever so slightly over, so lets fix that
    final_total = sum(i[1] for i in vested_amounts)

    if not 0 < abs(final_total - TOTAL_AMOUNT) < len(vested_amounts):
        raise ValueError(
            "Imprecision!!! Distribution amounts are too far off!")

    for i in range(abs(final_total - TOTAL_AMOUNT)):
        if final_total < TOTAL_AMOUNT:
            vested_amounts[i][1] += 1
        else:
            vested_amounts[i][1] -= 1

    tx = token.approve(vesting_escrow, TOTAL_AMOUNT, {
        "from": admin,
        "required_confs": confs
    })
    _log_tx(txid=tx.txid,
            fn_name=tx.fn_name,
            spender=vesting_escrow.address,
            amount=TOTAL_AMOUNT)
    tx = vesting_escrow.add_tokens(TOTAL_AMOUNT, {
        "from": admin,
        "required_confs": confs
    })
    _log_tx(txid=tx.txid, fn_name=tx.fn_name, amount=TOTAL_AMOUNT)

    # convert vested_amounts into input args for `VestingEscrow.fund` calls
    fund_arguments = [([x[0] for x in vested_amounts[i:i + 100]],
                       [x[1] for x in vested_amounts[i:i + 100]])
                      for i in range(0, len(vested_amounts), 100)]

    # final call needs to be extended with zero values
    zeros = 100 - len(fund_arguments[-1][0])
    fund_arguments[-1] = (
        fund_arguments[-1][0] +
        ["0x0000000000000000000000000000000000000000"] * zeros,
        fund_arguments[-1][1] + [0] * zeros,
    )

    # use threading to handle the funding across several accounts
    funding_threads = []
    for acct in [admin] + funding_admins:
        thread = threading.Thread(target=_fund_accounts,
                                  args=(acct, vesting_escrow, fund_arguments,
                                        confs))
        funding_threads.append(thread)
        thread.start()

    for thread in funding_threads:
        thread.join()

    # burn all the admin accounts!
    tx = vesting_escrow.disable_fund_admins({
        "from": admin,
        "required_confs": confs
    })
    _log_tx(txid=tx.txid, fn_name=tx.fn_name)
    vesting_escrow.commit_transfer_ownership(
        "0x000000000000000000000000000000000000dead", {
            "from": admin,
            "required_confs": confs
        })
    _log_tx(txid=tx.txid, fn_name=tx.fn_name)
    vesting_escrow.apply_transfer_ownership({
        "from": admin,
        "required_confs": confs
    })
    _log_tx(txid=tx.txid, fn_name=tx.fn_name)

    gas_used = sum(i.gas_used for i in history[start_idx:])
    print(f"Distribution complete! Total gas used: {gas_used}")

    # return the final vested amounts to be used in `sanity_check`, if desired
    return vesting_escrow, vested_amounts
def vest_tokens(admin, token_address, confs):
    token = ERC20CRV.at(token_address)

    # deploy library and vesting factories
    target = VestingEscrowSimple.deploy({
        "from": admin,
        "required_confs": confs
    })

    factory_contracts = []
    for data in config.FACTORY_ESCROWS:
        factory = VestingEscrowFactory.deploy(target, data["admin"], {
            "from": admin,
            "required_confs": confs
        })
        token.transfer(factory, data["amount"], {
            "from": admin,
            "required_confs": confs
        })
        factory_contracts.append((factory, data["amount"]))

    # deploy standard escrows
    start_time = token.future_epoch_time_write.call()
    for data in config.STANDARD_ESCROWS:

        vesting_escrow = VestingEscrow.deploy(
            token,
            start_time,
            start_time + data["duration"],
            data["can_disable"],
            [ZERO_ADDRESS] * 4,
            {
                "from": admin,
                "required_confs": confs
            },
        )
        data["contract"] = vesting_escrow

        total_amount = sum(data["recipients"].values())
        token.approve(vesting_escrow, total_amount, {
            "from": admin,
            "required_confs": confs
        })
        vesting_escrow.add_tokens(total_amount, {
            "from": admin,
            "required_confs": confs
        })

        zeros = 100 - len(data["recipients"])
        fund_inputs = tuple(data["recipients"].items())
        recipients = [i[0] for i in fund_inputs] + [ZERO_ADDRESS] * zeros
        amounts = [i[1] for i in fund_inputs] + [0] * zeros

        vesting_escrow.fund(recipients, amounts, {
            "from": admin,
            "required_confs": confs
        })

        if "admin" in data:
            vesting_escrow.commit_transfer_ownership(data["admin"], {
                "from": admin,
                "required_confs": confs
            })
            vesting_escrow.apply_transfer_ownership({
                "from": admin,
                "required_confs": confs
            })

    print("Deployments finished!\n\nFactories:")
    for factory, amount in factory_contracts:
        print(f"  {factory.address} : {amount} tokens")

    print("\nStandard Escrows:")
    for data in config.STANDARD_ESCROWS:
        total_amount = sum(data["recipients"].values())
        print(
            f"  {data['contract'].address}: {len(data['recipients'])} recipients, "
            f"{total_amount} total tokens, {data['duration']/YEAR} year lock")

    return config.STANDARD_ESCROWS, factory_contracts