Exemplo n.º 1
0
    def governance_queue_transaction(self,
                                     target,
                                     signature,
                                     data,
                                     eta,
                                     eth=0) -> str:
        multi = GnosisSafe(self.devMultisig)
        id = multi.addTx(
            MultisigTxMetadata(description="Queue timelock transaction"),
            {
                "to":
                self.governanceTimelock.address,
                "data":
                self.governanceTimelock.queueTransaction.encode_input(
                    target,
                    eth,
                    signature,
                    data,
                    eta,
                ),
            },
        )
        multi.executeTx(id)

        txHash = Web3.solidityKeccak(
            [
                "address",
                "uint256",
                "string",
                "bytes",
                "uint256",
            ],
            [
                target,
                eth,
                signature,
                data,
                eta,
            ],
        ).hex()

        txFilename = "{}.json".format(txHash)
        with open(os.path.join(TIMELOCK_DIR, txFilename), "w") as f:
            # Dump tx data to timelock pending tx dir.
            txData = {
                "target": target,
                "eth": eth,
                "signature": signature,
                "data": data.hex(),
                "eta": eta,
            }
            f.write(json.dumps(txData, indent=4, sort_keys=True))
        return txFilename
Exemplo n.º 2
0
def configure_bridge(badger: BadgerSystem, bridge: BridgeSystem):
    """
    Configures bridge to use curve token wrapper.
    """

    multi = GnosisSafe(badger.devMultisig)
    id = multi.addTx(
        MultisigTxMetadata(description="Set curve token wrapper on adapter",),
        {
            "to": bridge.adapter.address,
            "data": bridge.adapter.setCurveTokenWrapper.encode_input(
                bridge.curveTokenWrapper.address
            ),
        },
    )
    multi.executeTx(id)
Exemplo n.º 3
0
def whitelist_adapter_crv_sett(
    badger: BadgerSystem,
    bridge: BridgeSystem,
    multi: GnosisSafe,
    settID: str,
):
    sett = badger.sett_system.vaults[settID]
    id = multi.addTx(
        MultisigTxMetadata(
            description="Approve adapter access to sett {}".format(settID)
        ),
        {
            "to": sett.address,
            "data": sett.approveContractAccess.encode_input(bridge.adapter.address),
        },
    )
    multi.executeTx(id)
Exemplo n.º 4
0
 def upgrade_sett(self, id, newLogic):
     sett = self.getSett(id)
     multi = GnosisSafe(self.devMultisig)
     id = multi.addTx(
         MultisigTxMetadata(description="Upgrade timelock"),
         {
             "to": self.proxyAdmin.address,
             "data": self.proxyAdmin.upgrade.encode_input(sett, newLogic),
         },
     )
     tx = multi.executeTx(id)
Exemplo n.º 5
0
    def governance_execute_transaction(self, txFilename):
        multi = GnosisSafe(self.devMultisig)

        with open(os.path.join(TIMELOCK_DIR, txFilename), "r") as f:
            txData = json.load(f)
            id = multi.addTx(
                MultisigTxMetadata(description="Execute timelock transaction"),
                {
                    "to": self.governanceTimelock.address,
                    "data": self.governanceTimelock.executeTransaction.encode_input(
                        txData["target"],
                        txData["eth"],
                        txData["signature"],
                        txData["data"],
                        txData["eta"],
                    ),
                },
            )
            if multisig_success(multi.executeTx(id)):
                os.remove(os.path.join(TIMELOCK_DIR, txFilename))
    def wire_up_sett_multisig(self, vault, strategy, controller):
        multi = GnosisSafe(self.devMultisig, testMode=True)

        want = strategy.want()
        vault_want = vault.token()

        assert vault_want == want

        id = multi.addTx(
            MultisigTxMetadata(
                description="Set Vault for {} on Controller".format(want)
            ),
            {
                "to": controller.address,
                "data": controller.setVault.encode_input(
                    want, vault
                ),
            },
        )
        multi.executeTx(id)

        id = multi.addTx(
            MultisigTxMetadata(
                description="Approve Strategy for {} on Controller".format(want)
            ),
            {
                "to": controller.address,
                "data": controller.approveStrategy.encode_input(
                    want, strategy
                ),
            },
        )
        multi.executeTx(id)

        id = multi.addTx(
            MultisigTxMetadata(
                description="Set Strategy for {} on Controller".format(want)
            ),
            {
                "to": controller.address,
                "data": controller.setStrategy.encode_input(
                    want, strategy
                ),
            },
        )
        multi.executeTx(id)
Exemplo n.º 7
0
    def transfer(self, token, amount, recipient):

        rewardsEscrow = self.badger.rewardsEscrow
        multi = GnosisSafe(self.badger.devMultisig)

        # Approve Geyser as recipient if required
        if not rewardsEscrow.isApproved(recipient):
            multi.execute(
                MultisigTxMetadata(description="Approve Recipient " +
                                   recipient.address),
                {
                    "to": rewardsEscrow.address,
                    "data":
                    rewardsEscrow.approveRecipient.encode_input(recipient),
                },
            )

        before = token.balanceOf(recipient)

        # Top up Tree
        # TODO: Make the amount based on what we'll require for the next week
        id = multi.addTx(
            MultisigTxMetadata(description="Send {} {} to {}".format(
                token, amount, recipient)),
            {
                "to":
                rewardsEscrow.address,
                "data":
                rewardsEscrow.transfer.encode_input(token, recipient, amount),
            },
        )

        tx = multi.executeTx(id)
        print(tx.call_trace())

        after = token.balanceOf(recipient)
        console.print({"before": before, "after": after})
        assert after == before + amount
