Beispiel #1
0
def rebase(badger: BadgerSystem, account):
    digg = badger.digg
    supplyBefore = digg.token.totalSupply()

    print("spfBefore", digg.token._sharesPerFragment())
    print("supplyBefore", digg.token.totalSupply())

    print(digg.cpiMedianOracle.getData.call())

    sushi = SushiswapSystem()
    pair = sushi.getPair(digg.token, registry.tokens.wbtc)

    uni = UniswapSystem()
    uniPair = uni.getPair(digg.token, registry.tokens.wbtc)

    last_rebase_time = digg.uFragmentsPolicy.lastRebaseTimestampSec()
    min_rebase_time = digg.uFragmentsPolicy.minRebaseTimeIntervalSec()
    in_rebase_window = digg.uFragmentsPolicy.inRebaseWindow()
    now = chain.time()

    time_since_last_rebase = now - last_rebase_time
    min_time_passed = (last_rebase_time + min_rebase_time) < now

    console.print({
        "last_rebase_time": last_rebase_time,
        "in_rebase_window": in_rebase_window,
        "now": now,
        "time_since_last_rebase": time_since_last_rebase,
        "min_time_passed": min_time_passed,
    })

    # Rebase if sufficient time has passed since last rebase and we are in the window.
    # Give adequate time between TX attempts
    if time_since_last_rebase > hours(
            2) and in_rebase_window and min_time_passed:
        console.print(
            "[bold yellow]===== 📈 Rebase! 📉=====[/bold yellow]")
        print("pair before", pair.getReserves())
        print("uniPair before", uniPair.getReserves())

        tx_timer.start_timer(account, "Rebase")
        tx = digg.orchestrator.rebase({"from": account})
        tx_timer.end_timer()

        if rpc.is_active():
            chain.mine()
            print(tx.call_trace())
            print(tx.events)

        supplyAfter = digg.token.totalSupply()

        print("spfAfter", digg.token._sharesPerFragment())
        print("supplyAfter", supplyAfter)
        print("supplyChange", supplyAfter / supplyBefore)
        print("supplyChangeOtherWay", supplyBefore / supplyAfter)

        print("pair after", pair.getReserves())
        print("uniPair after", uniPair.getReserves())
    else:
        console.print("[white]===== No Rebase =====[/white]")
Beispiel #2
0
    def fetch_params(self):
        params = sett_config.uni.uniDiggWbtc.params

        uniswap = UniswapSystem()
        # TODO: Pull digg token addr from registry once its deployed.
        if uniswap.hasPair(self.digg.token, registry.tokens.wbtc):
            params.want = uniswap.getPair(self.digg.token,
                                          registry.tokens.wbtc)
        else:
            params.want = uniswap.createPair(
                self.digg.token,
                registry.tokens.wbtc,
                self.deployer,
            )
        want = params.want
        params.token = self.digg.token

        self.badger.deploy_logic("DiggRewardsFaucet",
                                 DiggRewardsFaucet,
                                 test=True)
        self.rewards = self.badger.deploy_digg_rewards_faucet(
            self.key, self.digg.token)

        params.geyser = self.rewards

        return (params, want)
