def test_getting_balances(self): # given self.dgx.mint(Wad(17 * 10**9)).transact() self.dai.mint(Wad.from_number(17)).transact() # when balances = self.zrx_api.get_balances(self.pair) # then assert balances[0] == Wad.from_number(17) assert balances[1] == Wad.from_number(17)
def test_transfer_generates_transfer(self): # when receipt = self.token.transfer(self.second_address, Wad(500)).transact() # then assert len(receipt.transfers) == 1 assert receipt.transfers[0].token_address == self.token.address assert receipt.transfers[0].from_address == self.our_address assert receipt.transfers[0].to_address == self.second_address assert receipt.transfers[0].value == Wad(500)
def close_repaid_safe(): if safe.locked_collateral > Wad(0) and safe.generated_debt == Wad(0): delta_collateral = safe.locked_collateral * -1 assert geb.safe_engine.modify_safe_collateralization( collateral_type, our_address, delta_collateral, Wad(0)).transact() collateral_balance = Wad( geb.safe_engine.collateral(collateral_type, our_address)) if collateral_balance > Wad(0): assert collateral.adapter.exit(our_address, collateral_balance).transact()
def auction_id(geb, c: Collateral, auction_income_recipient_address) -> int: # set to pymaker price set_collateral_price(geb, c, Wad.from_number(500)) # Ensure we start with a clean safe safe = geb.safe_engine.safe(c.collateral_type, auction_income_recipient_address) assert safe.locked_collateral == Wad(0) assert safe.generated_debt == Wad(0) # liquidate SAFE critical_safe = create_critical_safe(geb, c, bid_size, auction_income_recipient_address) return liquidate(geb, c, critical_safe)
def test_mainnet_async_sync_replacement(self): first_tx = weth.deposit(Wad(4)) logging.info( f"Submitting first TX with gas price deliberately too low") self._run_future(first_tx.transact_async(gas_price=slow_gas)) second_tx = weth.deposit(Wad(6)) logging.info(f"Replacing first TX with legitimate gas price") second_tx.transact(replace=first_tx, gas_price=fast_gas) assert first_tx.replaced
def test_empty_both(self): # when creating and shutting down the keeper keeper = self.create_keeper(True, True) keeper.shutdown() # then ensure the safe_engine is empty assert self.get_system_coin_safe_engine_balance() == Wad(0) assert self.get_collateral_safe_engine_balance() == Wad(0) # clean up self.give_away_system_coin()
def test_prepare_coins_for_redeeming(self, geb, our_address): assert geb.global_settlement.coin_bag(our_address) == Wad(0) assert geb.global_settlement.outstanding_coin_supply() > Rad(0) assert geb.system_coin.approve( geb.global_settlement.address).transact() assert geb.safe_engine.coin_balance(our_address) >= Rad.from_number(10) # FIXME: `prepareCoinsForRedeeming` fails, possibly because we're passing 0 to `safeEngine.transfer_collateral` assert geb.global_settlement.prepare_coins_for_redeeming( Wad.from_number(10)).transact() assert geb.global_settlement.coin_bag(our_address) == Wad.from_number( 10)
def test_transfer_failed_async(self): # when receipt = synchronize([ self.token.transfer(self.second_address, Wad(5000000)).transact_async() ])[0] # then assert receipt is None assert self.token.balance_of(self.our_address) == Wad(1000000) assert self.token.balance_of(self.second_address) == Wad(0)
def test_transfer_async(self): # when receipt = synchronize([ self.token.transfer(self.second_address, Wad(750)).transact_async() ]) # then assert receipt is not None assert self.token.balance_of(self.our_address) == Wad(999250) assert self.token.balance_of(self.second_address) == Wad(750)
def test_approval(self): # given assert self.ds_systemcoin.allowance_of(self.our_address, self.router_address) == Wad(0) # when self.systemcoin_usdc_uniswap.approve(self.token_systemcoin) # then assert self.ds_systemcoin.allowance_of(self.our_address, self.router_address) > Wad(0)
def test_mint_generates_transfer(self): # when receipt = self.dstoken.mint(Wad(100000)).transact() # then assert len(receipt.transfers) == 1 assert receipt.transfers[0].token_address == self.dstoken.address assert receipt.transfers[0].from_address == Address( '0x0000000000000000000000000000000000000000') assert receipt.transfers[0].to_address == self.our_address assert receipt.transfers[0].value == Wad(100000)
def test_burn_from_other_address(self): # given self.dstoken.mint_to(self.second_address, Wad(100000)).transact() # when self.dstoken.approve( self.our_address).transact(from_address=self.second_address) self.dstoken.burn_from(self.second_address, Wad(40000)).transact() # then assert self.dstoken.balance_of(self.second_address) == Wad(60000)
def test_transfer_from(self): # given self.token.approve(self.second_address).transact() # when self.token.transfer_from( self.our_address, self.third_address, Wad(500)).transact(from_address=self.second_address) # then assert self.token.balance_of(self.third_address) == Wad(500)
def test_transfer_out_of_gas_async(self): # when with pytest.raises(Exception): synchronize([ self.token.transfer(self.second_address, Wad(500)).transact_async(gas=26000) ])[0] # then assert self.token.balance_of(self.our_address) == Wad(1000000) assert self.token.balance_of(self.second_address) == Wad(0)
def ensure_clean_safe(geb: GfDeployment, collateral: Collateral, address: Address): assert isinstance(geb, GfDeployment) assert isinstance(collateral, Collateral) assert isinstance(address, Address) safe = geb.safe_engine.safe(collateral.collateral_type, address) assert safe.locked_collateral == Wad(0) assert safe.generated_debt == Wad(0) assert geb.safe_engine.token_collateral(collateral.collateral_type, address) == Wad(0)
def simulate_model_bid(self, geb: GfDeployment, c: Collateral, model: object, gas_price: Optional[int] = None): assert (isinstance(geb, GfDeployment)) assert (isinstance(c, Collateral)) assert (isinstance(gas_price, int)) or gas_price is None collateral_auction_house = c.collateral_auction_house initial_bid = collateral_auction_house.bids(model.id) assert initial_bid.amount_to_sell > Wad(0) our_bid = Wad.from_number(500) * initial_bid.amount_to_sell reserve_system_coin(geb, c, self.keeper_address, our_bid, extra_collateral=Wad.from_number(2)) simulate_model_output(model=model, price=Wad.from_number(500), gas_price=gas_price)
def remaining_sell_amount(self) -> Wad: unavailable_buy_amount = self._exchange.get_unavailable_buy_amount( self) if unavailable_buy_amount >= self.buy_amount: return Wad(0) else: return Wad.max( self.pay_amount - (unavailable_buy_amount * self.pay_amount / self.buy_amount), Wad(0))
def wipe_debt(geb: GfDeployment, collateral: Collateral, address: Address): safe = geb.safe_engine.safe(collateral.collateral_type, address) assert Rad(safe.generated_debt) >= geb.safe_engine.coin_balance(address) delta_collateral = Ray(geb.safe_engine.coin_balance( address)) / geb.safe_engine.collateral_type( collateral.collateral_type.name).accumulated_rate wrap_modify_safe_collateralization( geb, collateral, address, Wad(0), Wad(delta_collateral) * -1) #because there is residual state on the testchain assert geb.safe_engine.coin_balance(address) <= Rad( Wad(1)) # pesky dust amount in Dai amount
def test_eth_transfer(self): # given initial_balance = eth_balance(self.web3, self.second_address) # when eth_transfer(self.web3, self.second_address, Wad.from_number(1.5)).transact() # then assert eth_balance( self.web3, self.second_address) == initial_balance + Wad.from_number(1.5)
def get_balance(self, proxy: Address) -> Wad: assert (isinstance(proxy, Address)) total_pie = self.mcd.pot.pie() if total_pie == Wad.from_number(0): return Wad.from_number(0) slice = self.mcd.pot.pie_of(proxy) portion = slice / total_pie dai_in_pot = self.mcd.vat.dai(self.mcd.pot.address) return Wad(dai_in_pot * portion)
def test_join_all(self): # given system_coin we just exited token_balance_before = self.get_system_coin_token_balance() assert token_balance_before == Wad.from_number(237) # when keeper is started with a token balance self.create_keeper_join_all() # then ensure all available tokens were joined assert self.get_system_coin_token_balance() == Wad(0) assert self.get_system_coin_safe_engine_balance() == Wad.from_number( 237)
def test_exit_all(self): # given balances before assert self.get_system_coin_token_balance() == Wad.from_number(37) assert self.get_system_coin_safe_engine_balance() == Wad.from_number( 200) # when rebalancing to 0 self.create_keeper(0.0) # then ensure all system_coin has been exited assert self.get_system_coin_token_balance() == Wad.from_number(237) assert self.get_system_coin_safe_engine_balance() == Wad(0)
def max_delta_debt(geb: GfDeployment, collateral: Collateral, our_address: Address) -> Wad: assert isinstance(geb, GfDeployment) assert isinstance(collateral, Collateral) assert isinstance(our_address, Address) print("max_delta_debt") print( f"Liquidation price {geb.safe_engine.collateral_type(collateral.collateral_type.name).liquidation_price}" ) print( f"Safety price {geb.safe_engine.collateral_type(collateral.collateral_type.name).safety_price}" ) safe = geb.safe_engine.safe(collateral.collateral_type, our_address) collateral_type = geb.safe_engine.collateral_type( collateral.collateral_type.name) # change in debt = (collateral balance * collateral price with safety margin) - SAFE's stablecoin debt delta_debt = safe.locked_collateral * collateral_type.safety_price - Wad( Ray(safe.generated_debt) * collateral_type.accumulated_rate) print(f"max_delta_debt for collateral_type {collateral_type.name}") print( f"delta debt: {delta_debt} = locked_collateral {safe.locked_collateral} * safety_price {collateral_type.safety_price} - debt {Ray(safe.generated_debt)}" ) # change in debt must also take the rate into account delta_debt = Wad(Ray(delta_debt) / collateral_type.accumulated_rate) # prevent the change in debt from exceeding the collateral debt ceiling if (Rad(safe.generated_debt) + Rad(delta_debt)) >= collateral_type.debt_ceiling: print("max_delta_debt is avoiding collateral debt ceiling") delta_debt = Wad(collateral_type.debt_ceiling - Rad(safe.generated_debt)) # prevent the change in debt from exceeding the total debt ceiling debt = geb.safe_engine.global_debt() + Rad( collateral_type.accumulated_rate * delta_debt) debt_ceiling = Rad(geb.safe_engine.global_debt_ceiling()) if (debt + Rad(delta_debt)) >= debt_ceiling: print( f"debt {debt} + delta_debt {delta_debt} >= {debt_ceiling}; max_delta_debt is avoiding total debt ceiling" ) delta_debt = Wad(debt - Rad(safe.generated_debt)) # ensure we've met the debt_floor cutoff if Rad(safe.generated_debt + delta_debt) < collateral_type.debt_floor: print( f"max_delta_debt is being bumped from {safe.generated_debt + delta_debt} to {collateral_type.debt_floor} to reach debt_floor cutoff" ) delta_debt = Wad(collateral_type.debt_floor) return delta_debt
def test_approval(self): # given assert self.token1.allowance_of(self.our_address, self.asset_proxy) == Wad(0) assert self.zrx_token.allowance_of(self.our_address, self.asset_proxy) == Wad(0) # when self.exchange.approve([self.token1], directly()) # then assert self.token1.allowance_of(self.our_address, self.asset_proxy) > Wad(0)
def get_all_trades(self, pair: str, page_number: int = 1) -> List[Trade]: assert (isinstance(pair, str)) assert (isinstance(page_number, int)) assert (page_number == 1) result = self._http_get("/api/v1/trades", f"symbol={pair}") return list( map( lambda item: Trade(trade_id=int(item['id']), timestamp=float(item['time'] / 1000), price=Wad.from_number(item['price']), amount=Wad.from_number(item['qty'])), result))
def test_join_enough(self, keeper_address): # given purchasing some system_coin purchase_system_coin(Wad.from_number(237), keeper_address) token_balance_before = self.get_system_coin_token_balance() assert token_balance_before == Wad.from_number(237) # when rebalancing with a smaller amount than we have self.create_keeper(153.0) # then ensure system_coin was joined to the safe_engine assert token_balance_before > self.get_system_coin_token_balance() assert self.get_system_coin_safe_engine_balance() == Wad.from_number( 153)
def test_should_raise_exception_on_unknown_kwarg(self): # expect with pytest.raises(Exception): self.token.transfer(self.second_address, Wad(123)).transact(unknown_kwarg="some_value") # expect with pytest.raises(Exception): synchronize([ self.token.transfer( self.second_address, Wad(123)).transact_async(unknown_kwarg="some_value") ])
def test_exit_some(self): # given balances before assert self.get_system_coin_token_balance() == Wad(0) assert self.get_system_coin_safe_engine_balance() == Wad.from_number( 237) # when rebalancing to a smaller amount than currently in the safe_engine self.create_keeper(200.0) # then ensure balances are as expected assert self.get_system_coin_token_balance() == Wad.from_number(37) assert self.get_system_coin_safe_engine_balance() == Wad.from_number( 200)
def test_join_not_enough(self): # given balances before assert self.get_system_coin_token_balance() == Wad.from_number(84) assert self.get_system_coin_safe_engine_balance() == Wad.from_number( 153) # when rebalancing without enough tokens to cover the difference self.create_keeper(500.0) # then ensure all available tokens were joined assert self.get_system_coin_token_balance() == Wad(0) assert self.get_system_coin_safe_engine_balance() == Wad.from_number( 237)
def mint_prot(prot: DSToken, recipient_address: Address, amount: Wad): assert isinstance(prot, DSToken) assert isinstance(recipient_address, Address) assert isinstance(amount, Wad) assert amount > Wad(0) deployment_address = Address("0x00a329c0648769A73afAc7F9381E08FB43dBEA72") assert prot.mint(amount).transact(from_address=deployment_address) assert prot.balance_of(deployment_address) > Wad(0) assert prot.approve(recipient_address).transact( from_address=deployment_address) assert prot.transfer(recipient_address, amount).transact(from_address=deployment_address)