Exemplo n.º 8
0
def swap_transfer(recipient, params):
    badger = connect_badger("deploy-final.json")

    expectedMultisig = "0xB65cef03b9B89f99517643226d76e286ee999e77"
    assert badger.devMultisig == expectedMultisig
    multi = GnosisSafe(badger.devMultisig)

    one_wei = Wei("1")

    end_token = interface.IERC20(params["path"][-1])

    console.print("Executing Swap:", style="yellow")
    console.print(params)

    # === Approve Uniswap Router on Rewards Escrow if not approved ===
    uniswap = UniswapSystem()
    assert badger.rewardsEscrow.isApproved(badger.token)
    assert badger.rewardsEscrow.isApproved(uniswap.router)

    # === Approve UNI Router for Badger ===

    # Note: The allowance must first be set to 0
    id = multi.addTx(
        MultisigTxMetadata(
            description="Approve UNI Router to send BADGER",
            operation="call",
            callInfo={
                'address': uniswap.router,
                'amount': params["max_in"] // 2
            },
        ),
        params={
            "to":
            badger.rewardsEscrow.address,
            "data":
            badger.rewardsEscrow.call.encode_input(
                badger.token,
                0,
                badger.token.approve.encode_input(uniswap.router, 0),
            ),
        },
    )

    tx = multi.executeTx(id)

    # Set proper allowance
    id = multi.addTx(
        MultisigTxMetadata(
            description="Approve UNI Router to send BADGER",
            operation="call",
            callInfo={
                'address': uniswap.router,
                'amount': params["max_in"] // 2
            },
        ),
        params={
            "to":
            badger.rewardsEscrow.address,
            "data":
            badger.rewardsEscrow.call.encode_input(
                badger.token,
                0,
                badger.token.approve.encode_input(uniswap.router,
                                                  params["max_in"]),
            ),
        },
    )

    tx = multi.executeTx(id)

    console.print({
        "rewardsEscrowBalance":
        val(badger.token.balanceOf(badger.rewardsEscrow)),
        "rewardsEscrowRouterAllowance":
        val(badger.token.allowance(badger.rewardsEscrow, uniswap.router)),
        "max_in":
        val(params["max_in"]),
    })

    assert badger.token.balanceOf(badger.rewardsEscrow) > params["max_in"]
    assert (badger.token.allowance(badger.rewardsEscrow, uniswap.router) >=
            params["max_in"])

    # === Trade Badger for USDC through WBTC ===
    before = end_token.balanceOf(badger.rewardsEscrow)
    beforeBadger = badger.token.balanceOf(badger.rewardsEscrow)

    console.print({"EAO": params["exact_amount_out"]})

    expiration = chain.time() + 8000

    id = multi.addTx(
        MultisigTxMetadata(
            description="Trade Badger for output token",
            operation="call",
            callInfo={},
        ),
        params={
            "to":
            badger.rewardsEscrow.address,
            "data":
            badger.rewardsEscrow.call.encode_input(
                uniswap.router,
                0,
                uniswap.router.swapTokensForExactTokens.encode_input(
                    params["exact_amount_out"],
                    MaxUint256,
                    params["path"],
                    badger.rewardsEscrow,
                    expiration,
                ),
            ),
        },
    )

    tx = multi.executeTx(id)
    print(tx.call_trace())
    print(tx.events)

    printUniTrade(
        method="swapTokensForExactTokens",
        params=(
            params["exact_amount_out"],
            params["max_in"],
            params['path'],
            badger.rewardsEscrow,
            expiration,
        ),
    )

    console.log("=== Post Trade ===")
    console.print({
        'before_input_coin':
        beforeBadger,
        'after_input_coin':
        badger.token.balanceOf(badger.rewardsEscrow),
        'before_output_coin':
        before,
        'post_output_coin':
        end_token.balanceOf(badger.rewardsEscrow),
        'end_token':
        end_token,
        'chain_time_before':
        chain.time()
    })

    assert end_token.balanceOf(
        badger.rewardsEscrow) >= params["exact_amount_out"]

    # === Approve Recipient if not approved ===
    if not badger.rewardsEscrow.isApproved(recipient):
        id = multi.addTx(
            MultisigTxMetadata(
                description="Approve the transfer recipient",
                operation="approveRecipient",
                callInfo={},
            ),
            params={
                "to":
                badger.rewardsEscrow.address,
                "data":
                badger.rewardsEscrow.approveRecipient.encode_input(recipient),
            },
        )

        multi.executeTx(id)

    assert badger.rewardsEscrow.isApproved(recipient)

    # === Test Payment to recipient ===
    before = end_token.balanceOf(recipient)

    id = multi.addTx(
        MultisigTxMetadata(
            description="Test payment to recipientt",
            operation="transfer",
            callInfo={
                "to": recipient,
                "amount": one_wei
            },
        ),
        params={
            "to":
            badger.rewardsEscrow.address,
            "data":
            badger.rewardsEscrow.transfer.encode_input(end_token, recipient,
                                                       one_wei),
        },
    )

    multi.executeTx(id)
    after = end_token.balanceOf(recipient)
    assert after == before + one_wei

    # === Full Payment to recipient ===
    rest = params["exact_amount_out"] - 1
    before = end_token.balanceOf(recipient)

    id = multi.addTx(
        MultisigTxMetadata(
            description="$12k payment to auditor, in USDC",
            operation="transfer",
            callInfo={
                "to": recipient,
                "amount": rest
            },
        ),
        params={
            "to":
            badger.rewardsEscrow.address,
            "data":
            badger.rewardsEscrow.transfer.encode_input(end_token, recipient,
                                                       rest),
        },
    )

    multi.executeTx(id)

    after = end_token.balanceOf(recipient)

    assert after == before + rest

    print(before, after, before + params["exact_amount_out"])

    console.print("\n[green] ✅ Actions Complete [/green]")