Beispiel #3
0
def main():

    badger = connect_badger("deploy-final.json")

    deployer = badger.deployer
    controller = badger.getController("native")
    governance = badger.devMultisig
    strategist = badger.deployer
    keeper = badger.keeper
    guardian = badger.guardian

    for (key, strategyName, isUniswap) in [
        ("native.sushiWbtcIbBtc", "StrategySushiLpOptimizer", False),
        # ("native.uniWbtcIbBtc", "StrategyUniGenericLp", True),
    ]:
        if isUniswap:
            params = sett_config.uni.uniGenericLp.params
            swap = UniswapSystem()
        else:
            params = sett_config.sushi.sushiWbtcIbBtc.params
            params.badgerTree = badger.badgerTree

            swap = SushiswapSystem()

        if swap.hasPair(registry.tokens.ibbtc, registry.tokens.wbtc):
            params.want = swap.getPair(registry.tokens.ibbtc, registry.tokens.wbtc)
        else:
            params.want = swap.createPair(
                registry.tokens.ibbtc, registry.tokens.wbtc, deployer,
            )

        # NB: Work w/ sushi team to setup sushi reward allocations.

        vault = badger.deploy_sett(
            key,
            params.want,
            controller,
            governance=governance,
            strategist=strategist,
            keeper=keeper,
            guardian=guardian,
        )
        time.sleep(sleep_between_tx)

        strategy = badger.deploy_strategy(
            key,
            strategyName,
            controller,
            params,
            governance=governance,
            strategist=strategist,
            keeper=keeper,
            guardian=guardian,
        )
        time.sleep(sleep_between_tx)

        badger.wire_up_sett(vault, strategy, controller)

        # TODO: Unpause vault.
        assert vault.paused()
Beispiel #4
0
    def pre_deploy_setup(self):
        """
        Deploy StakingRewards for Strategy
        """
        uniswap = UniswapSystem()
        want = uniswap.getPair(self.badger.token, registry.tokens.wbtc)

        self.rewards = self.badger.deploy_sett_staking_rewards(
            self.key, want, self.badger.token)
Beispiel #5
0
    def fetch_params(self):
        params = sett_config.uni.uniGenericLp.params

        uniswap = UniswapSystem()
        want = uniswap.getPair(*self.tokens)

        params.want = want

        return (params, want)
Beispiel #6
0
    def fetch_params(self):
        params = sett_config.native.uniBadgerWbtc.params

        uniswap = UniswapSystem()
        want = uniswap.getPair(self.badger.token, registry.tokens.wbtc)

        params.want = want

        params.geyser = self.rewards

        return (params, want)
Beispiel #7
0
def deploy_uni_digg_wbtc_lp_sett(badger, digg):
    """
    If test mode, add initial liquidity and distribute to test user
    """
    deployer = badger.deployer
    key = "native.uniDiggWbtc"
    params = sett_config.uni.uniDiggWbtc.params
    uniswap = UniswapSystem()
    params.want = uniswap.getPair(digg.token, registry.tokens.wbtc)
    params.token = digg.token

    rewards = badger.deploy_digg_rewards_faucet(key, digg.token)
    params.geyser = rewards

    time.sleep(sleep_between_tx)

    deploy_sett_by_key(
        badger,
        key,
        "StrategyDiggLpMetaFarm",
        SettType.DEFAULT,
        params,
        deployer=deployer,
        governance=badger.devMultisig,
        strategist=badger.deployer,
        keeper=badger.keeper,
        guardian=badger.guardian,
    )
    # assert False

    strategy = badger.getStrategy(key)

    rewards.grantRole(PAUSER_ROLE, badger.keeper, {"from": deployer})
    rewards.grantRole(UNPAUSER_ROLE, badger.devMultisig, {"from": deployer})

    # Make strategy the recipient of the DIGG faucet
    rewards.initializeRecipient(strategy, {"from": deployer})
