示例#1
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),
                )
    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})