Exemplo n.º 9
0
    def testTransactions(self):
        rewardsEscrow = self.badger.rewardsEscrow
        multi = GnosisSafe(self.badger.devMultisig)
        opsMulti = GnosisSafe(self.badger.opsMultisig)

        # Setup
        accounts[7].transfer(multi.get_first_owner(), Wei("2 ether"))
        print(
            "Supplied ETH",
            accounts.at(multi.get_first_owner(), force=True).balance(),
        )

        badger = self.badger
        tree = self.badger.badgerTree

        before = badger.token.balanceOf(tree)
        top_up = Wei("100000 ether")
        top_up_digg = Wei("40 gwei")
        harvest_badger = Wei("30000 ether")
        harvest_digg = Wei("40 gwei")

        # Top up Tree
        # TODO: Make the amount based on what we'll require for the next week
        id = multi.addTx(
            MultisigTxMetadata(description="Top up badger tree with Badger"),
            {
                "to":
                rewardsEscrow.address,
                "data":
                rewardsEscrow.transfer.encode_input(badger.token, tree,
                                                    top_up),
            },
        )

        tx = multi.executeTx(id)

        after = badger.token.balanceOf(tree)
        assert after == before + top_up

        before = badger.digg.token.balanceOf(tree)

        tx = multi.execute(
            MultisigTxMetadata(description="Top up badger tree with DIGG"),
            {
                "to":
                rewardsEscrow.address,
                "data":
                rewardsEscrow.transfer.encode_input(badger.digg.token, tree,
                                                    top_up_digg),
            },
        )

        print(tx.call_trace(), before, after)

        after = badger.digg.token.balanceOf(tree)
        assert after == before + top_up_digg

        # multi.execute(
        #     MultisigTxMetadata(description="Top up rewards manager with Badger"),
        #     {
        #         "to": rewardsEscrow.address,
        #         "data": rewardsEscrow.transfer.encode_input(
        #             badger.token, badger.badgerRewardsManager, harvest_badger
        #         ),
        #     },
        # )

        multi.execute(
            MultisigTxMetadata(description="Top up rewards manager with DIGG"),
            {
                "to":
                rewardsEscrow.address,
                "data":
                rewardsEscrow.transfer.encode_input(
                    badger.digg.token, badger.badgerRewardsManager,
                    harvest_digg),
            },
        )

        # grant_token_locking_permission(self.badger, self.badger.unlockScheduler)

        geyserDists = []

        for key, distribution in self.distributions.items():
            if distribution.hasGeyserDistribution() == True:
                print("has geyser distribution", key)
                dist = GeyserDistributor()

                dists = dist.generate(
                    badger,
                    multi,
                    key,
                    distributions=distribution.getGeyserDistributions(),
                    start=self.start,
                    duration=self.duration,
                    end=self.end,
                )

                geyserDists.extend(dists)
                console.log("after " + key, geyserDists)

        # Add unlock schedeules inbulk
        console.log(geyserDists)
        tx = opsMulti.execute(
            MultisigTxMetadata(description="Signal unlock schedules"),
            {
                "to":
                badger.unlockScheduler.address,
                "data":
                badger.unlockScheduler.signalTokenLocks.encode_input(
                    geyserDists),
            },
        )
        print(tx.call_trace())

        tokens = [self.badger.token.address, self.badger.digg.token.address]

        for key in geyser_keys:
            print(key)
            geyser = self.badger.getGeyser(key)
            for token in tokens:
                print(token)
                console.log(
                    "{} schedules for {}".format(token, key),
                    geyser.getUnlockSchedulesFor(token),
                )