class DiggSystem:
    def __init__(self,
                 config,
                 deployer,
                 devProxyAdmin,
                 daoProxyAdmin,
                 owner=None):
        self.config = config
        self.contracts_static = []
        self.contracts_upgradeable = {}
        # These contracts adhere to the Ownable iface and belong to the
        # owner of the digg system (in prod it's the DAO). Note that this
        # is ONLY tracked on deploy as we will not modify ownership when
        # connecting to an existing system.
        self.contracts_ownable = []
        # Token is set when digg token (UFragments) is deployed.
        self.token = None

        self.logic = DotMap()
        # Store uniswap trading pairs addresses.
        # Expected key syntax is `tokenA_tokenB`.
        self.uniswap_trading_pair_addrs = DotMap()

        if rpc.is_active():
            print("RPC Active")
            self.owner = accounts.at(owner, force=True)
        else:
            print("RPC Inactive")
            # owner_key = decouple.config("DIGG_OWNER_PRIVATE_KEY")
            # self.owner = accounts.add(owner_key)

        if deployer == None:
            console.print(
                "[yellow]No deployer specified, using Owner[/yellow]")
            self.deployer = self.owner
        else:
            self.deployer = deployer
        if env_config.debug:
            print("deployer / owner", deployer, owner, self.deployer,
                  self.owner)
        #        self.owner=""
        #        self.deployer=self.owner

        self.connect_proxy_admins(devProxyAdmin, daoProxyAdmin)
        self.connect_dao()
        self.connect_multisig()

    def track_contract_static(self, contract):
        self.contracts_static.append(contract)

    def track_contract_upgradeable(self, key, contract):
        self.contracts_upgradeable[key] = contract

    def track_contract_ownable(self, contract):
        self.contracts_ownable.append(contract)

    # ===== Contract Connectors =====
    def connect_proxy_admins(self, devProxyAdmin, daoProxyAdmin):
        abi = artifacts.open_zeppelin["ProxyAdmin"]["abi"]

        self.devProxyAdmin = Contract.from_abi(
            "ProxyAdmin",
            web3.toChecksumAddress(devProxyAdmin),
            abi,
        )
        self.daoProxyAdmin = Contract.from_abi(
            "ProxyAdmin",
            web3.toChecksumAddress(daoProxyAdmin),
            abi,
        )

    def connect_centralized_oracle(self, address):
        self.centralizedOracle = connect_gnosis_safe(address)

    def connect_dao(self):
        deployer = self.deployer
        self.dao = DotMap(agent=Contract.from_abi(
            "Agent",
            badger_config.dao.agent,
            artifacts.aragon.Agent["abi"],
            deployer,
        ), )

    def connect_multisig(self):
        deployer = self.deployer

        if env_config.debug:
            print("Deploy Dev Multisig")
        self.devMultisig = connect_gnosis_safe(badger_config.multisig.address)

    def connect_uniswap_system(self):
        self.uniswap_system = UniswapSystem()

    def connect_uniswap_pair(self, pair_name, tokenA_addr, tokenB_addr):
        self.uniswap_trading_pair_addrs[
            pair_name] = self.uniswap_system.getPair(tokenA_addr, tokenB_addr)

    def connect(self, attr, BrownieArtifact, address, upgradeable=True):
        contract = BrownieArtifact.at(address)
        setattr(self, attr, contract)

        if upgradeable:
            self.track_contract_upgradeable(attr, contract)
        else:
            self.track_contract_static(contract)

    def connect_logic(self, logic):
        for name, address in logic.items():
            if env_config.debug:
                print("ConnectLogic:", name, address)
            Artifact = contract_name_to_artifact(name)
            self.logic[name] = Artifact.at(address)

    # ===== Deployers =====

    def deploy_core_logic(self):
        deployer = self.deployer
        self.logic = DotMap(
            # UFragments=UFragments.deploy({"from": deployer}),
            UFragments=UFragments.at(
                "0xfabec03b04279c6e73f27aaf25866acc844448ae"),
            UFragmentsPolicy=UFragmentsPolicy.at(
                "0x4750caa4999404cb26ff6db2d0abc09b000122e0"),
            # Timelock & Vesting: Use logic from existing badger deploy
            SimpleTimelock=SimpleTimelock.at(
                "0x4e3f56bb996ed91ba8d97ea773d3f818730d1a6f"),
            SmartVesting=SmartVesting.at(
                "0x07c0E4f4C977a29c46Fb26597ea8C9105ca50b42"),
            # DiggDistributor=DiggDistributor.deploy({"from": deployer}, publish_source=True),
        )

    def deploy_orchestrator(self):
        deployer = self.deployer
        self.orchestrator = Orchestrator.deploy(self.uFragmentsPolicy,
                                                {"from": deployer})
        self.track_contract_static(self.orchestrator)
        self.track_contract_ownable(self.orchestrator)

    def deploy_digg_policy(self):
        deployer = self.deployer
        self.uFragmentsPolicy = deploy_proxy(
            "UFragmentsPolicy",
            UFragmentsPolicy.abi,
            self.logic.UFragmentsPolicy.address,
            self.devProxyAdmin.address,
            self.logic.UFragmentsPolicy.initialize.encode_input(
                self.owner,
                self.uFragments,
                self.config.baseCpi,
            ),
            deployer,
        )
        config = self.config

        # TODO: F/u on why these values are not being set.
        self.uFragmentsPolicy.setDeviationThreshold(config.deviationThreshold,
                                                    {"from": deployer})
        self.uFragmentsPolicy.setRebaseLag(config.rebaseLag,
                                           {"from": deployer})
        self.uFragmentsPolicy.setRebaseTimingParameters(
            config.minRebaseTimeIntervalSec,
            config.rebaseWindowOffsetSec,
            config.rebaseWindowLengthSec,
            {"from": deployer},
        )

        self.track_contract_upgradeable("uFragmentsPolicy",
                                        self.uFragmentsPolicy)
        self.track_contract_ownable(self.uFragmentsPolicy)

    def deploy_digg_token(self):
        deployer = self.owner
        self.uFragments = deploy_proxy(
            "UFragments",
            UFragments.abi,
            self.logic.UFragments.address,
            self.devProxyAdmin.address,
            self.logic.UFragments.initialize.encode_input(self.owner, ),
            deployer,
        )
        self.track_contract_upgradeable("uFragments", self.uFragments)
        self.track_contract_ownable(self.uFragments)

        # Set the digg system token after deploying.
        # TODO: Move this to a better place.
        self.token = self.uFragments

    def deploy_constant_oracle(self):
        deployer = self.deployer
        self.constantOracle = ConstantOracle.deploy(
            self.cpiMedianOracle,
            {"from": deployer},
        )
        # self.constantOracle = ConstantOracle.deploy(
        #     self.cpiMedianOracle, {"from": deployer}, publish_source=True,
        # )
        self.track_contract_static(self.constantOracle)

    def deploy_cpi_median_oracle(self):
        deployer = self.deployer
        print("deploy_cpi_median_oracle", deployer)
        self.cpiMedianOracle = MedianOracle.deploy(
            self.config.cpiOracleParams.reportExpirationTimeSec,
            self.config.cpiOracleParams.reportDelaySec,
            self.config.cpiOracleParams.minimumProviders,
            {"from": deployer},
        )
        self.track_contract_static(self.cpiMedianOracle)
        self.track_contract_ownable(self.cpiMedianOracle)

    def deploy_market_median_oracle(self):
        deployer = self.deployer
        self.marketMedianOracle = MedianOracle.deploy(
            self.config.marketOracleParams.reportExpirationTimeSec,
            self.config.marketOracleParams.reportDelaySec,
            self.config.marketOracleParams.minimumProviders,
            {"from": deployer},
        )
        self.track_contract_static(self.marketMedianOracle)
        self.track_contract_ownable(self.marketMedianOracle)

    def deploy_dao_digg_timelock(self):
        deployer = self.deployer
        print(
            self.token,
            self.dao.agent,
            self.config.startTime + self.config.tokenLockParams.lockDuration,
            chain.time(),
        )
        self.daoDiggTimelock = deploy_proxy(
            "SimpleTimelock",
            SimpleTimelock.abi,
            self.logic.SimpleTimelock.address,
            self.devProxyAdmin.address,
            self.logic.SimpleTimelock.initialize.encode_input(
                self.token,
                self.dao.agent,
                self.config.startTime +
                self.config.tokenLockParams.lockDuration,
            ),
            deployer,
        )
        self.track_contract_upgradeable("daoDiggTimelock",
                                        self.daoDiggTimelock)

    def deploy_digg_team_vesting(self):
        deployer = self.deployer

        print(
            self.token,
            self.devMultisig,
            self.dao.agent,
            self.config.startTime,
            self.config.teamVestingParams.cliffDuration,
            self.config.teamVestingParams.totalDuration,
            chain.time(),
        )

        self.diggTeamVesting = deploy_proxy(
            "SmartVesting",
            SmartVesting.abi,
            self.logic.SmartVesting.address,
            self.devProxyAdmin.address,
            self.logic.SmartVesting.initialize.encode_input(
                self.token,
                self.devMultisig,
                self.dao.agent,
                self.config.startTime,
                self.config.teamVestingParams.cliffDuration,
                self.config.teamVestingParams.totalDuration,
            ),
            deployer,
        )
        self.track_contract_upgradeable("teamVesting", self.diggTeamVesting)

    def deploy_airdrop_distributor(self, root, rewardsEscrow,
                                   reclaimAllowedTimestamp):
        deployer = self.deployer

        self.diggDistributor = deploy_proxy(
            "DiggDistributor",
            DiggDistributor.abi,
            self.logic.DiggDistributor.address,
            self.devProxyAdmin.address,
            self.logic.DiggDistributor.initialize.encode_input(
                self.token, root, rewardsEscrow, reclaimAllowedTimestamp),
            deployer,
        )

        self.track_contract_upgradeable("diggDistributor",
                                        self.diggDistributor)

    def deploy_airdrop_distributor_no_initialize(self):
        deployer = self.deployer

        self.diggDistributor = deploy_proxy_uninitialized(
            "DiggDistributor",
            DiggDistributor.abi,
            self.logic.DiggDistributor.address,
            self.devProxyAdmin.address,
            deployer,
        )

        self.track_contract_upgradeable("diggDistributor",
                                        self.diggDistributor)

    def deploy_uniswap_pairs(self, test=False):
        # TODO: read these from config, hard configured for now. (Not set on init because token is lazily populated)
        pairs = [("digg_wbtc", self.token.address, registry.tokens.wbtc)]
        for (pair_name, tokenA_addr, tokenB_addr) in pairs:
            self._deploy_uniswap_pair_idempotent(pair_name,
                                                 tokenA_addr,
                                                 tokenB_addr,
                                                 test=test)

    def _deploy_uniswap_pair_idempotent(self,
                                        pair_name,
                                        tokenA_addr,
                                        tokenB_addr,
                                        test=False):
        deployer = self.deployer

        # Deploy digg/wBTC pair if not already deployed.
        if not self.uniswap_system.hasPair(tokenA_addr, tokenB_addr):
            self.uniswap_system.createPair(tokenA_addr, tokenB_addr, deployer)
        self.uniswap_trading_pair_addrs[
            pair_name] = self.uniswap_system.getPair(tokenA_addr, tokenB_addr)

        # In test mode, add liquidity to uniswap.
        if test:
            self.uniswap_system.addMaxLiquidity(tokenA_addr, tokenB_addr,
                                                deployer)

    # ===== Administrative functions =====

    # Used on DEPLOY ONLY,  ownership of ownable contracts to a new owner.
    def transfer_ownership(self, owner):
        prevOwner = self.owner
        self.owner = owner
        for contract in self.contracts_ownable:
            contract.transferOwnership(owner, {"from": prevOwner})

    # ===== Deploy for TESTING ONLY =====

    # requires the market median oracle to be deployed as this feeds it data
    def deploy_dynamic_oracle(self):
        deployer = self.deployer
        self.dynamicOracle = DynamicOracle.deploy(
            self.marketMedianOracle,
            {"from": deployer},
        )
        self.track_contract_static(self.dynamicOracle)
