Example #1
0
        public void SwapToken(Address buyer, Address seller, string baseSymbol, string quoteSymbol, BigInteger tokenID, BigInteger price, byte[] signature)
        {
            Runtime.Expect(IsWitness(buyer), "invalid witness");
            Runtime.Expect(seller != buyer, "invalid seller");

            Runtime.Expect(Runtime.Nexus.TokenExists(baseSymbol), "invalid base token");
            var baseToken = Runtime.Nexus.GetTokenInfo(baseSymbol);

            Runtime.Expect(!baseToken.Flags.HasFlag(TokenFlags.Fungible), "token must be non-fungible");

            var ownerships = new OwnershipSheet(baseSymbol);
            var owner      = ownerships.GetOwner(this.Storage, tokenID);

            Runtime.Expect(owner == seller, "invalid owner");

            var swap = new TokenSwap()
            {
                baseSymbol  = baseSymbol,
                quoteSymbol = quoteSymbol,
                buyer       = buyer,
                seller      = seller,
                price       = price,
                value       = tokenID,
            };

            var msg = Serialization.Serialize(swap);

            Runtime.Expect(Ed25519.Verify(signature, msg, seller.PublicKey), "invalid signature");

            Runtime.Expect(Runtime.Nexus.TokenExists(quoteSymbol), "invalid quote token");
            var quoteToken = Runtime.Nexus.GetTokenInfo(quoteSymbol);

            Runtime.Expect(quoteToken.Flags.HasFlag(TokenFlags.Fungible), "token must be fungible");

            var balances = new BalanceSheet(quoteSymbol);
            var balance  = balances.Get(this.Storage, buyer);

            Runtime.Expect(balance >= price, "invalid balance");

            Runtime.Expect(Runtime.Nexus.TransferTokens(quoteSymbol, this.Storage, Runtime.Chain, buyer, owner, price), "payment failed");
            Runtime.Expect(Runtime.Nexus.TransferToken(baseSymbol, this.Storage, Runtime.Chain, owner, buyer, tokenID), "transfer failed");

            Runtime.Notify(EventKind.TokenSend, seller, new TokenEventData()
            {
                chainAddress = Runtime.Chain.Address, symbol = baseSymbol, value = tokenID
            });
            Runtime.Notify(EventKind.TokenSend, buyer, new TokenEventData()
            {
                chainAddress = Runtime.Chain.Address, symbol = quoteSymbol, value = price
            });

            Runtime.Notify(EventKind.TokenReceive, seller, new TokenEventData()
            {
                chainAddress = Runtime.Chain.Address, symbol = quoteSymbol, value = price
            });
            Runtime.Notify(EventKind.TokenReceive, buyer, new TokenEventData()
            {
                chainAddress = Runtime.Chain.Address, symbol = baseSymbol, value = tokenID
            });
        }
Example #2
0
        public void SwapTokens(Address buyer, Address seller, string baseSymbol, string quoteSymbol, BigInteger amount, BigInteger price, byte[] signature)
        {
            Runtime.Expect(IsWitness(buyer), "invalid witness");
            Runtime.Expect(seller != buyer, "invalid seller");

            var baseToken = Runtime.Nexus.FindTokenBySymbol(baseSymbol);

            Runtime.Expect(baseToken != null, "invalid base token");
            Runtime.Expect(baseToken.Flags.HasFlag(TokenFlags.Fungible), "token must be fungible");

            var baseBalances = Runtime.Chain.GetTokenBalances(baseToken);
            var baseBalance  = baseBalances.Get(seller);

            Runtime.Expect(baseBalance >= amount, "invalid amount");

            var swap = new TokenSwap()
            {
                baseSymbol  = baseSymbol,
                quoteSymbol = quoteSymbol,
                buyer       = buyer,
                seller      = seller,
                price       = price,
                value       = amount,
            };

            var msg = Serialization.Serialize(swap);

            Runtime.Expect(Ed25519.Verify(signature, msg, seller.PublicKey), "invalid signature");

            var quoteToken = Runtime.Nexus.FindTokenBySymbol(quoteSymbol);

            Runtime.Expect(quoteToken != null, "invalid base token");
            Runtime.Expect(quoteToken.Flags.HasFlag(TokenFlags.Fungible), "token must be fungible");

            var quoteBalances = Runtime.Chain.GetTokenBalances(quoteToken);
            var quoteBalance  = quoteBalances.Get(buyer);

            Runtime.Expect(quoteBalance >= price, "invalid balance");

            Runtime.Expect(quoteToken.Transfer(quoteBalances, buyer, seller, price), "payment failed");
            Runtime.Expect(baseToken.Transfer(baseBalances, seller, buyer, amount), "transfer failed");

            Runtime.Notify(EventKind.TokenSend, seller, new TokenEventData()
            {
                chainAddress = Runtime.Chain.Address, symbol = baseSymbol, value = amount
            });
            Runtime.Notify(EventKind.TokenSend, buyer, new TokenEventData()
            {
                chainAddress = Runtime.Chain.Address, symbol = quoteSymbol, value = price
            });

            Runtime.Notify(EventKind.TokenReceive, seller, new TokenEventData()
            {
                chainAddress = Runtime.Chain.Address, symbol = quoteSymbol, value = price
            });
            Runtime.Notify(EventKind.TokenReceive, buyer, new TokenEventData()
            {
                chainAddress = Runtime.Chain.Address, symbol = baseSymbol, value = amount
            });
        }