Exemplo n.º 10
0
def swap_transfer(recipient, params):
    badger = connect_badger("deploy-final.json")

    badger.paymentsMultisig = connect_gnosis_safe(
        "0xD4868d98849a58F743787c77738D808376210292"
    )

    expectedMultisig = "0xB65cef03b9B89f99517643226d76e286ee999e77"
    assert badger.devMultisig == expectedMultisig
    multi = GnosisSafe(badger.paymentsMultisig)

    one_wei = Wei("1")

    end_token = interface.IERC20(params["path"][-1])

    console.print("Executing Swap:", style="yellow")
    console.print(params)

    # === Approve Uniswap Router on Rewards Escrow if not approved ===
    uniswap = UniswapSystem()

    # === Approve UNI Router for Badger ===

    # Note: The allowance must first be set to 0
    id = multi.addTx(
        MultisigTxMetadata(
            description="Approve UNI Router to send BADGER",
            operation="call",
        ),
        params={
            "to": badger.token.address,
            "data": badger.token.approve.encode_input(uniswap.router, 0),
        },
    )

    tx = multi.executeTx(id)

    # Set proper allowance
    id = multi.addTx(
        MultisigTxMetadata(
            description="Approve UNI Router to send BADGER",
            operation="call",
        ),
        params={
            "to": badger.token.address,
            "data": badger.token.approve.encode_input(
                uniswap.router, int(params["max_in"] * 1.5)
            ),
        },
    )

    tx = multi.executeTx(id)

    console.print(
        {
            "rewardsEscrowBalance": val(
                badger.token.balanceOf(badger.paymentsMultisig)
            ),
            "rewardsEscrowRouterAllowance": val(
                badger.token.allowance(badger.paymentsMultisig, uniswap.router)
            ),
            "max_in": val(params["max_in"]),
        }
    )

    assert badger.token.balanceOf(badger.paymentsMultisig) > params["max_in"]
    assert (
        badger.token.allowance(badger.paymentsMultisig, uniswap.router)
        >= params["max_in"]
    )

    # === Trade Badger ===
    before = end_token.balanceOf(badger.paymentsMultisig)
    beforeBadger = badger.token.balanceOf(badger.paymentsMultisig)

    console.print({"EAO": params["exact_amount_out"]})

    expiration = chain.time() + 8000

    id = multi.addTx(
        MultisigTxMetadata(
            description="Trade Badger for output token",
            operation="call",
            callInfo={},
        ),
        params={
            "to": uniswap.router.address,
            "data": uniswap.router.swapTokensForExactTokens.encode_input(
                params["exact_amount_out"],
                int(params["max_in"] * 1.5),
                params["path"],
                badger.paymentsMultisig,
                expiration,
            ),
        },
    )

    tx = multi.executeTx(id)
    print(tx.call_trace())
    print(tx.events)

    printUniTrade(
        method="swapTokensForExactTokens",
        params=(
            params["exact_amount_out"],
            int(params["max_in"] * 1.5),
            params["path"],
            badger.paymentsMultisig,
            expiration,
        ),
    )

    console.log("=== Post Trade ===")
    console.print(
        {
            "before_input_coin": val(beforeBadger),
            "after_input_coin": val(badger.token.balanceOf(badger.paymentsMultisig)),
            "change_input_coin": val(
                beforeBadger - badger.token.balanceOf(badger.paymentsMultisig)
            ),
            "before_output_coin": val(before, decimals=end_token.decimals()),
            "post_output_coin": val(
                end_token.balanceOf(badger.paymentsMultisig),
                decimals=end_token.decimals(),
            ),
            "end_token": end_token,
            "chain_time_before": chain.time(),
        }
    )

    assert end_token.balanceOf(badger.paymentsMultisig) >= params["exact_amount_out"]
    console.print("\n[green] ✅ Actions Complete [/green]")