Beispiel #9
0
def main():
    """
    Connect to badger system, and configure multisig for running transactions in local fork without access to accounts
    """

    # Connect badger system from file
    badger = connect_badger()
    digg = badger.digg

    # Sanity check file addresses
    expectedMultisig = "0xB65cef03b9B89f99517643226d76e286ee999e77"
    assert badger.devMultisig == expectedMultisig

    if rpc.is_active():
        distribute_test_ether(badger.devMultisig, Wei("5 ether"))

    # Multisig wrapper

    # Get price data from sushiswap, uniswap, and coingecko
    digg_usd_coingecko = 41531.72
    btc_usd_coingecko = 32601.13

    digg_per_btc = digg_usd_coingecko / btc_usd_coingecko

    uniTWAP = get_average_daily_price("scripts/oracle/data/uni_digg_hour")
    sushiTWAP = get_average_daily_price("scripts/oracle/data/sushi_digg_hour")
    averageTWAP = Average([uniTWAP, sushiTWAP])

    console.print({
        "uniTWAP": uniTWAP,
        "sushiTWAP": sushiTWAP,
        "averageTWAP": averageTWAP
    })

    supplyBefore = digg.token.totalSupply()

    print("spfBefore", digg.token._sharesPerFragment())
    print("supplyBefore", digg.token.totalSupply())

    marketValue = Wei(str(averageTWAP) + " ether")

    print(marketValue)

    print(int(marketValue * 10**18))

    print("digg_per_btc", digg_per_btc, averageTWAP, marketValue)

    if rpc.is_active():
        distribute_test_ether(digg.centralizedOracle, Wei("5 ether"))

    centralizedMulti = GnosisSafe(digg.centralizedOracle)

    print(digg.marketMedianOracle.providerReports(digg.centralizedOracle, 0))
    print(digg.marketMedianOracle.providerReports(digg.centralizedOracle, 1))

    print(digg.cpiMedianOracle.providerReports(digg.constantOracle, 0))
    print(digg.cpiMedianOracle.providerReports(digg.constantOracle, 1))

    print(digg.cpiMedianOracle.getData.call())

    sushi = SushiswapSystem()
    pair = sushi.getPair(digg.token, registry.tokens.wbtc)

    uni = UniswapSystem()
    uniPair = uni.getPair(digg.token, registry.tokens.wbtc)

    print("pair before", pair.getReserves())
    print("uniPair before", uniPair.getReserves())

    tx = centralizedMulti.execute(
        MultisigTxMetadata(description="Set Market Data"),
        {
            "to": digg.marketMedianOracle.address,
            "data":
            digg.marketMedianOracle.pushReport.encode_input(marketValue),
        },
    )
    chain.mine()

    print(tx.call_trace())
    print(tx.events)

    chain.sleep(hours(0.4))
    chain.mine()

    in_rebase_window = digg.uFragmentsPolicy.inRebaseWindow()

    while not in_rebase_window:
        print("Not in rebase window...")
        chain.sleep(hours(0.1))
        chain.mine()
        in_rebase_window = digg.uFragmentsPolicy.inRebaseWindow()

    tx = digg.orchestrator.rebase({"from": accounts[0]})
    chain.mine()

    supplyAfter = digg.token.totalSupply()

    print("spfAfter", digg.token._sharesPerFragment())
    print("supplyAfter", supplyAfter)
    print("supplyChange", supplyAfter / supplyBefore)
    print("supplyChangeOtherWay", supplyBefore / supplyAfter)

    print("pair after", pair.getReserves())
    print("uniPair after", uniPair.getReserves())
Beispiel #10
0
def create_uniswap_pair(token0, token1, signer):
    uniswap = UniswapSystem()
    if not uniswap.hasPair(token0, token1):
        uniswap.createPair(token0, token1, signer)

    return uniswap.getPair(token0, token1)