def _spotPrices(T1: btoken.BToken, T2: btoken.BToken, wallet: web3wallet.Web3Wallet, bal1: float, bal2: float, w1: float, w2: float): pool = _createPoolWith2Tokens(T1, T2, wallet, bal1, bal2, w1, w2) a1, a2 = T1.address, T2.address return (fromBase18(pool.getSpotPrice_base(a1, a2)), fromBase18(pool.getSpotPriceSansFee_base(a1, a2)))
def transferOCEAN(self, dst_wallet, amt: float) -> None: assert isinstance(dst_wallet, AgentWallet) or \ isinstance(dst_wallet, BurnWallet) dst_address = dst_wallet._address amt_base = toBase18(amt) assert amt_base >= 0 if amt_base == 0: return OCEAN_base = self._OCEAN_base() if OCEAN_base == 0: raise ValueError("no funds to transfer from") tol = 1e-12 if (1.0 - tol) <= amt / fromBase18(OCEAN_base) <= (1.0 + tol): amt_base = OCEAN_base if amt_base > OCEAN_base: raise ValueError("transfer amt (%s) exceeds OCEAN holdings (%s)" % (fromBase18(amt_base), fromBase18(OCEAN_base))) globaltokens.OCEANtoken().transfer(dst_address, amt_base, self._web3wallet) dst_wallet._total_OCEAN_in += amt self.resetCachedInfo() dst_wallet.resetCachedInfo()
def testSendEth(): _web3 = web3util.get_web3() network = web3util.get_network() #wallet1 should have got ETH from ganache startup (see deploy.py) private_key1 = web3util.confFileValue(network, 'TEST_PRIVATE_KEY1') wallet1 = web3wallet.Web3Wallet(private_key1) orig_bal1_base = wallet1.ETH_base() print("orig bal1 = %s" % web3util.fromBase18(orig_bal1_base)) assert orig_bal1_base > web3util.toBase18(1.0) #wallet2 should have 0 ETH wallet2 = web3wallet.randomWeb3Wallet() orig_bal2_base = wallet2.ETH_base() print("orig bal2 = %s" % web3util.fromBase18(orig_bal2_base)) assert orig_bal2_base == 0 #wallet1 gives wallet2 1.0 ETH sent_base = web3util.toBase18(1.0) wallet1.sendEth(wallet2.address, sent_base) new_bal1_base = wallet1.ETH_base() new_bal2_base = wallet2.ETH_base() print("new bal1 = %s" % web3util.fromBase18(new_bal1_base)) print("new bal2 = %s" % web3util.fromBase18(new_bal2_base)) assert new_bal2_base == sent_base assert (orig_bal1_base - sent_base*1.1) < new_bal1_base < (orig_bal1_base - sent_base)
def test_exitswapExternAmountOut(T1, T2, alice_address, alice_wallet): pool = _createPoolWith2Tokens(T1, T2, alice_wallet, 90.0, 10.0, 9.0, 1.0) BPT = pool pool.finalize(from_wallet=alice_wallet) assert fromBase18(T1.balanceOf_base(alice_address)) == 910.0 pool.exitswapExternAmountOut( tokenOut_address=T1.address, tokenAmountOut_base=toBase18(2.0), #T1 wanted maxPoolAmountIn_base=toBase18(10.0), #max BPT spent from_wallet=alice_wallet) assert fromBase18(T1.balanceOf_base(alice_address)) == (910.0 + 2.0) assert fromBase18(BPT.balanceOf_base(alice_address)) >= (100.0 - 10.0)
def test_joinswapPoolAmountOut(T1, T2, alice_address, alice_wallet): pool = _createPoolWith2Tokens(T1, T2, alice_wallet, 90.0, 10.0, 9.0, 1.0) BPT = pool pool.finalize(from_wallet=alice_wallet) T1.approve(pool.address, toBase18(90.0), from_wallet=alice_wallet) assert fromBase18(T1.balanceOf_base(alice_address)) == 910.0 pool.joinswapPoolAmountOut( tokenIn_address=T1.address, poolAmountOut_base=toBase18(10.0), #BPT wanted maxAmountIn_base=toBase18(90.0), #max T1 to spend from_wallet=alice_wallet) assert fromBase18(T1.balanceOf_base(alice_address)) >= (910.0 - 90.0) assert fromBase18(BPT.balanceOf_base(alice_address)) == (100.0 + 10.0)
def test_calcSpotPrice_base(T1, T2, alice_address, alice_wallet): pool = _deployBPool(alice_wallet) x = pool.calcSpotPrice_base(tokenBalanceIn_base=toBase18(10.0), tokenWeightIn_base=toBase18(1.0), tokenBalanceOut_base=toBase18(11.0), tokenWeightOut_base=toBase18(1.0), swapFee_base=0) assert round(fromBase18(x), 3) == 0.909
def test_unbind(T1, T2, alice_wallet): pool = _createPoolWith2Tokens(T1, T2, alice_wallet, 1.0, 1.0, 1.0, 1.0) pool.unbind(T1.address, from_wallet=alice_wallet) assert pool.getNumTokens() == 1 assert pool.getCurrentTokens() == [T2.address] assert fromBase18(pool.getBalance_base(T2.address)) == 1.0
def test_calcInGivenOut_base(alice_wallet): pool = _deployBPool(alice_wallet) x = pool.calcInGivenOut_base(tokenBalanceIn_base=toBase18(10.0), tokenWeightIn_base=toBase18(1.0), tokenBalanceOut_base=toBase18(10.1), tokenWeightOut_base=toBase18(1.0), tokenAmountOut_base=toBase18(1.0), swapFee_base=0) assert round(fromBase18(x), 3) == 1.099
def test_calcPoolInGivenSingleOut_base(alice_wallet): pool = _deployBPool(alice_wallet) x = pool.calcPoolInGivenSingleOut(tokenBalanceOut_base=toBase18(1000.0), tokenWeightOut_base=toBase18(5.0), poolSupply_base=toBase18(100.0), totalWeight_base=toBase18(10.0), tokenAmountOut_base=toBase18(0.1), swapFee_base=0) assert round(fromBase18(x), 3) == 0.005
def test_calcSingleOutGivenPoolIn_base(alice_wallet): pool = _deployBPool(alice_wallet) x = pool.calcSingleOutGivenPoolIn_base(tokenBalanceOut_base=toBase18(10.0), tokenWeightOut_base=toBase18(1.0), poolSupply_base=toBase18(120.0), totalWeight_base=toBase18(2.0), poolAmountIn_base=toBase18(10.0), swapFee_base=0) assert round(fromBase18(x), 3) == 1.597
def __str__(self): s = [] s += ["BPool:"] s += [f" pool_address={self.contract.address}"] s += [f" controller address = {self.getController()}"] s += [f" isPublicSwap = {self.isPublicSwap()}"] s += [f" isFinalized = {self.isFinalized()}"] swap_fee = web3util.fromBase18(self.getSwapFee_base()) s += [" swapFee = %.2f%%" % (swap_fee * 100.0)] s += [f" numTokens = {self.getNumTokens()}"] cur_addrs = self.getCurrentTokens() cur_symbols = [BToken(addr).symbol() for addr in cur_addrs] s += [f" currentTokens (as symbols) = {', '.join(cur_symbols)}"] if self.isFinalized(): final_addrs = self.getFinalTokens() final_symbols = [BToken(addr).symbol() for addr in final_addrs] s += [f" finalTokens (as symbols) = {final_symbols}"] s += [f" is bound:"] for addr, symbol in zip(cur_addrs, cur_symbols): s += [f" {symbol}: {self.isBound(addr)}"] s += [f" weights (fromBase):"] for addr, symbol in zip(cur_addrs, cur_symbols): denorm_w = web3util.fromBase18( self.getDenormalizedWeight_base(addr)) norm_w = web3util.fromBase18(self.getNormalizedWeight_base(addr)) s += [f" {symbol}: denorm_w={denorm_w}, norm_w={norm_w} "] total_denorm_w = web3util.fromBase18( self.getTotalDenormalizedWeight_base()) s += [f" total_denorm_w={total_denorm_w}"] s += [f" balances (fromBase):"] for addr, symbol in zip(cur_addrs, cur_symbols): balance_base = self.getBalance_base(addr) dec = BToken(addr).decimals() balance = web3util.fromBase(balance_base, dec) s += [f" {symbol}: {balance}"] return "\n".join(s)
def test_2tokens_basic(T1, T2, alice_wallet, alice_address): pool = _deployBPool(alice_wallet) assert T1.address != T2.address assert T1.address != pool.address assert fromBase18(T1.balanceOf_base(alice_address)) >= 90.0 bal2 = fromBase18(T2.balanceOf_base(alice_address)) >= 10.0 with pytest.raises(Exception): #can't bind until we approve pool.bind(T1.address, toBase18(90.0), toBase18(9.0)) #Bind two tokens to the pool T1.approve(pool.address, toBase18(90.0), from_wallet=alice_wallet) T2.approve(pool.address, toBase18(10.0), from_wallet=alice_wallet) assert fromBase18(T1.allowance_base(alice_address, pool.address)) == 90.0 assert fromBase18(T2.allowance_base(alice_address, pool.address)) == 10.0 assert not pool.isBound(T1.address) and not pool.isBound(T1.address) pool.bind(T1.address, toBase18(90.0), toBase18(9.0), from_wallet=alice_wallet) pool.bind(T2.address, toBase18(10.0), toBase18(1.0), from_wallet=alice_wallet) assert pool.isBound(T1.address) and pool.isBound(T2.address) assert pool.getNumTokens() == 2 assert pool.getCurrentTokens() == [T1.address, T2.address] assert pool.getDenormalizedWeight_base(T1.address) == toBase18(9.0) assert pool.getDenormalizedWeight_base(T2.address) == toBase18(1.0) assert pool.getTotalDenormalizedWeight_base() == toBase18(9.0 + 1.0) assert pool.getNormalizedWeight_base(T1.address) == toBase18(0.9) assert pool.getNormalizedWeight_base(T2.address) == toBase18(0.1) assert pool.getBalance_base(T1.address) == toBase18(90.0) assert pool.getBalance_base(T2.address) == toBase18(10.0) assert str(pool)
def test_joinSwapExternAmountIn(T1, T2, alice_wallet, alice_address): pool = _createPoolWith2Tokens(T1, T2, alice_wallet, 90.0, 10.0, 9.0, 1.0) T1.approve(pool.address, toBase18(100.0), from_wallet=alice_wallet) #pool's not public with pytest.raises(Exception): pool.swapExactAmountOut(tokenIn_address=T1.address, maxAmountIn_base=toBase18(100.0), tokenOut_address=T2.address, tokenAmountOut_base=toBase18(10.0), maxPrice_base=HUGEINT, from_wallet=alice_wallet) #pool's public pool.setPublicSwap(True, from_wallet=alice_wallet) pool.swapExactAmountOut(tokenIn_address=T1.address, maxAmountIn_base=toBase18(100.0), tokenOut_address=T2.address, tokenAmountOut_base=toBase18(1.0), maxPrice_base=HUGEINT, from_wallet=alice_wallet) assert 908.94 <= fromBase18(T1.balanceOf_base(alice_address)) <= 908.95 assert fromBase18(T2.balanceOf_base(alice_address)) == (1000.0 - 9.0)
def OCEAN(self) -> float: return fromBase18(self._OCEAN_base())
def BPT(self, pool: bpool.BPool) -> float: return fromBase18(self._BPT_base(pool))
def DT(self, dt: datatoken.Datatoken) -> float: return fromBase18(self._DT_base(dt))
def ETH(self) -> float: return fromBase18(self._ETH_base())
def test_public_pool(T1, T2, alice_address, alice_wallet, bob_address, bob_wallet): pool = _createPoolWith2Tokens(T1, T2, alice_wallet, 90.0, 10.0, 9.0, 1.0) BPT = pool #alice give Bob some tokens T1.transfer(bob_address, toBase18(100.0), from_wallet=alice_wallet) T2.transfer(bob_address, toBase18(100.0), from_wallet=alice_wallet) #verify holdings assert fromBase18(T1.balanceOf_base(alice_address)) == (1000.0 - 90.0 - 100.0) assert fromBase18(T2.balanceOf_base(alice_address)) == (1000.0 - 10.0 - 100.0) assert fromBase18(BPT.balanceOf_base(alice_address)) == 0 assert fromBase18(T1.balanceOf_base(bob_address)) == 100.0 assert fromBase18(T2.balanceOf_base(bob_address)) == 100.0 assert fromBase18(BPT.balanceOf_base(bob_address)) == 0 assert fromBase18(T1.balanceOf_base(pool.address)) == 90.0 assert fromBase18(T2.balanceOf_base(pool.address)) == 10.0 assert fromBase18(BPT.balanceOf_base(pool.address)) == 0 #finalize pool = bpool.BPool(pool.address) pool.finalize(from_wallet=alice_wallet) #verify holdings assert fromBase18(T1.balanceOf_base(alice_address)) == (1000.0 - 90.0 - 100.0) assert fromBase18(T2.balanceOf_base(alice_address)) == (1000.0 - 10.0 - 100.0) assert fromBase18(BPT.balanceOf_base(alice_address)) == 100.0 #new! assert fromBase18(T1.balanceOf_base(pool.address)) == 90.0 assert fromBase18(T2.balanceOf_base(pool.address)) == 10.0 assert fromBase18(BPT.balanceOf_base(pool.address)) == 0 #bob join pool. Wants 10 BPT T1.approve(pool.address, toBase18(100.0), from_wallet=bob_wallet) T2.approve(pool.address, toBase18(100.0), from_wallet=bob_wallet) pool.joinPool( poolAmountOut_base=toBase18(10.0), #10 BPT maxAmountsIn_base=[toBase18(100.0), toBase18(100.0)], from_wallet=bob_wallet) #verify holdings assert fromBase18(T1.balanceOf_base(alice_address)) == (1000.0 - 90.0 - 100.0) assert fromBase18(T2.balanceOf_base(alice_address)) == (1000.0 - 10.0 - 100.0) assert fromBase18(BPT.balanceOf_base(alice_address)) == 100.0 assert fromBase18(T1.balanceOf_base(bob_address)) == (100.0 - 9.0) assert fromBase18(T2.balanceOf_base(bob_address)) == (100.0 - 1.0) assert fromBase18(BPT.balanceOf_base(bob_address)) == 10.0 assert fromBase18(T1.balanceOf_base(pool.address)) == (90.0 + 9.0) assert fromBase18(T2.balanceOf_base(pool.address)) == (10.0 + 1.0) assert fromBase18(BPT.balanceOf_base(pool.address)) == 0 #bob sells 2 BPT # -this is where BLabs fee kicks in. But the fee is currently set to 0. pool.exitPool(poolAmountIn_base=toBase18(2.0), minAmountsOut_base=[toBase18(0.0), toBase18(0.0)], from_wallet=bob_wallet) assert fromBase18(T1.balanceOf_base(bob_address)) == 92.8 assert fromBase18(T2.balanceOf_base(bob_address)) == 99.2 assert fromBase18(BPT.balanceOf_base(bob_address)) == 8.0 #bob buys 5 more BPT pool.joinPool(poolAmountOut_base=toBase18(5.0), maxAmountsIn_base=[toBase18(90.0), toBase18(90.0)], from_wallet=bob_wallet) assert fromBase18(BPT.balanceOf_base(bob_address)) == 13.0 #bob fully exits pool.exitPool(poolAmountIn_base=toBase18(13.0), minAmountsOut_base=[toBase18(0.0), toBase18(0.0)], from_wallet=bob_wallet) assert fromBase18(BPT.balanceOf_base(bob_address)) == 0.0
def test_setSwapFee_works(alice_wallet): pool = _deployBPool(alice_wallet) pool.setSwapFee(toBase18(0.011), from_wallet=alice_wallet) assert fromBase18(pool.getSwapFee_base()) == 0.011