Exemplo n.º 11
0
def transfer_badger(recipient, params):
    badger = connect_badger("deploy-final.json")

    expectedMultisig = "0xB65cef03b9B89f99517643226d76e286ee999e77"
    assert badger.devMultisig == expectedMultisig
    multi = GnosisSafe(badger.devMultisig)

    one_wei = Wei("1")
    end_token = badger.token

    # === Approve Recipient if not approved ===
    if not badger.rewardsEscrow.isApproved(recipient):
        id = multi.addTx(
            MultisigTxMetadata(
                description="Approve the transfer recipient",
                operation="approveRecipient",
                callInfo={},
            ),
            params={
                "to":
                badger.rewardsEscrow.address,
                "data":
                badger.rewardsEscrow.approveRecipient.encode_input(recipient),
            },
        )

        multi.executeTx(id)

    assert badger.rewardsEscrow.isApproved(recipient)

    # === Test Payment to recipient ===
    before = end_token.balanceOf(recipient)
    if params["use_test_payment"]:
        id = multi.addTx(
            MultisigTxMetadata(
                description="Test payment: {} badger to {}".format(
                    one_wei, recipient),
                operation="transfer",
                callInfo={
                    "to": recipient,
                    "amount": one_wei
                },
            ),
            params={
                "to":
                badger.rewardsEscrow.address,
                "data":
                badger.rewardsEscrow.transfer.encode_input(
                    end_token, recipient, one_wei),
            },
        )

        multi.executeTx(id)
        after = end_token.balanceOf(recipient)
        assert after == before + one_wei

    # === Full Payment to recipient ===
    rest = 0
    if params["use_test_payment"]:
        rest = params["amount"] - 1
    else:
        rest = params["amount"]

    before = end_token.balanceOf(recipient)

    id = multi.addTx(
        MultisigTxMetadata(
            description="Full payment, {} badger to {}".format(
                val(rest), recipient),
            operation="transfer",
            callInfo={
                "to": recipient,
                "amount": rest
            },
        ),
        params={
            "to":
            badger.rewardsEscrow.address,
            "data":
            badger.rewardsEscrow.transfer.encode_input(end_token, recipient,
                                                       rest),
        },
    )

    multi.executeTx(id)

    after = end_token.balanceOf(recipient)

    assert after == before + rest

    print(before, after, before + params["amount"])

    console.print("\n[green] ✅ Actions Complete [/green]")
    def testTransactions(self):
        rewardsEscrow = self.badger.rewardsEscrow
        multi = GnosisSafe(self.badger.devMultisig)

        # Setup
        accounts[7].transfer(multi.get_first_owner(), Wei("2 ether"))
        print(
            "Supplied ETH",
            accounts.at(multi.get_first_owner(), force=True).balance(),
        )

        badger = self.badger
        tree = self.badger.badgerTree

        before = badger.token.balanceOf(tree)
        top_up = Wei("200000 ether")

        # Top up Tree
        # TODO: Make the amount based on what we'll require for the next week
        id = multi.addTx(
            MultisigTxMetadata(
                description="Top up badger tree",
                operation="Top Up Badger Tree",
            ),
            {
                "to":
                rewardsEscrow.address,
                "data":
                rewardsEscrow.transfer.encode_input(badger.token, tree,
                                                    top_up),
            },
        )

        tx = multi.executeTx(id)

        after = badger.token.balanceOf(tree)
        assert after == before + top_up

        for key, distribution in self.distributions.items():
            console.print("===== Distributions for {} =====".format(key),
                          style="bold yellow")

            # == Distribute to Geyser ==
            geyser = self.badger.getGeyser(key)

            # Approve Geyser as recipient if required
            if not rewardsEscrow.isApproved(geyser):
                id = multi.addTx(
                    MultisigTxMetadata(
                        description="Approve StakingRewards " + key,
                        operation="transfer",
                    ),
                    {
                        "to":
                        rewardsEscrow.address,
                        "data":
                        rewardsEscrow.approveRecipient.encode_input(geyser),
                    },
                )

                multi.executeTx(id)

            numSchedules = geyser.unlockScheduleCount(self.badger.token)
            console.print(
                "Geyser Distribution for {}: {}".format(
                    key, val(distribution.toGeyser)),
                style="yellow",
            )

            id = multi.addTx(
                MultisigTxMetadata(
                    description="Signal unlock schedule for " + key,
                    operation="signalTokenLock",
                ),
                {
                    "to":
                    rewardsEscrow.address,
                    "data":
                    rewardsEscrow.signalTokenLock.encode_input(
                        geyser,
                        self.badger.token,
                        distribution.toGeyser,
                        self.duration,
                        self.start,
                    ),
                },
            )

            multi.executeTx(id)

            # Verify Results
            numSchedulesAfter = geyser.unlockScheduleCount(self.badger.token)

            console.print(
                "Schedule Addition",
                {
                    "numSchedules": numSchedules,
                    "numSchedulesAfter": numSchedulesAfter
                },
            )

            assert numSchedulesAfter == numSchedules + 1

            unlockSchedules = geyser.getUnlockSchedulesFor(self.badger.token)
            schedule = unlockSchedules[-1]
            print(schedule)
            assert schedule[0] == distribution.toGeyser
            assert schedule[1] == self.end
            assert schedule[2] == self.duration
            assert schedule[3] == self.start

            # == Distribute to StakingRewards, if relevant ==
            if distribution.toStakingRewards > 0:
                stakingRewards = self.badger.getSettRewards(key)
                console.print(
                    "Staking Rewards Distribution for {}: {}".format(
                        key, val(distribution.toStakingRewards)),
                    style="yellow",
                )

                # Approve if not approved
                if not rewardsEscrow.isApproved(stakingRewards):
                    id = multi.addTx(
                        MultisigTxMetadata(
                            description="Approve StakingRewards " + key,
                            operation="transfer",
                        ),
                        {
                            "to":
                            rewardsEscrow.address,
                            "data":
                            rewardsEscrow.approveRecipient.encode_input(
                                stakingRewards),
                        },
                    )

                    multi.executeTx(id)

                    assert rewardsEscrow.isApproved(stakingRewards) == True

                # Add tokens if insufficent tokens
                preBal = self.badger.token.balanceOf(stakingRewards)
                if preBal < distribution.toStakingRewards:
                    required = distribution.toStakingRewards - preBal
                    console.print(
                        "� We need to add {} to the {} Badger supply of {} to reach the goal of {} Badger"
                        .format(
                            val(required),
                            key,
                            val(preBal),
                            val(distribution.toStakingRewards),
                        ),
                        style="blue",
                    )

                    id = multi.addTx(
                        MultisigTxMetadata(
                            description="Top up tokens for staking rewards " +
                            key,
                            operation="transfer",
                        ),
                        {
                            "to":
                            rewardsEscrow.address,
                            "data":
                            rewardsEscrow.transfer.encode_input(
                                self.badger.token, stakingRewards, required),
                        },
                    )

                    multi.executeTx(id)

                assert (self.badger.token.balanceOf(stakingRewards) >=
                        distribution.toStakingRewards)

                # Modify the rewards duration, if necessary
                if stakingRewards.rewardsDuration() != self.duration:
                    id = multi.addTx(
                        MultisigTxMetadata(
                            description="Modify Staking Rewards duration for "
                            + key,
                            operation="call.notifyRewardAmount",
                        ),
                        {
                            "to":
                            stakingRewards.address,
                            "data":
                            stakingRewards.setRewardsDuration.encode_input(
                                self.duration),
                        },
                    )
                    tx = multi.executeTx(id)

                # assert stakingRewards.rewardsDuration() == self.duration

                # Notify Rewards Amount
                id = multi.addTx(
                    MultisigTxMetadata(
                        description="Distribute Staking Rewards For " + key,
                        operation="call.notifyRewardAmount",
                    ),
                    {
                        "to":
                        stakingRewards.address,
                        "data":
                        stakingRewards.notifyRewardAmount.encode_input(
                            self.start,
                            distribution.toStakingRewards,
                        ),
                    },
                )

                tx = multi.executeTx(id)
                console.print(tx.call_trace())
                console.print("notify rewards events", tx.events)

                # Verify Results

                rewardsDuration = stakingRewards.rewardsDuration()
                rewardRate = stakingRewards.rewardRate()
                periodFinish = stakingRewards.periodFinish()
                lastUpdate = stakingRewards.lastUpdateTime()

                oldRewardsRate = Wei("50000 ether") // rewardsDuration

                console.log({
                    "start":
                    to_utc_date(self.start),
                    "end":
                    to_utc_date(self.end),
                    "finish":
                    to_utc_date(periodFinish),
                    "rewardRate":
                    rewardRate,
                    "expectedRewardRate":
                    distribution.toStakingRewards // rewardsDuration,
                    "rewardsRateDiff":
                    rewardRate -
                    distribution.toStakingRewards // rewardsDuration,
                    "oldRewardsRate":
                    oldRewardsRate,
                    "howTheRateChanged":
                    (distribution.toStakingRewards // rewardsDuration) /
                    oldRewardsRate,
                    "howWeExpectedItToChange":
                    Wei("35000 ether") / Wei("50000 ether"),
                    "lastUpdate":
                    to_utc_date(lastUpdate),
                })

                assert lastUpdate == self.start
                assert rewardsDuration == self.duration
                assert rewardRate == distribution.toStakingRewards // rewardsDuration
                assert periodFinish == self.start + self.duration

                bal = self.badger.token.balanceOf(stakingRewards)
                assert bal >= distribution.toStakingRewards

                if bal > distribution.toStakingRewards * 2:
                    console.print(
                        "[red] Warning: Staking rewards for {} has excessive coins [/red]"
                        .format(key))

                # Harvest the rewards and ensure the amount updated is appropriate
                strategy = self.badger.getStrategy(key)
                keeper = accounts.at(strategy.keeper(), force=True)

                before = strategy.balance()
                chain.sleep(self.start - chain.time() + 2)
                strategy.harvest({"from": keeper})
                after = strategy.balance()

                print({"before": before, "after": after})
Exemplo n.º 13
0
def init_prod_digg(badger: BadgerSystem, user):
    deployer = badger.deployer

    digg = badger.digg

    multi = GnosisSafe(badger.devMultisig)

    digg_liquidity_amount = 1000000000
    wbtc_liquidity_amount = 100000000

    print("TOKEN_LOCKER_ROLE", TOKEN_LOCKER_ROLE)
    locker_role = "0x4bf6f2cdcc8ad6c087a7a4fbecf46150b3686b71387234cac2b3e2e6dc70e345"

    # TODO: Have this as proxy in real deploy
    seederLogic = DiggSeeder.deploy({"from": deployer})

    seeder = deploy_proxy(
        "DiggSeeder",
        DiggSeeder.abi,
        seederLogic.address,
        badger.devProxyAdmin.address,
        seederLogic.initialize.encode_input(digg.diggDistributor),
        deployer,
    )

    # # Take initial liquidity from DAO
    # aragon = AragonSystem()
    # voting = aragon.getVotingAt("0xdc344bfb12522bf3fa58ef0d6b9a41256fc79a1b")

    # PROD: Configure DIGG
    digg.uFragmentsPolicy.setCpiOracle(
        digg.cpiMedianOracle,
        {"from": deployer},
    )
    digg.uFragmentsPolicy.setMarketOracle(
        digg.marketMedianOracle,
        {"from": deployer},
    )
    digg.uFragmentsPolicy.setOrchestrator(
        digg.orchestrator,
        {"from": deployer},
    )
    digg.uFragments.setMonetaryPolicy(
        digg.uFragmentsPolicy,
        {"from": deployer},
    )

    # ===== Upgrade DAOTimelock to allow voting =====
    # print(badger.logic.SimpleTimelockWithVoting.address)
    # timelockWithVotingLogic = SimpleTimelockWithVoting.at(badger.logic.SimpleTimelockWithVoting.address)
    # timelock = interface.ISimpleTimelockWithVoting(badger.daoBadgerTimelock.address)

    # multi.execute(
    #     MultisigTxMetadata(description="Upgrade DAO Badger Timelock to Allow voting",),
    #     {
    #         "to": badger.devProxyAdmin.address,
    #         "data": badger.devProxyAdmin.upgrade.encode_input(
    #             badger.daoBadgerTimelock, timelockWithVotingLogic
    #         ),
    #     },
    # )

    # # ===== Vote to move initial liquidity funds to multisig  =====
    # tx = multi.execute(
    #     MultisigTxMetadata(description="Vote on DAO Timelock from multisig",),
    #     {
    #         "to": timelock.address,
    #         "data": timelock.vote.encode_input(0, True, True)
    #     },
    # )

    # # Approve DAO voting as recipient
    # multi.execute(
    #     MultisigTxMetadata(description="Approve DAO voting as recipient",),
    #     {
    #         "to": badger.rewardsEscrow.address,
    #         "data": badger.rewardsEscrow.approveRecipient.encode_input(voting),
    #     },
    # )

    # # Vote on DAO voting as rewardsEscrow

    # before = badger.token.balanceOf(badger.rewardsEscrow)

    # tx = multi.execute(
    #     MultisigTxMetadata(description="Vote on Rewards Escrow from multisig",),
    #     {
    #         "to": badger.rewardsEscrow.address,
    #         "data": badger.rewardsEscrow.call.encode_input(
    #             voting, 0, voting.vote.encode_input(0, True, True)
    #         ),
    #     },
    # )

    # after = badger.token.balanceOf(badger.rewardsEscrow)

    # print(tx.call_trace())

    # assert after == before

    # crvRen = interface.IERC20(registry.curve.pools.renCrv.token)
    wbtc = interface.IERC20(registry.tokens.wbtc)
    # assert crvRen.balanceOf(badger.devMultisig) >= wbtc_liquidity_amount * 10 ** 10 * 2

    # crvPool = interface.ICurveZap(registry.curve.pools.renCrv.swap)

    # # crvPool.Remove_liquidity_one_coin(
    # #     wbtc_liquidity_amount * 10 ** 10, 1, wbtc_liquidity_amount
    # # )

    # # ===== Convert crvRen to wBTC on multisig =====
    # tx = multi.execute(
    #     MultisigTxMetadata(description="Withdraw crvRen for 100% WBTC",),
    #     {
    #         "to": crvPool.address,
    #         "data": crvPool.remove_liquidity_one_coin.encode_input(
    #             wbtc_liquidity_amount * 10 ** 10 * 2, 1, wbtc_liquidity_amount * 2
    #         ),
    #     },
    # )

    # assert wbtc.balanceOf(badger.devMultisig) >= wbtc_liquidity_amount * 2

    # ===== Move initial liquidity funds to Seeder =====
    multi.execute(
        MultisigTxMetadata(
            description="Transfer initial liquidity WBTC to the Seeder", ),
        {
            "to": wbtc.address,
            "data": wbtc.transfer.encode_input(seeder, 200000000),
        },
    )

    # ===== Move DIGG to Seeder =====
    digg.token.transfer(seeder, digg.token.totalSupply(), {"from": deployer})

    # ===== Move Required Badger to Seeder from RewardsEscrow =====
    multi.execute(
        MultisigTxMetadata(
            description="Move Required Badger to Seeder from RewardsEscrow", ),
        {
            "to":
            badger.rewardsEscrow.address,
            "data":
            badger.rewardsEscrow.transfer.encode_input(badger.token, seeder,
                                                       Wei("30000 ether")),
        },
    )

    # ===== Add DIGG token to all geyser distribution lists =====
    # (Also, add Seeder as approved schedule creator)
    geyser_keys = [
        "native.badger",
        "native.renCrv",
        "native.sbtcCrv",
        "native.tbtcCrv",
        "native.uniBadgerWbtc",
        "harvest.renCrv",
        "native.sushiWbtcEth",
        "native.sushiBadgerWbtc",
        "native.uniDiggWbtc",
        "native.sushiDiggWbtc",
    ]

    for key in geyser_keys:
        geyser = badger.getGeyser(key)
        print(key, geyser)
        id = multi.addTx(
            MultisigTxMetadata(
                description="Add DIGG token to distribution tokens on {} geyser"
                .format(key), ),
            {
                "to": geyser.address,
                "data": geyser.addDistributionToken.encode_input(digg.token),
            },
        )

        tx = multi.executeTx(id)

        assert geyser.hasRole(DEFAULT_ADMIN_ROLE, badger.devMultisig)

        multi.execute(
            MultisigTxMetadata(
                description="Allow Seeder to set unlock schedules on {} geyser"
                .format(key), ),
            {
                "to": geyser.address,
                "data": geyser.grantRole.encode_input(locker_role, seeder),
            },
        )

        assert geyser.hasRole(locker_role, seeder)

    # Seeder needs to have admin role to config Faucets. Remove role as part of seed.
    rewards_keys = [
        "native.digg",
        "native.uniDiggWbtc",
        "native.sushiDiggWbtc",
    ]

    for key in rewards_keys:
        rewards = badger.getSettRewards(key)
        rewards.grantRole(DEFAULT_ADMIN_ROLE, seeder, {"from": deployer})
        rewards.grantRole(DEFAULT_ADMIN_ROLE, badger.devMultisig,
                          {"from": deployer})
        rewards.renounceRole(DEFAULT_ADMIN_ROLE, deployer, {"from": deployer})

    # print(digg.token.balanceOf(deployer))
    # assert digg.token.balanceOf(deployer) == digg.token.totalSupply()
    # digg.token.transfer(seeder, digg.token.totalSupply(), {"from": deployer})
    # wbtc = interface.IERC20(token_registry.wbtc)
    # wbtc.transfer(seeder, 200000000, {"from": user})

    # ===== Seed Prep =====

    print("wbtc.balanceOf(seeder)", wbtc.balanceOf(seeder))
    assert digg.token.balanceOf(seeder) >= digg.token.totalSupply()
    assert wbtc.balanceOf(seeder) >= 200000000

    print(digg.diggDistributor.address)
    print("digg.diggDistributor", digg.diggDistributor.isOpen())
    digg.diggDistributor.transferOwnership(seeder, {"from": deployer})

    print("prePreSeed", digg.token.balanceOf(seeder))

    seeder.preSeed({"from": deployer})

    print("postPreSeed", digg.token.balanceOf(seeder))

    seeder.seed({"from": deployer})

    # seeder.transferOwnership(badger.devMultisig, {'from': deployer})

    # tx = multi.execute(
    #     MultisigTxMetadata(description="Withdraw crvRen for 100% WBTC",),
    #     {
    #         "to": seeder.address,
    #         "data": seeder.preSeed.encode_input(),
    #     },
    # )

    # seeder.initialize({"from": deployer})

    # Unpause all Setts
    setts_to_unpause = [
        "native.digg",
        "native.uniDiggWbtc",
        "native.sushiDiggWbtc",
    ]

    for key in setts_to_unpause:
        sett = badger.getSett(key)

        id = multi.addTx(
            MultisigTxMetadata(description="Unpause Sett {}".format(key), ),
            {
                "to": sett.address,
                "data": sett.unpause.encode_input(),
            },
        )

        tx = multi.executeTx(id)
        assert sett.paused() == False
    def __init__(self,
                 badger,
                 multi,
                 key,
                 distributions,
                 start=0,
                 duration=0,
                 end=0):
        # == Distribute to Geyser ==
        geyser = badger.getGeyser(key)
        rewardsEscrow = badger.rewardsEscrow

        self.start = start
        self.duration = duration
        self.end = end

        multi = GnosisSafe(badger.devMultisig)
        for asset, dist in distributions.items():
            token = asset_to_address(asset)
            self.validate_staking_rewards_emission(key, asset)

            stakingRewards = badger.getSettRewards(key)
            console.print(
                "Staking Rewards Distribution for asset {} on {}: {}".format(
                    asset, key, val(dist)),
                style="yellow",
            )

            # Approve if not approved
            if not rewardsEscrow.isApproved(stakingRewards):
                id = multi.addTx(
                    MultisigTxMetadata(
                        description="Approve StakingRewards " + key,
                        operation="transfer",
                    ),
                    {
                        "to":
                        rewardsEscrow.address,
                        "data":
                        rewardsEscrow.approveRecipient.encode_input(
                            stakingRewards),
                    },
                )

                multi.executeTx(id)

                assert rewardsEscrow.isApproved(stakingRewards) == True

            # Add tokens if insufficent tokens
            preBal = badger.token.balanceOf(stakingRewards)
            print("PreBalance", val(preBal))

            if preBal < dist:
                required = dist - preBal
                console.print(
                    "⊁ We need to add {} to the {} Badger supply of {} to reach the goal of {} Badger"
                    .format(
                        val(required),
                        key,
                        val(preBal),
                        val(dist),
                    ),
                    style="blue",
                )

                id = multi.addTx(
                    MultisigTxMetadata(
                        description="Top up tokens for staking rewards " + key,
                        operation="transfer",
                    ),
                    {
                        "to":
                        rewardsEscrow.address,
                        "data":
                        rewardsEscrow.transfer.encode_input(
                            badger.token, stakingRewards, required),
                    },
                )

                multi.executeTx(id)

            assert badger.token.balanceOf(stakingRewards) >= dist

            # Modify the rewards duration, if necessary
            if stakingRewards.rewardsDuration() != self.duration:
                id = multi.addTx(
                    MultisigTxMetadata(
                        description="Modify Staking Rewards duration for " +
                        key,
                        operation="call.notifyRewardAmount",
                    ),
                    {
                        "to":
                        stakingRewards.address,
                        "data":
                        stakingRewards.setRewardsDuration.encode_input(
                            self.duration),
                    },
                )
                tx = multi.executeTx(id)

            # assert stakingRewards.rewardsDuration() == self.duration

            # Notify Rewards Amount
            id = multi.addTx(
                MultisigTxMetadata(
                    description="Distribute Staking Rewards For " + key,
                    operation="call.notifyRewardAmount",
                ),
                {
                    "to":
                    stakingRewards.address,
                    "data":
                    stakingRewards.notifyRewardAmount.encode_input(
                        self.start,
                        dist,
                    ),
                },
            )

            tx = multi.executeTx(id)
            console.print(tx.call_trace())
            console.print("notify rewards events", tx.events)

            # Verify Results

            rewardsDuration = stakingRewards.rewardsDuration()
            rewardRate = stakingRewards.rewardRate()
            periodFinish = stakingRewards.periodFinish()
            lastUpdate = stakingRewards.lastUpdateTime()

            oldRewardsRate = Wei("50000 ether") // rewardsDuration

            console.log({
                "start":
                to_utc_date(self.start),
                "end":
                to_utc_date(self.end),
                "finish":
                to_utc_date(periodFinish),
                "rewardRate":
                rewardRate,
                "expectedRewardRate":
                dist // rewardsDuration,
                "rewardsRateDiff":
                rewardRate - dist // rewardsDuration,
                "oldRewardsRate":
                oldRewardsRate,
                "howTheRateChanged":
                (dist // rewardsDuration) / oldRewardsRate,
                "howWeExpectedItToChange":
                Wei("35000 ether") / Wei("50000 ether"),
                "lastUpdate":
                to_utc_date(lastUpdate),
            })

            assert lastUpdate == self.start
            assert rewardsDuration == self.duration
            assert rewardRate == dist // rewardsDuration
            assert periodFinish == self.start + self.duration

            bal = badger.token.balanceOf(stakingRewards)
            assert bal >= dist

            if bal > dist * 2:
                console.print(
                    "[red] Warning: Staking rewards for {} has excessive coins [/red]"
                    .format(key))

            # Harvest the rewards and ensure the amount updated is appropriate
            strategy = badger.getStrategy(key)
            keeper = accounts.at(strategy.keeper(), force=True)

            before = strategy.balance()
            chain.sleep(self.start - chain.time() + 2)
            strategy.harvest({"from": keeper})
            after = strategy.balance()

            print({"before": before, "after": after})