# Tinyman V2 Overview

The Tinyman V2 docs

[Tinyman](https://tinyman.org/) is a next-generation decentralized Automated Market Maker (AMM) on the Algorand blockchain.

{% hint style="info" %}
Tinyman is live on Algorand Mainnet. See [app.tinyman.org](https://app.tinyman.org)
{% endhint %}

\
\
**Website**: <https://tinyman.org/>\
**Web** **App**: <https://app.tinyman.org>\
**Github**: <https://github.com/tinymanorg>\
**Twittter**: [@tinymanorg](https://twitter.com/tinymanorg)

This documentation describes the [design](/protocol-specification) of the system, provides an explanation of the [core concepts](/faq), and documents the technical details to enable integration with the protocol.

{% content-ref url="/pages/n5ko2tclDAPqMRwG4VB2" %}
[About Tinyman](/about-tinyman)
{% endcontent-ref %}

{% content-ref url="/pages/yepG1RgDnNV9ra799YEA" %}
[Protocol Specification](/protocol-specification)
{% endcontent-ref %}

{% content-ref url="/pages/cwqcOHy8YiOqFQZ7EF4k" %}
[Permissioned Methods](/permissioned-methods)
{% endcontent-ref %}

{% content-ref url="/pages/xpCC5BuwV17Ct3SsysNr" %}
[FAQ](/faq)
{% endcontent-ref %}

{% content-ref url="/pages/3ayJCioT4SAnBhcjo6kv" %}
[Fees](/protocol-specification/fees)
{% endcontent-ref %}

{% content-ref url="/pages/RArypJMatkCdksZvFhuW" %}
[Formulae](/formulae)
{% endcontent-ref %}

{% content-ref url="/pages/yUCillzzyKU0bMCug39T" %}
[Swap Router](/swap-router)
{% endcontent-ref %}

{% content-ref url="/pages/umTUHU1s6OxGklSQEVRj" %}
[Disclaimer](/disclaimer)
{% endcontent-ref %}

{% content-ref url="/pages/6WFMyNgtT5MkwMSgQBGT" %}
[Audits & Security](/audits-and-security)
{% endcontent-ref %}


# About Tinyman

Tinyman protocol, platform and core principles

Tinyman is a decentralized application developed to empower all web3 users, regardless of their background. It takes inspiration from the principles of transparency, open source development, decentralization, autonomy, and permissionless access that are central to creating public blockchains. With these values at its core, Tinyman aims to promote the use of these principles in the web3 space to create a more inclusive and transparent financial system.<br>

Tinyman consists of two main components: Tinyman protocol and Tinyman platform.&#x20;

**Tinyman Protocol** is a smart contract set that operates as an Automated Market-Maker on the Algorand blockchain.&#x20;

**Tinyman Platform** is the web interface that enables users to interact with the Tinyman protocol through the tinyman.org domain.&#x20;

## Tinyman Protocol

Tinyman is a non-custodian decentralized exchange on Algorand that works with the Automated Market Maker(AMM) approach, specifically with the Constant Product Formula. This model is considered more suitable for trading on blockchain thanks to its capability to provide liquidity at all times. To read more about the differences between AMM and the order book mode, please refer to LINK.

Tinyman AMM v2 protocol was developed and deployed by the Tinyman team on the Algorand blockchain.

Tinyman [contracts](/contracts) are written in [Tealish](https://github.com/tinymanorg/tealish) for AVM V7.&#x20;

The Tinyman development team chose Algorand as the foundation for their project due to its compatibility with Tinyman's values and advanced technological capabilities. Algorand's commitment to scalability, security, and decentralization, as well as its ability to handle a high volume of transactions efficiently, made it an ideal choice for the team.

## Tinyman Platform

Facilitating on-chain interactions for Tinyman users, the Tinyman platform is comprised of a web app that runs on [tinyman.org](https://tinyman.org) domain and its additional tools such as:

* Tinyman protocol
* [SDKs](/v2-integration/official-sdks)
* Widgets
* Tealish
* ASA icons platform on [asa-list.tinyman.org](https://asa-list.tinyman.org)
* Social Media Channels

All components of the Tinyman platform are managed by the Tinyman team.\ <br>

## Tinyman Core Principles

The design of the Tinyman AMM v2 protocol is based on the following principles:

**Open-source:** The Tinyman AMM v2 protocol is open-source, meaning that the entire codebase is available for review by anyone interested in trading on or adding funds to the protocol. This transparency allows all users to validate the operating system, whether they are interacting directly with the smart contracts or using the Tinyman platform. We encourage all users to review the codebase and related documents to ensure complete understanding and confidence in the system.

**Decentralized:** Decentralization is a core principle of Tinyman. The platform has no control over the funds that users add and cannot access any of the assets in pools. All assets are held in the contracts deployed on the decentralized Algorand blockchain, ensuring that the system is fully decentralized and not subject to the control of any single entity.

**Permissionless:** Core Tinyman functionalities can be initiated by any Algorand address, granted the contract's task requirements are met. During any stage of these operations, no Algorand address or entity, including Tinyman itself, can disable access or revert transactions.

**Immutable:** Tinyman protocols, rules, and parameters are fixed and cannot be modified once deployed on the blockchain. The use of immutability in Tinyman helps to ensure the integrity and security of the system, as it prevents any unauthorized changes or tampering with the system's functioning.


# Protocol Specification

Tinyman AMM V2 is a Constant Product Market Maker. It is mathematically similar to Tinyman V1 which in turn was modeled on Uniswap V2. The contract and protocol design for Tinyman AMM V2 is significantly different from V1 as it uses more recent features of the Algorand Virtual Machine.

{% content-ref url="/pages/pVna3G3NTPShGBCeoAZx" %}
[Pool](/protocol-specification/pool)
{% endcontent-ref %}

{% content-ref url="/pages/S0OxRQn6f19zMXQqTjoy" %}
[Swap](/protocol-specification/swap)
{% endcontent-ref %}

{% content-ref url="/pages/3ayJCioT4SAnBhcjo6kv" %}
[Fees](/protocol-specification/fees)
{% endcontent-ref %}

{% content-ref url="/pages/xvPYQRY3M8WXZMEtpygG" %}
[Flash Loan](/protocol-specification/flash-loan)
{% endcontent-ref %}

{% content-ref url="/pages/ylc9j1pHX69GiiCV5ZR8" %}
[Flash Swap](/protocol-specification/flash-swap)
{% endcontent-ref %}

{% content-ref url="/pages/slwrdmGbjPZhhrEF0lpD" %}
[Additional Notes](/protocol-specification/additional-notes)
{% endcontent-ref %}


# Pool

An AMM based decentralized exchange is made up of a number of ‘Pools’, with one pool per asset pair. Users can swap assets through these pools by sending some of one asset and receiving the equivalent value of the other asset.

The funds in the pools are owned by ‘Liquidity Providers’. Each liquidity provider contributes and retains ownership of a share of the pool’s funds. The liquidity provider receives ‘Pool Tokens’ to represent their share of the pool. They can reclaim their assets at any time by returning the pool tokens.&#x20;

Each Pool is an Algorand Account. The accounts hold the assets and state related to the pool. A single stateful Algorand Application contains all the logic that controls the asset transfers and state management of the pools.

Each Pool has a number of local state variables which are updated during every operation. The asset reserves (liquidity) of the pool are tracked in the local state and not determined dynamically from the account balances. This means that ‘donations’ to the pool or Algo making up the minimum balance do not contribute to the asset reserves.

If assets are transferred to the pool account with transactions that are not part of a documented group the assets will be lost. These assets are called “extra” and are only transferable to the fee collector. They will not affect the liquidity of the pool or the shares of the liquidity providers.

{% content-ref url="/pages/5NUIGQ79qZmcfGOONpKW" %}
[Pool Creation](/protocol-specification/pool/pool-creation)
{% endcontent-ref %}

{% content-ref url="/pages/LVpghIKStlSOc0Iq288Q" %}
[Adding Liquidity](/protocol-specification/pool/adding-liquidity)
{% endcontent-ref %}

{% content-ref url="/pages/dRd1KyIqrjQiYuOpWthy" %}
[Removing Liquidity](/protocol-specification/pool/removing-liquidity)
{% endcontent-ref %}


# Pool Creation

Pools are created with two separate operations; Bootstrap & Add Initial Liquidity.

A pool is created as a [Smart Signature Contract Account](https://developer.algorand.org/docs/get-details/dapps/smart-contracts/smartsigs/modes/#contract-account). The Smart Signature is derived from a standard template but it is unique per pool because it contains the ids of the pair of assets.

## Bootstrap

The account is turned into a pool by issuing an Application Call transaction to the AMM app. This transaction opts the account into the app and also rekeys the contract account to the App account. \
As a contract account, this transaction must be signed by the associated Smart Signature. After this transaction is confirmed the Smart Signature no longer has authority over the account as it has been rekeyed. Instead, the AMM App has full authority over the pool account.

During the Bootstrap operation, the app creates the Pool Token asset and transfers the total supply to the pool account. These are done with Inner Transactions. All pool token assets are created by the app account so that there is a single well-known creator address of Tinyman AMM V2 pool tokens. The Reserve address of the pool token asset is set to the pool address.\
\
The Bootstrap operation requires some Algo to cover the minimum balances for the pool account (Formula I), asset creation (100000 micro Algo), and transaction fees. This Algo must be supplied to the pool prior to the Bootstrap Application Call. It will usually be in the same group but this is not required.

[Transaction Details for bootstrap](/v2-integration/protocol-methods/bootstrap)


# Adding Liquidity

Funds are added to the pool with Asset Transfer transactions together with an Application Call. Pool tokens are sent to the user by the pool using an inner transaction. There are two methods for adding liquidity.

## **Adding Initial Liquidity**

If the pool has no liquidity then the first user to add liquidity is free to set the ratio between the two assets. If the pool has any liquidity this transaction fails and the user should use the Adding Subsequent Liquidity method. The formula to determine the number of pool tokens for initial liquidity is [Formula II.A](https://docs.tinyman.org/protocol-specification/pool/pages/RArypJMatkCdksZvFhuW#a.-adding-initial-liquidity).

[Transaction Details for add\_initial\_liquidity](/v2-integration/protocol-methods/add-initial-liquidity)

## **Adding Subsequent Liquidity**

The formula to determine the number of pool tokens for subsequent liquidity is [Formula II.B](https://docs.tinyman.org/protocol-specification/pool/pages/RArypJMatkCdksZvFhuW#b.-adding-subsequent-liquidity).

The protocol supports adding liquidity in a flexible way so that the user does not have to provide amounts of assets at exactly the current pool ratio. Instead, it supports a continuum between liquidity at exactly the current ratio and all liquidity in a single asset. This is achieved by internal implicit swaps where necessary. A swap fee is charged on the amount that must be swapped. The value of this fee is reduced from the pool tokens output.

If the user does provide liquidity at exactly the current ratio then there will be no swap fee and pool tokens will be output for the entirety of the liquidity provided.

A special case of providing liquidity in a flexible way is providing liquidity in only one single asset. In this case the user does not need to transfer a zero amount but can instead omit the transfer transaction entirely.

When providing liquidity at a ratio different from the current pool ratio the user must be aware of the loss of value due to both price impact and fees of the implicit swap. The user can pre-calculate the expected value of pool tokens accounting for these and provide the min\_output parameter to ensure the amount of pool tokens output matches their expectations. This can protect the user from sudden price changes between the time of signing and executing the transaction.

### **Adding liquidity with two assets**

When adding liquidity with two assets two transfer transactions are required in addition to the application call transaction. The 2nd application arg must be the byte string “flexible” in this case.

### **Adding liquidity with a single asset**

When adding liquidity with one asset one transfer transaction is required in addition to the application call transaction. The 2nd application arg must be the byte string “single” in this case.

[Transaction Details for add\_liquidity](/v2-integration/protocol-methods/add-subsequent-liquidity)


# Removing Liquidity

Liquidity providers can remove funds from the pool with an Asset Transfer of pool tokens and an Application Call.&#x20;

Amounts of each asset are sent to the user by the pool using two inner transactions. The amount of each asset received is proportional to the pool tokens returned and dependent on the current ratio of the pool. See [Formula III.A](https://docs.tinyman.org/protocol-specification/pool/pages/RArypJMatkCdksZvFhuW#a.-multiple-asset-out).

## **Removing liquidity as a single asset**

The protocol supports removing liquidity as a single asset from pools by combining removing liquidity with an internal swap calculation. The entirety of one side of the liquidity will be swapped into the other asset. A swap fee is charged on this amount and deducted from the output.

See [Formula III.B](https://docs.tinyman.org/protocol-specification/pool/pages/RArypJMatkCdksZvFhuW#b.-single-asset-out).

When using this convenience method the user must be aware of the loss of value due to both price impact and fees of the implicit swap. The user can pre-calculate the expected output accounting for these and provide the min\_output parameter to ensure the amount of output matches their expectations. This can protect the user from sudden price changes between the time of signing and executing the transaction.


# Swap

Swaps are made with an Asset Transfer transaction together with an Application Call.

An amount of the other asset is sent to the user by the pool using an inner transaction.

The type of swap may be either fixed-input or fixed-output. If the type is fixed-output an extra inner transaction is sent to return any change from the input amount to the user (see below). A fixed-output swap has a higher transaction fee because it requires one extra inner transaction.

A swap fee is charged on all swaps. The fee is set per pool as basis points. This fee is deducted from the input amount before applying the swap formula to calculate the output.

The formulae for fixed-input and fixed-output swaps are described in [Formula IV.A & IV.B](https://docs.tinyman.org/protocol-specification/pages/RArypJMatkCdksZvFhuW#iv.-swapping) respectively.

## **Slippage Tolerance**

Swaps have slippage tolerance to allow for changes to the exchange rate between the time the swap was prepared and the swap was executed. For a fixed-input swap, a minimum output amount is included in the Application Call arguments. If the calculated output amount is less than this amount the swap will fail.

For a fixed-output swap, the slippage tolerance is included in the input amount and the exact output amount is specified in the arguments. If the calculated input amount required to achieve the target output amount is less than the provided input amount the swap fails. If it is greater then the change is returned to the user by an inner transaction.

[Transaction Details for swap](/v2-integration/protocol-methods/swap)


# Fees

Tinyman charges fees on swaps, loans and internal swap operations. A portion of this fee is allocated to the protocol (Tinyman) and the remainder is allocated to the liquidity providers by adding to the pool reserves.

The fee rate and the protocol fee fraction portion are configurable parameters on each pool. The total fee rate can be set in the range from 0.01% to 1% (1 to 100 basis points), the protocol fee fraction can be set as 1/n in the range from 1/3 to 1/10. The default fee rate is %0.3 and protocol fee fraction is 1/6 (0.05% of total input). These defaults are the same as the Tinyman V1.

Pools have a single fee setting and the same rate is applied to all swap, loan and internal swap operations.

The protocol fees accumulate in both assets. They can be claimed in full at any time by any user that issues an appropriate Application Call. The accumulated amounts of both assets are transferred by inner transactions to the fee collector. The fee collector is specified by a global state variable of the App (fee\_collector). The  fee\_collector can be set by the global fee\_manager address.

Fee parameters can be set by the global fee\_setter address. The fee\_setter address can be set by the global fee\_manager address. The fee\_manager address can be set by the current fee\_manager address.

## **Swap Fees**

Swap fees are collected from the input assets.

**Examples:**

**A. Fixed Input**

If the input amount is 5000A, fee is 5000\*fee rate AssetA. If the fee rate is 0.3%, total fee is 15 AssetA, pooler fee is 13 AssetA and protocol fee is 2 AssetA.

If the input amount is 20000A, fee is 20000A\*fee rate AssetA. If the fee rate is 0.3%, total fee is 60 AssetA and protocol fee is 10 AssetA.

\
**B. Fixed Output**

In this method, the extra amount added because of the slippage is returned back to the users with an inner transaction. The input amount is calculated by subtracting the extra amount from the transferred amount and the fee is applied to this amount.

If the transferred amount is 1005A, and extra amount is 5, the fee is applied to 1000 AssetA.

## **Flash Loan Fees**

The fee rate is the same with the swap fee rate of the pool. It is applied to the loan amounts. The repayment must be equal or greater than the total of loan amount and fee.

**Examples:**

**A. Loan single asset**

If the loan is 3000 AssetA, fee is 3000\*fee rate AssetA. It is 9 AssetA if the fee rate is 0.3%, so minimum repayment amount is 3009 AssetA.

**B. Loan multiple assets**

If the loan is 3000 AssetA and 5000 AssetB, fee is 3000\*fee rate AssetA and 5000\*fee rate AssetB. The minimum repayment amounts are 3009 AssetA and 5015 AssetB, if the fee rate is 0.3%.

## **Flash Swap Fees**

The fee calculation is the same as swap. The same swap fee rate is applied to input amounts.

**Examples:**

**A. Pay in single asset**

If the payment is 3000 AssetA, the fee is 3000\*fee rate AssetA.

**B. Pay in multiple assets**

If the payment is 1000 AssetA and 2000 AssetB, the fees are 1000\*fee rate AssetA and 2000\*fee rate AssetB.

## **Swap Router Fees**

The swap router doesn’t charge additional fees. Tinyman AMM V2 fee policy applies to swaps.

Using the swap router requires 3 more transactions than 2 swaps and 6 more transactions than a single swap. API is aware of this difference and makes suggestions accordingly. The total transaction fee is converted from Algo to input asset amount using the price information, calculated by pool reserves. However, if this conversion is impossible, the transaction fee isn’t included in the calculation.

All transaction fees must be paid by the sender of any of the outer transactions. The inner transaction fees are not paid by the swap router app account.


# Flash Loan

Flash loan allows users to borrow single or multiple assets with no collateral with the condition of paying it back within the same transaction group. It allows advanced users to create a custom transaction group to generate a profit without an initial capital.

Flash loan requires two application calls. The first one is for requesting a loan from the pool and the second one is for verifying the repayment.

The repayments must be made in the same asset. The repayment amount should cover the loan amount and fee. The swap fee rate applies to loan amounts.

With the first app call users specify the amount of loans in terms of asset 1 and asset 2 and group index difference between first and second application calls. Loan amounts cannot exceed the pool reserves. Requested assets are transferred to the user using inner transactions.

Verification calls check the repayment amounts. The transaction fails if they don’t cover the loan amount and fee. Repayments should be placed just before the verification app call and the contract checks the transfer amounts. Any extra payments are considered donations to pools.

Flash loan transactions can appear anywhere within a transaction group and a single group may contain multiple flash loans.

Users can use the same pool freely between the two application calls and do a swap. Unlike Flash Swap (below) usage of the pool is not restricted.


# Flash Swap

Flash swap has similarities to swap and flash loan. It is designed for advanced users. They can create a custom transaction group, borrow assets from the pool with an application call and make a profit (arbitrage, collateral swap etc.), pay it back within the same transaction group and make another application call to verify the payment. If the payment amount is insufficient all transactions in the atomic group fail. It allows users to generate profit without risk and collateral.

Unlike the flash loan, users are free to pay back in both assets as long as the final pool invariant increases and covers the fee. This can allow for more efficient transactions in some scenarios compared to the Flash Loan.

In the regular swap, the user transfers input assets to the pool first and then receives the output assets. Flash swap allows users to change this order. They can receive the output assets first, and use these assets to make a profit, and transfer input assets to the pool. In this scenario, the applied fee is exactly the same as the swap and the fee is applied to input assets and collected in terms of input assets. If users receive 500 AssetA and send 1000 AssetB, fee amount will be 3 AssetB with default fee rate 0.3% (1000\*0.003=3).

Additionally, similar to flash loan, flash swap allows users to borrow a single asset or both assets of the pool. Unlike the flash loan, users are free to pay back in both assets as long as the final pool invariant increases and covers the fee. Fees are applied to all input assets. If the repayment is made as 1000 AssetA and 2000 AssetB, the fee is collected in both assets as 3 AssetA and 6 AssetB. If the repayment is made in a single asset such as 3000 AssetB, the fee is 9 AssetB.

With the first app call, users specify the amount of loans in terms of asset 1 and asset 2 and group index difference between first and second (verification) application calls. Loan amounts cannot exceed the pool reserves. Requested assets are transferred to the user using inner transactions.

The verification calls check the initial and final invariant. Repayments must be made between two app calls. The app checks the final balance to determine the paid amounts and doesn’t check a particular transfer so users can make multiple inner and outer transactions. Any extra payments are considered as donations to the pools.

The pool is locked between the two application calls and no operation (swap, add & remove liquidity etc.) is allowed. These operations can be used before or after the flash swap in the same transaction group however.


# Additional Notes

## **Donations**

Any assets that are in the pool accounts but not part of the reserves, protocol fees or minimum Algo balance are claimable to the fee\_collector address.

Algorand Participation Rewards that accumulate in accounts holding Algo are considered donations to the pool and do not contribute to the pool reserves in AMM V2 (unlike V1). As of [2022/05/14 the Participation Rewards program is finished](https://algorand.foundation/faq#participation-rewards-) and no further rewards are planned to be distributed by this mechanism. In the event that this mechanism is re-enabled in the future the pool accounts would accumulate rewards that would be claimable by the fee\_collector address. It would be up to the protocols managers (development team or DAO) to decide how those rewards should be used.

## **Algo Pools**

The AMM V2 protocol supports ASA-Algo pools just like V1. All references to ‘Assets’ in this document equally apply to Algo. The transaction details differ slightly whenever Algo is involved as Payment transactions are used instead of Asset Transfer.

## **Transaction Fees**

All transaction fees must be paid by the sender of any of the outer transactions of an operation. The inner transaction fees cannot be paid by the pool account and app account.

## **Users**

This document refers to ‘Users’ as the senders of assets and transactions to the pool and receivers of assets from the pool. The protocol does not place any restriction on the type of account that initiates a pool operation and therefore supports operations made by application accounts in the same way as regular accounts. Additionally there is no requirement that the sender of all transactions in an operation group is the same account.

The receiver of assets (Pool Tokens, swapped assets, removed assets, change, etc) is always the sender of the Application Call.

## **Transaction Groups & Composability**

Each operation requires multiple transactions that must be part of the same atomic group. The exact indices of the transactions within the group or the size of the group is not specified by the protocol however so it is possible to create groups containing additional transactions before or after a swap for example. However relative indexing is used so the relative location of transactions within the group is specified and must be adhered to.

Operation transaction groups may also be created as inner transactions from within another Application. The only exception to this is the Bootstrap operation for creating pools, which requires a Smart Signature that cannot be used from an inner transaction.

## **Pool Discovery**

Clients can discover the existence of pools in either of two ways;

1. Every pool account is opted into the Tinyman App. Any account opted into this app is a valid pool. A list of pool accounts can therefore be retrieved from an Algorand Indexer or other block follower. The [local state](/v2-integration/state-data#local-state-pool) of these accounts gives the details of the pool.
2. The pool account address can be computed from the LogicSig template.


# FAQ

{% content-ref url="/pages/mdAOSSqQnO7Xh2CfAR77" %}
[Migration FAQ](/faq/migration-faq)
{% endcontent-ref %}

## Introduction

### What is Tinyman?

Tinyman is a decentralized protocol on the Algorand blockchain that enables users to trade or swap Assets at market rates. The web app ([app.tinyman.org](http://app.tinyman.org)) is a visual interface for interacting with a set of smart contracts deployed to the Algorand blockchain.

### What are Tinyman’s design principles?

Tinyman protocol is open-source, decentralized, permissionless, persistent, non-custodian, and immutable (non-upgradable).&#x20;

### What is Algorand and ALGO?

Algorand is a blockchain launched in 2018 to solve the “blockchain-trilemma” with a fast, secure, decentralized and scalable framework built with PPoS (Pure Proof of Stake) consensus mechanism. Tinyman V2 smart contracts are deployed on Algorand blockhain.\
ALGO is the native currency of the Algorand blockchain.

### What is Algorand Standard Asset?

Algorand Standard Assets (ASA) provide a standardized, Layer-1 mechanism to represent any type of Asset on the Algorand blockchain. Only ASAs and ALGO are tradable assets on Tinyman.&#x20;

### How does Tinyman work?

Tinyman protocol works with smart contracts that allow users to swap assets, provide liquidity and borrow/pay flash loans. Tinyman smart contracts are built with the Automated Market Maker(AMM) mechanism, specifically the Constant Product Formula.

### What is an AMM - Automated Market Maker?

Automated market makers (AMM) are a type of decentralized exchange (DEX) that pool liquidity from users and allow digital assets to be traded automatically and without permission. AMMs use smart contracts to provide deep liquidity, low transaction fees, and uninterrupted access for all users. They offer a highly efficient and reliable way to trade digital assets on the blockchain.

### Who can use Tinyman?

Any individual or organization interested in trading or supplying liquidity on DeFi can use Tinyman.&#x20;

### How can users interact with Tinyman?

Users can interact with Tinyman pools using either of three methods:

1. Manually/programmatically creating, signing and submitting a set of transactions that satisfy the smart contracts
2. Signing and submitting the transactions created by the helper functions of the Tinyman Python SDK and Tinyman JS SDK.
3. Using the web app to do the swap, signing the transactions with a wallet browser extension.

### How can a user connect to Tinyman? Which wallets are available currently?

Users can access Tinyman using their Algorand wallet accounts. Currently:

* [Pera Wallet,](https://perawallet.app/)
* [MyAlgoWallet,](https://wallet.myalgo.com/access)
* [Exodus Wallet,](https://www.exodus.com/)
* [Defly,](https://defly.app/)
* [Fireblocks](https://www.fireblocks.com/)

are supported on the Tinyman web app. In addition, Tinyman supports the&#x20;

* Pera Connect,
* Wallet Connect,
* AlgoSigner connection modals.

For the latest wallet list, you may check the “Connect to a wallet” button on app.tinyman.org

Tinyman protocol and platform can operate with Ledger Wallets too. These users are encouraged to follow the latest updates to their ledgers as older versions can frequently experience issues with Tinyman. You may follow Ledger’s page for the latest updates:

<https://support.ledger.com/hc/en-us/articles/360012341980-Algorand-ALGO-?docs=true>

### What are the core Tinyman operations users can perform?

Users can:

1. Swap (exchange) assets. Those who swap on Tinyman are referred to as Traders or Swappers
2. Add/Remove Liquidity to Tinyman Pools, referred to Poolers or Liquidity Providers (LPs)
3. Earn farming rewards, referred to as Farmers

## Swap

### What is a Swap?&#x20;

Swap function allows users to exchange different assets using the liquidity provided by Tinyman pools. To initiate a swap on the web app, users may select the assets they want to exchange (input asset), specify the amount, and authorize the swap after confirming its details. If the conditions are met, then the swap will be successfully completed, and users will receive the output asset. If the transaction fails, the user will receive their input asset amount back.&#x20;

### Is there a fee when doing swaps? How much are the fees?

Yes, there is an industry-standard fee of 0.3% for all swaps on Tinyman, paid in the currency of input/sell asset. The V2 contracts for Tinyman allow for customization of swap fees, which is expected to increase flexibility and functionality in the future.

### What are slippage and slippage tolerance?

Slippage refers to the difference(slip) in price between the time a transaction is initiated and the time it is executed.&#x20;

Slippage tolerance is a user's preferred level of tolerance for slippage, expressed as a percentage. It determines the minimum output amount for a swap. For example, a slippage tolerance of "0%" means that the user does not tolerate any unfavorable change in the output amount of the swap, while a tolerance of "100%" means that the user is willing to accept any output amount.&#x20;

Tinyman's default slippage tolerance is set at 1%, which can be adjusted in the settings modal and on the swap form.&#x20;

### What is a Price Impact?

The price of a swap may change due to the depth of the liquidity pool and the size of the transaction. This change in price is known as Price Impact, which is expressed as a percentage. If the price impact of a proposed swap is greater than 5%, the Tinyman platform will display a warning and disable the swap button for a period of time. This precaution is in place to ensure that users are aware of the fair price levels, helping them to make informed decisions about their trades.

### What should Traders need to pay attention to when swapping?

It is recommended that Tinyman users compare the prices of the pool for a fair exchange, as well as consider the expected price impact and their current slippage rates during a swap. Having this information can assist users in making informed decisions about their trades. To support its users, Tinyman will also indicate on the swap form if a swap price seems ‘’fair’’, "normal" or ‘’too expensive’’

## Pool

### What is a Pool?

A pool is a collection of digital assets in a smart contract account contributed by Poolers. Pools provide liquidity for trading. Currently, each Tinyman pool contains only two assets. There is only one pool for every asset pair and currently, all pools are run by the same protocol rules.

### What is Total Value Locked (TVL)?

The total value (in $USD) of assets in the pool(s) is called Total Value Locked (TVL).

### How to add liquidity to a Pool?

Each Tinyman pool is designed to hold two specific assets and once created, only accepts those assets as liquidity. When users add liquidity to the pool, the protocol attempts to mathematically ensure that the requirements for adding assets to the pool are met.&#x20;

Tinyman V2 allows users to provide liquidity with different proportions of assets, including single-asset liquidity adding.&#x20;

### What are the Proportional Style and Flexible (FLEX) Styles?

Please read the previous answer first.

**Proportional Style Liquidity Adding** is the fundamental process for adding funds to a Tinyman pool, where the liquidity provider (LP) adds assets in the same proportion as that already present in the pool.&#x20;

**Flexible Style (FLEX) Liquidity Adding** is an alternative method that allows LPs to add any proportion of the two assets to the pool. In this case, Tinyman will perform an implicit swap to match the desired asset proportions, charging the LP a swap fee for this service and subsequently adding the assets to the Pool. **Single-asset liquidity adding** can also be done with Flexible Style on the web app.

### How much do LPs earn from swaps?

A fee of 0.3% is taken for all swaps on Tinyman. Out of this fee, the Tinyman protocol earns 0.05% and LPs earn 0.25%. The fee is paid in the currency of input/sell asset and added to the liquidity in the pool. LPs will earn a share of these fees based on their share of the pool. They can track their earnings for each pool on the "Your Positions" page.

### What is an LP token?

When liquidity providers (LPs) add assets to a Tinyman pool, they receive LP tokens that represent their share of the pool. The total value of all LP tokens represents the total value of assets in the pool, also known as the locked value. This ensures that the value of LP tokens accurately reflects the value of the assets in the pool and allows LPs to track their share of the pool.

### How do I withdraw my earnings from LP tokens?

Earnings from the swap fees accumulate within the LP tokens. To access these earnings, liquidity providers (LPs) can withdraw their liquidity from the pool. The earnings will be included in the LP tokens and can be claimed at that time.

### What is an Impermanent Loss (IL)?

We must revisit the mathematical formula of The Constant Product Model (CPM) used in AMMs to understand the Impermanent Loss. CPM’s formula is "Asset1 x Asset2 = k" where k is a constant that remains unchanged after trades and can only be adjusted when LPs add or remove funds from the pool. The "Asset 1 / Asset 2" ratio is the most current relative price.

Impermanent Loss: During trading, if the asset is traded against (sold), its amount in the pool grows and its price decreases. As a result, LPs will have more of the assets that decreased in value and less of the assets that increased in value. The difference in values between their original positions and their current positions, calculated with the most current asset prices, would yield a loss for the Liquidity Provider. This is a temporary - “impermanent” -  loss because if the market changes direction and the price returns to its original state, the loss will disappear. Similarly, any future price movements may cause this loss to appear and disappear again.

## Farm

### What is a farm?

Farms on Tinyman are programs that reward users for holding and committing specific LP tokens. Farms are a way for Tinyman to incentivize users to provide liquidity to selected pools. The farms are launched and managed by the Tinyman team, and they are funded by third-party organizations looking to offer additional incentives.

### Are LP tokens transferred or removed from users' wallets during farming?

No, LP tokens do not need to be transferred out of the user's wallet during Tinyman farming. When a user signs up for a Tinyman farming program, Tinyman simply tracks the amount of LP tokens in the user's wallet. There is no locking or movement of these tokens required. As long as the user maintains the agreed-upon amount of LP tokens in their wallet throughout the farming cycle, they will earn the corresponding rewards.

### How do I claim my farming earnings on Tinyman?

Tinyman farmers can claim their rewards at any time. These rewards can be collected after each cycle or accumulated until the farmer wishes to collect them.

## Other Services

### What are a flash loan and a flash swap?

Flash loans and flash swaps are advanced features that are currently only available on the Tinyman protocol and are not included in the web app.

A flash loan is a special transaction that allows users to borrow single or multiple assets from a pool with no collateral, provided that the borrowed assets are paid back within the same transaction group, along with a loan fee.

Flash swaps are similar to flash loans, but allow users to pay back the loan with either of the two assets in the pool, rather than just the borrowed asset.

### What other services does Tinyman offer?

Other Tinyman services and tools include:

* Analytics,
* Account Page,
* Bridge,
* Fiat on-ramp application,
* Python SDK,
* JavaScript SDK,
* Icon list for ASAs (asa-list.tinyman.org)

### What is Tinyman Analytics?

Tinyman Analytics is a feature of Tinyman that allows users to access real-time, detailed statistics, graphs, and other information about pools, assets, and transactions. By analyzing these statistics, users can make informed decisions about what to trade or which pools to provide liquidity to.

### Where can users see their wallet data?

The Tinyman Account page shows each wallet address's historical and current position data on a single page.&#x20;

### What is Bridge?&#x20;

A blockchain bridge is a tool that allows to port assets from one blockchain to another. It is used to overcome interoperability problems between different blockchains. Using bridges, users can access tokens or currencies on other chains. Tinyman has non-referral links to the following bridge applications:

* Wormhole,
* Algomint,
* pNetwork

### What is a Fiat On-ramp?&#x20;

A fiat on-ramp on Tinyman is a solution that allows users to access digital assets using their fiat holdings. Moonpay has been integrated into Tinyman, allowing users to purchase a variety of assets with their fiat currency. Tinyman does not currently charge an additional fee for its Moonpay referrals.

## Community Developers

### Where can I find Tinyman's contracts and other materials for developers?

Here is Tinyman’s GitHub: <https://github.com/tinymanorg>

### What is Tealish?

Tealish is an easy-to-read programming language designed for the Algorand Virtual Machine (AVM), the decentralized, open-source virtual machine that is built on top of the Algorand blockchain. Tealish is designed to enable developers to build and deploy smart contracts on the Algorand blockchain.

Tealish GitHub: <https://github.com/tinymanorg/tealish>

### What are the Tinyman protocol SDKs?

There are two SDKs for Tinyman protocol:\
Python SDK: <https://github.com/tinymanorg/tinyman-py-sdk>\
JavaScript SDK: <https://github.com/tinymanorg/tinyman-js-sdk/tree/main>

### Were Tinyman V2 smart contracts audited?

Yes the V2 smart contracts were audited by Runtime Verification. Here is their audit report and blog:

Audit Report: <https://github.com/runtimeverification/publications/blob/main/reports/smart-contracts/Tinyman-amm-v2-audit/tinyman-amm-v2-audit-report.pdf>\
Blog: <https://runtimeverification.com/blog/runtime-verification-audits-tinyman-amm-v2>

### Is there an ongoing community audit of Tinyman V2 smart contracts? Is there a bounty?

Tinyman encourages community developers to review and test the V2 smart contracts. There is a bug bounty of up to 200,000 USD available to incentivize these efforts. If you are interested in participating in the community audit, please visit [Bug Bounty Campaign on Immunefi](https://immunefi.com/bounty/tinymanv2/) to read more about the scope of the bug bounty and follow the guidelines for participation.

You can also reach out to us at <security@tinyman.org> to report your findings. Please be sure to follow caution and our guidelines when submitting a vulnerability.

## Tinyman Community

### What are the official Tinyman channels?

[Discord](https://discord.gg/xJRKueQdrG)

[Telegram](https://t.me/tinymanofficial)

[Twitter](https://twitter.com/tinymanorg)

[Reddit](https://www.reddit.com/r/Tinyman/)

[Website](https://tinyman.org/)

[Youtube](https://www.youtube.com/c/tinymanorg)

### How can a user contribute to Tinyman?

Users can participate in Tinyman's social channels to share their ideas, feedback, and comments. The team values the input of all community members and appreciates their contributions. Additionally, Tinyman has community roles available for various types of volunteer work. For the most up-to-date information, you can visit the Tinyman Discord channel.

### What is Tinyman Token, and when will it be released?

Tinyman Token is an item on Tinyman's roadmap that is planned to play a significant role in the future of the project. There is no set date for the release of the token at this time, and updates will be provided as more information becomes available.

## ASA guide for Tinyman

### How can I launch my ASA on Tinyman?

To launch your Algorand Standard Asset (ASA) on Tinyman, you can create a pool by pairing it with another asset. For example, you can create an "ASA-ALGO" pool by combining your ASA with Algo.

### What are the requirements for launching a new ASA Tinyman?

Tinyman is built on the Algorand blockchain, so it relies on Algorand Standard Assets (ASAs) to function. In order to be traded on Tinyman, an asset must be minted on the Algorand blockchain.

ASAs without decimal points, often used as NFTs in the Algorand ecosystem, are not compatible with the Tinyman protocol and may cause calculations to fail or result in funds becoming stuck in pools. While it may be possible to create pools with non-decimal ASAs, it is recommended to avoid using these types of assets with the Tinyman protocol.

Tinyman system is designed with the expectation that the minimum input and output amount of a swap is 1000 microunits. Swapping smaller amounts than this may lead to rounding errors that negatively affect users. Therefore, it is not at all advisable to create pools with assets that have a low total supply.

### How can I sell my NFT on Tinyman?

Tinyman is not designed to support the sale or exchange of NFTs (non-fungible tokens), which are often ASAs with no decimals. It is not recommended to offer and trade NFTs on Tinyman.

### How can I set the initial price of my ASA?

The ratio of assets in a Tinyman pool determines its relative price. When an ASA is first introduced on the platform, the initial asset ratio establishes its price. ASA owners can set their desired price by considering the ratio of assets they are adding to the pool.

### How can I control who can swap in my pool and who can add additional liquidity?

Tinyman is completely decentralized and permissionless. Swapping, adding liquidity, and removing liquidity can be carried out by any Algorand wallet engaging with Tinyman smart contracts. Therefore, nobody can limit access to a pool, whether it be the pool creator or the protocol.

### How can I pause/stop trading on my pool?

Regardless of who creates the pool or who issues an ASA, Tinyman functionalities cannot be obstructed.

### Where can I upload my logo?

To upload your logo to the Tinyman GitHub repository, follow the steps outlined on [asa-list.tinyman.org](https://asa-list.tinyman.org/). Once you have submitted your merge request, it will be reviewed by the Tinyman team. Please be aware that this process may take a few days, and we appreciate your patience as we review and process your request.

### How can I get verification on Tinyman?

Tinyman does not verify any assets and does not play a role in the verification process. This is handled by Pera Wallet, from which Tinyman obtains all verification information. Check out Pera Wallet's verification program [here](https://explorer.perawallet.app/asa-verification/).

Please note that Algoexplorer.io also has a separate verification program that is not connected to Pera Wallet or the information displayed on Tinyman.

### What does clawback mean in Algorand?

Assets on Algorand can optionally have “clawback” functionality enabled. This option can be enabled only when creating the asset. Once enabled/disabled, it becomes a feature of the asset and cannot be changed back. This allows the creator (or another delegated address) to remove assets from a holder’s account without their permission. This feature has genuine use cases but it may also be exploited by bad actors. Tinyman does not prevent creating or listing pools with clawback-enabled assets because some of the most commonly used assets have this feature enabled (e.g. USDt).&#x20;

Tinyman informs users if clawback is enabled with a badge on the asset. Users of the platform should use this information and consider the additional trust requirements in this situation. Users should be especially wary of providing liquidity to pools with these assets if they do not trust the asset creators. Tinyman Pools, as Algorand Accounts, can be subjected to clawback of their assets. If this happens the pool no longer maintains the correct ratio of assets and the internal accounting of pool reserves and pool price is out of sync with the account. This can cause transactions on the pool to fail. Transactions will continue to fail until the pool asset balances are returned to their correct levels. There is nothing the Tinyman team can do in this scenario and there is a real risk of loss of funds.&#x20;

The clawback usage warning will remain on a pool even if the pool has been returned to its correct levels and functions correctly. This serves as an additional warning to the user that the pool is at risk of malicious actions by the asset creator.

## Tinyman

### Does Tinyman store individual user information?

No, it doesn’t. Tinyman platforms do not require users to log in with personal accounts and do not track individual visitor data.

### Is there any legal restriction to becoming a Tinyman user?

The Tinyman protocol is open to participation from individuals and entities of all regions and nationalities, subject to compliance with local regulations.


# Migration FAQ

### How does Migration work?

Tinyman Migration allows users to transfer their liquidity and redeemables from a V1 pool to a corresponding V2 pool. It streamlines the process of migrating assets by handling all necessary steps under a single flow. When you initiate a pool migration with Tinyman, it will provide a list of all the steps it will complete.

### Is there a difference between migrating to an already existing pool and creating a new pool in V2?

Yes, there is a difference between creating a new pool in V2 and migrating to an already existing pool.&#x20;

When creating a new pool, a user must pay an additional Algo for the creation of the pool account, lock the initial 1 LP token, and set the price.&#x20;

Migrating to an existing V2 pool, on the other hand, does not require these actions and users follow the current price of the V2 pool when adding liquidity. It is also possible that flexible liquidity adding, with internal swaps to match the proportions of the pool and user funds, may be required when moving to an existing pool.

### During migration, why do I see different amounts of V1 and V2 LP tokens?

The amounts of V1 and V2 LP tokens may differ during migration due to the mathematical assessments of the protocol. The difference in LP token amounts does not necessarily imply any specific meaning or difference in value.

### Will the dollar value of my LP tokens stay the same after migrating V2 pools?

The dollar value of LP tokens may not remain the same after migrating to V2 pools.&#x20;

If a user is creating a new pool, pool creation fees and locked LP tokens will decrease the funds being added.&#x20;

If the user is adding liquidity to an existing V2 pool, a price difference between V1 and V2 pools is expected. The process of adding liquidity to an existing V2 pool while adjusting the liquidity to match the ratio of assets in the pool, nown as flexible liquidity adding, will incur a swap fee and may cause a fluctuation in funds.

### I see a different APR or no APR for v2 pools, why?

APR and APY values for V1 and V2 pools may differ because Tinyman calculates these values based on 1-day and 7-day trade volumes for each individual pool. Additionally, APR/APY values for newly created V2 pools, in particular, may be low or nonexistent in the early days of Tinyman V2.<br>


# Fees

Current Tinyman and Algorand fees incurred for each function

## Swapping

A fee of 0.3% is added to all swaps.&#x20;

* 5/6ths of this fee (0.25%) is paid to Poolers
* 1/6th of this fee (0.05%) is paid to the protocol (Tinyman Treasury)

**Fixed input swap:**\
Algorand transaction fees: 4 \* min fee = 0.004 Algo

**Fixed output swap:**\
Algorand transaction fees: 5 \* min fee = 0.005 Algo

## Adding & Removing Liquidity

There are no extra fees charged by Tinyman for Minting or Burning.

**Adding Initial liquidity:**\
Algorand transaction fees: 4 \* min fee = 0.004 Algo

**Adding subsequent liquidity for flexible:**\
Algorand transaction fees: 5 \* min fee = 0.005 Algo

**Adding subsequent liquidity for single asset:**\
Algorand transaction fees: 4 \* min fee = 0.004 Algo

**Removing liquidity for both multiple assets and single asset:**\
Algorand transaction fees: 4 \* min fee = 0.004 Algo

## Pool Creation (Bootstrap)

There are no extra fees charged by Tinyman for Pool Creation.

There are additional Algo costs to cover the minimum balance required for the Pool account:\
ASA-ASA Pool: 1.043 Algo\
ASA-Algo Pool: 0.943 Algo

Algorand transaction fees: \
ASA-ASA Pool: 7 \* min fee = 0.007 Algo\
ASA-Algo Pool: 6 \* min fee = 0.006 Algo

**Total costs for Pool Creation:**\
ASA-ASA Pool: 1.05 Algo\
ASA-Algo Pool: 0.949 Algo

## Flash Loan

A fee of 0.3% is added to flash loans.&#x20;

* 5/6ths of this fee (0.25%) is paid to Poolers
* 1/6th of this fee (0.05%) is paid to the protocol (Tinyman Treasury)

Algorand transaction fees: 4 \* min fee = 0.004 Algo

## Flash Swaps

A fee of 0.3% is added to flash loans.&#x20;

* 5/6ths of this fee (0.25%) is paid to Poolers
* 1/6th of this fee (0.05%) is paid to the protocol (Tinyman Treasury)

Algorand transaction fees: 4 \* min fee = 0.004 Algo

## Variable Fees

Tinyman V2 is introducing new governance functionality that will allow liquidity providers (LPs) to set the percentage of fees they want to collect for their pool up to a maximum of 5%. The current fee structure will remain unchanged until the governance feature is activated and put up for a vote. At that point, LPs will be able to propose changes to the fee structure through the governance process. Until then, the fee structure will continue as is.&#x20;


# Permissioned Methods

Manager Functionality

The protocol includes a number of permissioned methods. These are methods that can only be called by specific addresses. In this section we describe what these methods can and cannot do.

{% content-ref url="/pages/tT8M0vLpxjsdubOEoBTq" %}
[Roles](/permissioned-methods/roles)
{% endcontent-ref %}

{% content-ref url="/pages/kwaP6mx96Fq1owwOwfQ8" %}
[Methods](/permissioned-methods/methods)
{% endcontent-ref %}

{% content-ref url="/pages/wCK0IKl0CvIWlZMVGJ9q" %}
[Related Non-Permissioned Methods](/permissioned-methods/related-non-permissioned-methods)
{% endcontent-ref %}


# Roles

The fee\_manager, fee\_setter and fee\_collector are distinct roles in the protocol. Each of these are mutable.&#x20;

## **Fee Collector**

The fee\_collector is expected to be a single signature account used by an off-chain system to actively manage the accumulated protocol fees and extras. There is a not insignificant chance that this account could become compromised so in order to protect future earnings of the protocol this account must be replaceable by a higher authority - the fee\_manager.

## **Fee Setter**

The fee\_setter is expected to initially be a multisig account but over time it may transition to a system account for an automated process or a contract account governed by voting. To facilitate these changes of use and to protect against compromised keys the fee\_setter is configurable only by the fee\_manager.

## **Fee Manager**

The fee\_manager is expected to be a multisig account initially, and potentially a contract account governed by voting in the future. It is assumed that this account is never compromised. The protocol requires that the role can be transferred between accounts.

The fee\_manager, fee\_setter and fee\_collector roles are all initialized to the creator address of the application. This is assumed to be a multisig.

These roles are global - they cannot be defined separately for different pools.

There are no other roles or management capabilities defined in the protocol. There is no capability to pause/lock/close/empty any pool and there is no capability to upgrade the application.<br>


# Methods

## **Set Fee Collector**

This method is callable by the fee\_manager. It updates the global state value of fee\_collector to a new address.

## **Set Fee Setter**

This method is callable by the fee\_manager. It updates the global state value of fee\_setter to a new address.

## **Set Fee**

This method is callable by the fee\_setter. It updates the pool local state values of total\_fee\_share and protocol\_fee\_ratio to new values. The protocol enforces limits on the allowable values for each of these. This allows the swap fees of each pool to vary over time without moving or fragmenting liquidity. It is intended that these changes will be made based on sound market analysis for the benefit of the poolers and protocol.

## **Set Fee Manager**

This method is callable by the fee\_manager. It updates the global state value of fee\_manager to a new address.


# Related Non-Permissioned Methods

## **Claim Fees**

This method is callable by any address. It transfers all accumulated protocol fees to the fee\_collector account. This operation does not affect the liquidity of the pool.

## **Claim Extra**

This method is callable by any address. It allows transferring the extra asset and Algo amounts from application or pool accounts to the fee\_collector account. This operation does not affect the liquidity of the pool. “extra amounts” are defined as amounts held in the pool account that are not part of the asset reserves, protocol fees or minimum balance requirement.


# Formulae

## I. Pool Minimum Balance

Ref: [Minimum balance requirement for a smart contract](https://developer.algorand.org/docs/get-details/dapps/smart-contracts/apps/#minimum-balance-requirement-for-a-smart-contract)

Local state uint count: 12

Local state byte slice count: 2

### A. ASA-ASA Pool

100000 (Accounts on Algorand require a minimum balance of 100,000 micro Algo)\
\+ 100000 ASA 1 (Asset Optin)\
\+ 100000 ASA 2 (Asset Optin)\
\+ 100000 Pool Token (Asset Optin)\
\+ 542000 App Optin (100000 + (25000+3500)\*12 + (25000+25000)\*2)\
\= 942000 micro Algo

### B. ASA-ALGO Pool

100000 (Accounts on Algorand require a minimum balance of 100,000 micro Algo)\
\+ 100000 ASA 1 (Asset Optin)\
\+ 100,000 ASA 2 (Asset Optin)\
\+ 100000 Pool Token (Asset Optin)\
\+ 542000 App Optin (100000 + (25000+3500)\*12 + (25000+25000)\*2)\
\= 842000 micro Algo

## II. Adding Liquidity

### **A. Adding Initial Liquidity**

Issued Pool Tokens = floor(sqrt(Asset1 Amount \* Asset2 Amount))\
Locked Pool Tokens= 1000\
Pool Token Output = Issued Pool Tokens - Locked Pool Tokens

### **B. Adding Subsequent Liquidity**

The same formula applies to single and flexible modes.

Old K = Asset1 Reserves \* Asset2 Reserves\
New K = (Asset1 Reserves + Asset1 Amount) \* (Asset2 Reserves + Asset2 Amount)\
R = sqrt(Old K) / Issued Pool Tokens\
New Issued Pool Tokens = sqrt(New K) / R\
New Issued Pool Tokens = sqrt(New K) / ( sqrt(Old K) / Issued Pool Tokens)\
New Issued Pool Tokens = sqrt((New K \* Issued Pool Tokens\* Issued Pool Tokens) / Old K)

Pool Tokens Out = New Issued Pool Tokens - Old Issued Pool Tokens\
New Asset1 Reserves = Old Asset1 Reserves + Asset1 Amount\
New Asset2 Reserves = Old Asset1 Reserves + Asset2 Amount

Calculated Asset1 Amount = floor((Pool Tokens Out \* New Asset1 Reserves) / New Issued Pool Tokens)\
Calculated Asset2 Amount =floor((Pool Tokens Out \*New  Asset2 Reserves) / New Issued Pool Tokens)\
Asset1 Swap Amount = Asset1 Amount - Calculated Asset1 Amount\
Asset2 Swap Amount = Asset2 Amount - Calculated Asset2 Amount\
Swap Amount = Max(Asset1 Swap Amount, Asset2 Swap Amount)

Total Fee Amount = (Swap Amount \* Total Fee Share) / (10000 - Total Fee Share)\
Protocol Fee Amount = Total Fee Amount / Protocol Fee Ratio\
Poolers Fee Amount = Total Fee Amount - Protocol Fee Amount

Asset1 Swap Amount > Asset2 Swap Amount:\
Fee As Pool Tokens = (Total Fee Amount \* New Issued Pool Tokens) / (New Asset1 Reserves \* 2)\
New Asset1 Reserves = New Asset1 Reserves - Protocol Fee Amount\
Pool Tokens Out = Pool Tokens Out - Fee As Pool Tokens

Asset2 Swap Amount > Asset1 Swap Amount:\
Fee As Pool Tokens = (Total Fee Amount \* New Issued Pool Tokens) / (New Asset2 Reserves \* 2)\
New Asset2 Reserves = New Asset2 Reserves - Protocol Fee Amount\
Pool Tokens Out = Pool Tokens Out - Fee As Pool Tokens

## III. Removing Liquidity

### **A. Multiple Asset Out**

#### a. Remove all circulating pool tokens

Issued Pool Tokens == Locked Pool Tokens + Removed Pool Tokens\
Asset1 Output = Asset1 Reserves\
Asset2 Output = Asset2 Reserves

#### b. Otherwise

Issued Pool Tokens > Locked Pool Tokens + Removed Pool Tokens\
Asset1 Output= floor(Removed Pool Token Amount \* Asset1 Reserves / Issued Pool Tokens)\
Asset2 Output= floor(Removed Pool Token Amount \* Asset2 Reserves / Issued Pool Tokens)

### **B. Single Asset Out**

Calculate the Asset1 Output and Asset2 Output as multiple assets out and convert an asset to desired output by doing an internal swap (fixed-input swap).

#### a. Asset 1 Out

Input Amount = Asset2 Output\
Swap Output = FixedInputSwap(Input Amount)\
Asset1 Output=Asset1 Output + Swap Output\
Asset2 Output=0

#### b. Asset 2 Out

Input Amount = Asset1 Output\
Swap Output = FixedInputSwap(Input Amount)\
Asset2 Output=Asset2 Output + Swap Output\
Asset1 Output=0

## IV. Swapping

### **A. Fixed Input**&#x20;

Total Fee = floor((Input Amount \* Total Fee Share) / 10000)\
Protocol Fee = floor(Total Fee / Protocol Fee Ratio)\
Poolers Fee = Total Fee - Protocol Fee\
Swap Amount = Input Amount - Total Fee\
K = Input Supply \* Output Supply\
Swap Output = Output Supply - (floor(K / (Input Supply + Swap Amount)) + 1)

### **B. Fixed Output**

Swap Amount = (floor(K / (Output Supply - Output Amount)) + 1) - Input Supply\
Input Amount = floor((Swap Amount \* 10000) / (10000 - Total Fee Share))\
Total Fee = Input Amount - Swap Amount\
Protocol Fee = floor(Total Fee / Protocol Fee Ratio)\
Poolers Fee = Total Fee - Protocol Fee\
Change = Input Transfer Amount - Input Amount

## V. Flash Loan

Applies to both assets.

Total Fee = floor((Loan Amount \* Total Fee Share) / 10000)\
Protocol Fee = floor(Total Fee / Protocol Fee Ratio)\
Poolers Fee = Total Fee - Protocol Fee\
Expected Repayment Amount = Loan Amount + Total Fee\
Donation Amount = Repayment Transfer Amount - Expected Repayment Amount

## VI. Flash Swap

Applies to both assets.

Input Amount= Transfer Amount (Final Balance - Initial Balance)

**Note:** The rest is the same with fixed input swap.

Total Fee = floor((Input Amount \* Total Fee Share) / 10000)\
Protocol Fee = floor(Total Fee / Protocol Fee Ratio)\
Poolers Fee = Total Fee - Protocol Fee


# Disclaimer

Your use of the Tinyman protocol involves various risks, including, but not limited to, losses while digital assets are being supplied to the Tinyman protocol and losses due to the fluctuation of prices of tokens in a trading pair or liquidity pool. Before using the Tinyman protocol, you should review the relevant documentation to understand how the Tinyman protocol works. You are responsible for doing your diligence on the risks involved.

AS DESCRIBED IN THE TINYMAN PROTOCOL LICENSES, THE TINYMAN PROTOCOL IS PROVIDED "AS IS", AT YOUR OWN RISK, AND WITHOUT WARRANTIES OF ANY KIND. Although TM Distributed Development Ltd. ( "Tinyman" ) developed much of the initial code for the Tinyman protocol, it does not provide, own, or control the Tinyman protocol, which is run by smart contracts deployed on the Algorand blockchain. Accordingly, no developer or entity involved in creating the Tinyman protocol will be liable for any claims or damages whatsoever associated with your use, inability to use, or your interaction with other users of the Tinyman protocol, including any direct, indirect, incidental, special, exemplary, punitive or consequential damages, or loss of profits, cryptocurrencies, tokens, or anything else of value.


# Contracts

Source code on Github: <https://github.com/tinymanorg/tinyman-amm-contracts-v2>

Mainnet Validator App ID: [1002541853](https://algoexplorer.io/application/1002541853)

Testnet Validator App ID: [148607000](https://testnet.algoexplorer.io/application/148607000)

### Overview

The Tinyman V2 contracts consist of a single stateful smart contract (the **Validator App**) and a template for a stateless smart contract for each Pool, the **Pool LogicSig**. The Validator app is created/deployed to the network by the Tinyman team. The Pool contract accounts are created from the Pool LogicSig template by the first Pooler who wishes to provide liquidity. Pool contract account addresses are discovered or verified by Swappers/Poolers using the Pool LogicSig template to generate a specific Pool LogicSig and retrieving the address.

#### Validator App <a href="#docs-internal-guid-b18fd459-7fff-aa47-087b-2bcfdededbc5" id="docs-internal-guid-b18fd459-7fff-aa47-087b-2bcfdededbc5"></a>

* Stateful smart contract
* Created by Tinyman core team
* Fully immutable
  * No updates allowed
  * No deletion allowed
* Local state in Pool  accounts&#x20;
* Contains validation and state manipulation logic for all operations

#### Pool Logic Signature Template

* A stateless smart contract template
* Template variables for asset 1 id, asset 2 id, and Validator App id
* Pool contract account address retrieved by hashing the completed template
* ONLY used during pool creation (bootstrap) where it is rekeyed to the Validator App


# Audits & Security

## Audits

### Runtime Verification

Audit Report: <https://github.com/runtimeverification/publications/tree/main/reports/smart-contracts/Tinyman-amm-v2-audit>\
Blog: <https://runtimeverification.com/blog/runtime-verification-audits-tinyman-amm-v2>

## Bug Bounty Program

Tinyman has a bug bounty program for responsible disclosure of vulnerabilities in the V2 Contracts. See the Immunefi page for more details: <https://immunefi.com/bounty/tinymanv2/>

## Contact

For sensitive security issues and responsible disclosure of *contract-related bugs* please contact <security@tinyman.org>.


# TINY Token Details

TINY token is a token that will be used to facilitate voting and decision-making within the Tinyman Governance.

## Tokenomics

<table><thead><tr><th width="289">TINY Token - Allocations</th><th width="111" align="center">Share</th><th width="135" align="center">Amount</th><th>Details</th></tr></thead><tbody><tr><td>1. Investors</td><td align="center">30.65%</td><td align="center">306,500,00</td><td>10-12% upfront <br>1-year cliff <br>18-month linear vesting</td></tr><tr><td>     <em>1.1 Seed Round</em></td><td align="center">     <em>25.25%</em></td><td align="center">     <em>258,5M</em></td><td></td></tr><tr><td>     <em>1.2 Strategic Round</em></td><td align="center">     <em>4.80%</em></td><td align="center">     <em>48M</em></td><td></td></tr><tr><td>2. Tinyman Protocol</td><td align="center">34.35%</td><td align="center">343,500,000</td><td>15% upfront <br>1-year cliff <br>2-year linear vesting</td></tr><tr><td>     <em>2.1 Team and Par</em>tners</td><td align="center">     <em>14.40%</em></td><td align="center">     <em>144M</em></td><td></td></tr><tr><td>     <em>2.2 Ecosystem Support Part.</em></td><td align="center">     <em>6.95%</em></td><td align="center">     <em>69,5M</em></td><td></td></tr><tr><td>     <em>2.3 Reserve Tinyman Cont.</em></td><td align="center">     <em>13.00%</em></td><td align="center">     <em>130M</em></td><td></td></tr><tr><td>3. Community</td><td align="center">35.00%</td><td align="center">350,000,000</td><td>Airdrop<br>+<br>4-year linear vesting</td></tr><tr><td>     <em>3.1 Airdrop</em></td><td align="center">     <em>5.00%</em></td><td align="center">     <em>50M</em></td><td></td></tr><tr><td>     <em>3.2 Governance Rewards</em></td><td align="center">     <em>18.00%</em></td><td align="center">     <em>180M</em></td><td></td></tr><tr><td>     <em>3.3 Liquidity Mining Rewards</em></td><td align="center">     <em>12.00%</em></td><td align="center">     <em>120M</em></td><td></td></tr><tr><td><strong>TOTAL</strong></td><td align="center"><strong>100%</strong></td><td align="center">1,000,000,00</td><td></td></tr></tbody></table>

**TINY Token Allocations**: 1 billion TINY will be available in total and become accessible over the course of 4 years. The initial four-year allocation is as follows:

* 30.00% to Investors with 10% upfront, 1-year lock period, and 18-month linear vesting
* 15.00% to Team members with 1-year cliff and 2-year linear vesting
* 20.00% to Protocol treasury and grants with 1-year cliff and 2-year linear vesting
* 35.00% to Community members with 4-year vesting

## Distribution Details

* With the token creation event, all investors will receive a 10% upfront payment and Tinyman Treasury will receive a 15% upfront payment.
* All investors and Tinyman Treasury are subject to a one-year cliff period. During this period, stakeholders are not entitled to receive tokens. After one year, the remaining amount will be automatically distributed monthly.
  * 12 months cliff, then 18 months linear vesting for the Investors
  * 12 months cliff, then 24 months linear vesting for Tinyman Treasury
* Community will start earning TINY Rewards through 2 different channels for 4 years:
  * Governance Rewards: Users who lock their $TINYs to Tinyman Governance Vault will qualify for TINY Power. This Power will determine users to earn rewards from Governance Vault and also empower users on Governance Voting.
  * Liquidity Mining Rewards – Tinyman Governors will vote on governance proposals monthly and determine which pool will receive the most rewards that month. TINY tokens will be distributed to LPs through these Tinyman Farms.

## Token Generation Event

13.25% of the Token Supply will be in circulation on day 1. (\~132.5M $TINY)

* 30,050M – Investors (22.68% of initial allocation)
* 32,925M – Tinyman Treasury (24.85% of initial allocation)
* 69,500M – Community Airdrop (52.46% of initial allocation)

*Note: Investors or Tinyman Treasury will not be able to vest any tokens within one year of the Token Generation Event. The only way new tokens will be released into circulation for the first 12 months is through community rewards: Governance Rewards and Liquidity Mining Rewards.*

\ <br>


# Governance Details


# Overview

<figure><img src="/files/IhMwggXKbQNeeWOpHC5j" alt=""><figcaption><p>Tinyman Governance Workflow</p></figcaption></figure>

## Governance Forum

The Tinyman Governance Forum is where our community shapes the future of [Tinyman](https://tinyman.org/), embracing decentralization and effective governance. Here, every community member can propose, discuss, and evolve ideas in a structured, transparent environment.

The forum is designed as the starting point for all governance activities. You’ll begin by discussing and refining proposals with community feedback, then move these proposals through a structured process of validation and execution, which includes both forum-based discussions & voting and on-chain voting. Here’s how you can participate:

## Governance Forum Process

The forum is your first step in the governance process, where you can engage with the community to refine ideas, gather initial feedback, and join voting.

* **Proposal Discussion**: Start by posting your idea in the Governance Forum to solicit community feedback and further develop your proposal based on the discussions.
* **Proposal Submission**: After refining your proposal with community input, you can move it one step forward. This includes a more detailed version of your proposal following a specific template that outlines the goal, detailed actions, and expected outcomes.
* **Community Polling**: Proposals that achieve sufficient support in the forum through off-chain community polling (requiring at least 50 votes and over 50% approval) can move forward. For the next 3-6 months, forum polling is required before moving to the on-chain part to prevent abuse. This ensures that proposals have community backing before progressing.

## On-Chain Voting Process

* **On-Chain Submission**: Successful proposals are submitted for on-chain voting on <https://tinyman.org/#/governance/proposals>, where they undergo a structured process that includes a waiting period and a voting period. To initiate a proposal, the proposer must hold 450K $TINY Power. Proposals that do not meet the forum approval criteria will be removed from the Tinyman interface.
* **​​Waiting Period**: Once on-chain, proposals enter a waiting period (approximately 2 days) to ensure all community members are informed.
* **Voting Period**: The proposal is open for voting for 7 days, enabling all governors to participate. This on-chain process requires governors to connect their wallets to verify their positions in the governance vault. They must sign a transaction, which will be recorded on the blockchain. The influence of governors on the voting outcome is proportional to their voting power. The proposal requires at least 2.25 million "YES" votes in Tiny Power to pass.
* **Execution**: If approved, proposals are automatically executed after a 2-day timelock, integrating the changes into the Tinyman ecosystem.

This structured approach ensures thorough community involvement and the integrity of the governance process, facilitating the automation and implementation of community-driven upgrades.

\ <br>

\ <br>


# Governance Vault

## Overview

Tinyman Governance Vault is a smart contract that holds and manages the TINY tokens being staked for governance. When a user stakes their TINY tokens, they are transferred to the governance vault contract. The governance vault is responsible for managing the lockup period, participating in governance proposals, and continuous stake rewards. The longer a user stakes their tokens, the more voting power they accumulate. However, there is also a time decay factor. As the unlock period gets closer, the voting power diminishes.

<figure><img src="/files/rzxjz4RGdzCh2cgE4GmZ" alt=""><figcaption><p>Governance Vault</p></figcaption></figure>

## Locking Mechanism<br>

### Locking Duration:&#x20;

* Users will have pre-defined time period options to lock their tokens to the governance vault.
  * 1 Month = 4 Weeks (Minimum commitment)
  * 3 Months = 12 Weeks&#x20;
  * 6 Months = 24 Weeks
  * 1 Year = 52 Weeks
  * 2 Years = 104 Weeks
  * 3 Years = 156 Weeks
  * 4 Years = 208 Weeks (Maximum commitment)
* There is no withdrawal during the active lock period. When a user stakes their TINY tokens, they are locked up for the period of their choosing, which can range from 1 month to 4 years. During this time, the user's tokens cannot be transferred or sold, and they are not available for trading.
* The governance vault contract tracks the lockup period and prevents users from withdrawing their tokens before it ends.&#x20;
* Once the lockup period has ended, users can withdraw their staked TINY tokens, and they become available for trading.
* When users lock TINY tokens, they will be able to see their voting power and estimated governance rewards over time.&#x20;

### Locking Amount:

* There is a minimum limit for locking tokens to the governance vault: 10 TINY&#x20;
* There is no maximum token limit to having a commitment; it is unlimited.
* The same rule applies to updating/extending an existing commitment. Users should update their commitment with at least 10 TINY tokens.

### Extending the governance commitment:

* When users stake their TINY tokens, they are locked up for a period of time. However, they can update their commits to increase their voting power.
* There will be 3 forms of extending the commitment: (Amount x Duration)
  * Case1: Increasing the amount for the same duration
  * Case2: The same amount for a longer duration
  * Case3: Increasing the amount for a longer duration
  * E.g. Existing Commitment: 1000 TINY x 1-year
    * Case1 – Updated Amount: 2000 TINY x 1-year
    * Case2 – Updated Duration: 1000 TINY x 2-year
    * Case3 – Updated the two: 2000 TINY x 2-year
* The minimum limit for locking tokens is also valid for extending the commitment.&#x20;
* Updating the commitment is a unidirectional action, with a positive impact:
  * There is no withdrawal during the active lock period.
  * There is no decrease in the locked amount.&#x20;
  * There is no shortening of the time duration of the commitment.
* When users extend their commitment, the governance system grants them a new level of Tiny Power, increasing their share of the governance rewards and voting power in the governance process.
  * Updated Power will be valid for the upcoming governance reward cycle.
  * Additionally, the updated voting power will apply only to future governance proposals, not to any existing or active proposals.

## Tiny Power

* TINY Power, is a concept within the Tinyman Governance system. &#x20;
* It is a measure of a user's commitment to the governance process and is determined by the number of tokens committed and the duration of the commitment. (TINY Power = Committed Amount x Commitment Duration)
* The TINY Power affects the portion of governance rewards that users receive, as well as increasing their voting power in the governance process.&#x20;
* This incentivizes users to make longer commitments to the governance system, as it allows them to have a greater say in the decision-making process and receive greater rewards.
* **Formula**: TINY Power = “Committed Amount / 208 x Remaining Weeks”
  * The number of tokens to be locked directly increases TINY Power.
  * The locking duration also directly increases TINY Power.
  * As the unlock period gets closer, the TINY Power diminishes gradually.

<figure><img src="/files/sPODq36lqbhA56HAQ1G4" alt=""><figcaption><p>Tiny Power (over time)</p></figcaption></figure>

TINY Power directly affects the following:

* Voting Power in Tinyman Governance Proposal – Categories
  * Tinyman Protocol — Pools and Fee Structure
  * Tinyman Protocol — Roadmap & Features
  * $TINY Token – Rewards (Governance, Farming, etc.)
  * $TINY Token – Grants
* Voting Power in Liquidity Mining Rewards – TINY Token Farms. Governors will vote on governance proposals monthly and determine which pools will receive an allocation of $TINY rewards.
  * “ALGO/USDC”, “TINY/USDC”, “TINY/ALGO” – by default farms
  * Governors will be able to choose other pools of their choice in the ecosystem, such as Stable Pools, Lending Pools, Meme Tokens, etc.
* Rewards Multiplier in Tinyman Governance Rewards
  * Commit more TINY = More TINY Rewards (Weekly)
  * Commit with longer periods = More TINY Rewards (Weekly)

This token and governance structure aims to make Tinyman a sustainable protocol and gradually transfer ownership to the community. We believe that users and other projects will commit to the Tinyman Governance Vault for the long term, benefiting from participating in governance and shaping the protocol's future.

\ <br>

\ <br>


# Governance Rewards

* Staking TINY tokens in the governance vault allows users to earn staking rewards on an ongoing basis. (Stake $TINY, Earn $TINY)
* Longer commitments will result in higher TINY Power, which will be rewarded more.&#x20;
  * The rewards will be distributed to the governors based on their shares in locked tokens.
  * These structures are designed to encourage long-term participation in the governance process.
* There will be a fixed amount of TINY tokens allocated each week for 4 years to be distributed to governors under this initiative.&#x20;
  * 1st Year – 1000K TINY Token per Week
  * 2nd Year – 900K TINY Token per Week
  * 3rd Year – 700K TINY Token per Week
* Tokens will be unlocked in weekly cycles
  * Users will receive the rewards based on their share of total locked tokens in the Governance vault. (TINY Power)
  * Rewards are distributed daily and can be claimed on a weekly basis.
  * Governors can claim the Governance Rewards they are qualified for at any time.
* When users update their commitment in the governance vault, they will start earning staking rewards based on the new commitment from the next cycle, typically within a day.

<figure><img src="/files/1KwNWyl50tF4aFpPBSDc" alt=""><figcaption></figcaption></figure>


# Governance Process

This section will contain all parts of Tinyman Governance: Creating a Proposal, Proposal Voting, and Proposal Execution. All activities will take place on the blockchain and will require transaction signing.

## Proposal Creating

This is actually the main step of the Governance Proposal: on-chain proposal and subsequent voting. To submit an on-chain proposal, the proposer must have a minimum TINY Power to his address and must publish a Governance forum post with a summary of the earlier discussions, the poll results from the forum, the proposal itself, and the proposal’s action.

* At this stage, a Proposal Template with the following details will be provided for creating a proposal and submitting it.&#x20;
  * Title
  * Category
  * Governance Forum URL
  * Governance Forum Poll
  * Description
* Proposals must belong to one of the listed categories. The number and variety of categories will increase over time. Initial Categories:
  * Tinyman Protocol — Fee Structure
  * $TINY Token - Rewards (Governance, Farming, etc.)
  * Tinyman - Governance
  * Grants
  * Tinyman Analytics
  * Etc.
  * *Note: We will provide a proposal template and placeholders for each category.*&#x20;
* The proposal should defend something very clearly and urge the governors to agree or disagree with it. (For or Against, Yes or No, etc.)
  * There will also be a 3rd option that allows users who are undecided or dislike the proposal to veto the vote. (Veto or Abstention)
* After the proposal is submitted by the owner, Tinyman team will check its eligibility. E.g.
  * Is the Discussion Forum URL valid and includes the associated discussion.&#x20;
  * Is the Forum Poll URL valid and confirms that the early offer has been approved by the majority?
  * Is the content of the proposal convenient with the specified category?
  * etc.
  * *Note: All these rules will be clearly expressed and public in the Forum.*
* Once the moderators approve the proposal, it will be listed in the Tinyman Governance Portal. Two days before the voting starts, the proposal will be reviewed.&#x20;
* *Note: The amount or percentage of the threshold should be configurable with Governance proposals.*

## Proposal Voting

After the review process is over, everyone will have 7 days to vote. This is an on-chain process and governors have to connect their wallets to Governance Portal and validate their positions in the Governance vault. The proposal requires at least 2.25 million "YES" votes in Tiny Power to pass.

**Details**;

* Users need to sign a transaction and this transaction will be tracked/recorded on the blockchain.
* It is an irreversible activity: users vote once and it's over.
* The governors will affect the voting result as much as the voting power they have.&#x20;


# TINY Farming

The Tinyman Governance system enables voting on the distribution of $TINY as farming rewards. Tinyman Governors will vote on monthly governance proposals  and determine which pool will receive the most rewards that month. TINY tokens will be distributed to LPs through these Tinyman Farms.

<table data-header-hidden><thead><tr><th></th><th width="155"></th><th></th><th></th></tr></thead><tbody><tr><td>TINY Rewards</td><td>Share</td><td>Total Amount</td><td>Monthly Allocation</td></tr><tr><td>Year 1</td><td>27.00%</td><td>32,400,000.00</td><td>2,700,000.00</td></tr><tr><td>Year 2</td><td>24.00%</td><td>28,800,000.00</td><td>2,400,000.00</td></tr><tr><td>Year 3</td><td>21.00%</td><td>25,200,000.00</td><td>2,100,000.00</td></tr><tr><td>Year 4</td><td>18.00%</td><td>21,600,000.00</td><td>1,800,000.00</td></tr><tr><td>Later</td><td>10.00%</td><td>12,000,000.00</td><td></td></tr><tr><td>TOTAL</td><td>100.00%</td><td>120,000,000.00</td><td></td></tr></tbody></table>

### Workflow:

* Farming proposals will be listed automatically on 17th or 18th of every month. &#x20;
* Voting begins on the 20th of each month and lasts 7 days.
* During the voting period, users are presented with an interface where they can choose which pools they would like to see in farming, and users will vote based on the TINY Power they hold.
* The pools that receive the most votes (top 60 pools) from the community at the end of the duration are selected for the farming initiative with their reward allocations for the next month.

### **Rewards Distribution:**&#x20;

* Protocol Share: 20% to fixed pools (e.g. ALGO/USDC, TINY/ALGO and TINY/USDC)&#x20;
* Community Share: 80% to all pools based on community vote. (proportionally)

\ <br>


# Protocol Methods

This section describes the transaction groups for each method of the protocol.

Where more than one transaction is required they must appear in an atomic group. The exact indices within the group are not important unless specified. However, the relative positions of transactions for each method are important. The transaction order may not change and no other transactions may appear between the transactions of each method.

Where user\_address is specified the same address must be used for all instances within a method. any\_address can be any value.

{% content-ref url="/pages/ndyYpsCSMpJIfDtxB53l" %}
[Bootstrap](/v2-integration/protocol-methods/bootstrap)
{% endcontent-ref %}

{% content-ref url="/pages/zWVGS6XaWy5jIg9Nq98W" %}
[Add Initial Liquidity](/v2-integration/protocol-methods/add-initial-liquidity)
{% endcontent-ref %}

{% content-ref url="/pages/eVfHvJDYukcSWUMBJlci" %}
[Add Subsequent Liquidity](/v2-integration/protocol-methods/add-subsequent-liquidity)
{% endcontent-ref %}

{% content-ref url="/pages/QgMlcr5nD13sERf5aZtG" %}
[Remove Liquidity](/v2-integration/protocol-methods/remove-liquidity)
{% endcontent-ref %}

{% content-ref url="/pages/chdMmFTDopXD6Al1IKHd" %}
[Swap](/v2-integration/protocol-methods/swap)
{% endcontent-ref %}

{% content-ref url="/pages/PE8p4ctw5ZMCurkRWXOr" %}
[Flash Loan](/v2-integration/protocol-methods/flash-loan)
{% endcontent-ref %}

{% content-ref url="/pages/Hh0Zw8IqAF1aYryptkTy" %}
[Flash Swap](/v2-integration/protocol-methods/flash-swap)
{% endcontent-ref %}

{% content-ref url="/pages/QEnxPyDyBrPYQyg7zbob" %}
[State Data](/v2-integration/state-data)
{% endcontent-ref %}

{% content-ref url="/pages/E7Qx06KdjUmOZfIWyBUx" %}
[Oracle Data](/v2-integration/oracle-data)
{% endcontent-ref %}


# Bootstrap

### **Transactions**

**Pay:**

Sender: any\_address\
Receiver: pool\_address\
Amount:\
Pool minimum balance ([Formula I](https://docs.tinyman.org/v2-integration/protocol-methods/pages/RArypJMatkCdksZvFhuW#i.-pool-minimum-balance))\
\+ Transaction fee of the app call\
\+ 100000 (min transaction fee for asset creation)

**AppCall:**

Sender: pool\_address (Logic Sig)\
Index: tinyman\_amm\_v2\_app\_id\
OnComplete: OptIn\
App Args: \[“bootstrap”]\
Foreign Assets: \[asset\_1\_id, asset\_2\_id]\
RekeyTo: tinyman\_amm\_v2\_app\_address\
Fee: (7 \* min\_fee) (Note: 6 \* min\_fee if asset 2 is Algo)

### **Side Effects**

#### **Local State Changes**

1. pool\_token\_asset\_id
2. asset\_1\_id
3. asset\_2\_id
4. total\_fee\_share
5. protocol\_fee\_ratio
6. asset\_1\_reserves
7. asset\_2\_reserves
8. issued\_pool\_tokens
9. asset\_1\_protocol\_fees
10. asset\_2\_protocol\_fees
11. lock
12. asset\_1\_cumulative\_price
13. asset\_2\_cumulative\_price
14. cumulative\_price\_update\_timestamp

#### **Inner Transactions**

**1. Pay:**

Sender: pool\_address\
Receiver: tinyman\_amm\_v2\_app\_address\
Amount: 100\_000\
Fee: 0

**2. AssetConfig:**

Sender: tinyman\_amm\_v2\_app\_address\
UnitName: “TMPOOL2”\
Name: “TinymanPool2.0 {asset\_1\_unit\_name}-{asset\_2\_unit\_name}”\
MetadataHash: “{asset\_1\_id}{asset\_2\_id}{trailing zeros}”\
uint64 (8 bytes) + uint64 (8 bytes) + zeros (16 bytes)\
Total: 18446744073709551615\
Reserve: pool\_address\
Decimals: 6\
URL: “<https://tinyman.org>”\
Fee: 0

**3. AssetTransfer (Opt-In):**

Sender: pool\_address\
Receiver: pool\_address\
Index: asset\_1\_id\
Amount: 0

**4. AssetTransfer (Opt-In) (If Asset 2 is not Algo):**

Sender: pool\_address\
Receiver: pool\_address\
Index: asset\_2\_id\
Amount: 0

**5. AssetTransfer (Opt-In):**

Sender: pool\_address\
Receiver: pool\_address\
Index: created\_asset\_id\
Amount: 0

**6. AssetTransfer:**

Sender: tinyman\_amm\_v2\_app\_address\
Receiver: pool\_address\
Index: created\_asset\_id\
Amount: 18446744073709551615


# Add Initial Liquidity

### **Transactions**

**1. AssetTransfer:**

Sender: user\_address\
Receiver: pool\_address\
Index: asset\_1\_id\
Amount: asset\_1\_amount

**2. AssetTransfer/Pay:**

Sender: user\_address\
Receiver: pool\_address\
Index: asset\_2\_id\
Amount: asset\_2\_amount

**3. AppCall:**

Sender: user\_address\
Index: tinyman\_amm\_v2\_app\_id\
OnComplete: NoOp\
App Args: \[“add\_initial\_liquidity”]\
Foreign Assets: \[pool\_token\_asset\_id]\
Accounts: \[pool\_address]\
Fee: (2 \* min\_fee)

### **Side Effects**

#### **Local State Changes**

1. asset\_1\_reserves
2. asset\_2\_reserves
3. issued\_pool\_tokens

#### **Inner Transactions**

**1. AssetTransfer:**

Sender: pool\_address\
Receiver: user\_address\
Index: pool\_token\_asset\_id\
Amount: (See formula [II.A](https://docs.tinyman.org/v2-integration/protocol-methods/pages/RArypJMatkCdksZvFhuW#a.-adding-initial-liquidity) for pool token calculation)


# Add Subsequent Liquidity

## A. **Flexible**

### **Transactions**

**1. AssetTransfer:**

Sender: user\_address\
Receiver: pool\_address\
Index: asset\_1\_id\
Amount: asset\_1\_amount

**2. AssetTransfer/Pay:**

Sender: user\_address;\
Receiver: pool\_address\
Index: asset\_2\_id\
Amount: asset\_2\_amount

**3. AppCall:**

Sender: user\_address\
Index: tinyman\_amm\_v2\_app\_id\
OnComplete: NoOp\
App Args: \[“add\_liquidity”, “flexible”, min\_output]\
Foreign Assets: \[pool\_token\_asset\_id]\
Accounts: \[pool\_address]\
Fee: (3 \* min\_fee)

### **Side Effects**

#### **Local State Changes**

1. asset\_1\_reserves
2. asset\_2\_reserves
3. issued\_pool\_tokens
4. asset\_1\_protocol\_fees
5. asset\_2\_protocol\_fees
6. asset\_1\_cumulative\_price
7. asset\_2\_cumulative\_price
8. cumulative\_price\_update\_timestamp

#### **Logs**

1. input\_asset\_id
2. output\_asset\_id
3. swap\_amount
4. poolers\_fee\_amount
5. protocol\_fee\_amount
6. total\_fee\_amount

#### **Inner Transactions**

**1. App Call (to increase op code budget):**

It is for increasing the opcode (computational) [budget](https://developer.algorand.org/docs/get-details/dapps/avm/teal/?from_query=opcode%20budged#dynamic-operational-cost-of-teal-opcodes) which is required for internal swap calculations.

**2. AssetTransfer:**

Sender: pool\_address\
Receiver: user\_address\
Index: pool\_token\_asset\_id\
Amount: (See formula [II.B](https://docs.tinyman.org/v2-integration/protocol-methods/pages/RArypJMatkCdksZvFhuW#b.-adding-subsequent-liquidity) for pool token calculation)

## B. Single Asset

### **Transactions**

**1. AssetTransfer/Pay:**

Sender: user\_address\
Receiver: pool\_address\
Index: asset\_id\
Amount: asset\_amount

**2.AppCall:**

Sender: user\_address\
Index: tinyman\_amm\_v2\_app\_id\
OnComplete: NoOp

### **Side Effects**

#### **Local State Changes**

1. asset\_1\_reserves
2. asset\_2\_reserves
3. issued\_pool\_tokens
4. asset\_1\_protocol\_fees
5. asset\_2\_protocol\_fees
6. asset\_1\_cumulative\_price
7. asset\_2\_cumulative\_price
8. cumulative\_price\_update\_timestamp

#### **Logs**

1. input\_asset\_id
2. output\_asset\_id
3. swap\_amount
4. poolers\_fee\_amount
5. protocol\_fee\_amount
6. total\_fee\_amount

#### **Inner Transactions**

**1. App Call (to increase op code budget):**

It is for increasing the opcode (computational) [budget](https://developer.algorand.org/docs/get-details/dapps/avm/teal/?from_query=opcode%20budged#dynamic-operational-cost-of-teal-opcodes) which is required for internal swap calculations.

**2. AssetTransfer:**

Sender: pool\_address\
Receiver: user\_address\
Index: pool\_token\_asset\_id\
Amount: (See formula [II.B](https://docs.tinyman.org/v2-integration/protocol-methods/pages/RArypJMatkCdksZvFhuW#b.-adding-subsequent-liquidity) for pool token calculation)


# Remove Liquidity

## A. Multiple Assets Out

### **Transactions**

**1. AssetTransfer:**

Sender: user\_address\
Receiver: pool\_address\
Index: pool\_token\_asset\_id\
Amount: pool\_token\_asset\_amount

**2. AppCall:**

Sender: user\_address\
Index: tinyman\_amm\_v2\_app\_id\
OnComplete: NoOp\
App Args: \[“remove\_liquidity”, min\_asset\_1\_out, min\_asset\_2\_out]\
Foreign Assets: \[asset\_1\_id, asset\_2\_id]\
Accounts: \[pool\_address]\
Fee: (3 \* min\_fee)

### **Side Effects**

#### **Local State Changes**

1. asset\_1\_reserves
2. asset\_2\_reserves
3. issued\_pool\_tokens
4. asset\_1\_protocol\_fees
5. asset\_2\_protocol\_fees
6. asset\_1\_cumulative\_price
7. asset\_2\_cumulative\_price
8. cumulative\_price\_update\_timestamp

#### **Inner Transactions**

**1. AssetTransfer:**

Sender: pool\_address\
Receiver: user\_address\
Index: asset\_1\_id\
Amount: (See formula [III.A](https://docs.tinyman.org/v2-integration/protocol-methods/pages/RArypJMatkCdksZvFhuW#a.-multiple-asset-out))

**2. AssetTransfer/Pay:**

Sender: pool\_address\
Receiver: user\_address\
Index: asset\_2\_id\
Amount: (See formula [III.A](https://docs.tinyman.org/v2-integration/protocol-methods/pages/RArypJMatkCdksZvFhuW#a.-multiple-asset-out))

## B. Single Asset Out

### **Transactions**

**1. AssetTransfer:**

Sender: user\_address\
Receiver: pool\_address\
Index: pool\_token\_asset\_id\
Amount: pool\_token\_asset\_amount

**2. AppCall:**

Sender: user\_address\
Index: tinyman\_amm\_v2\_app\_id\
OnComplete: NoOp\
App Args: \[“remove\_liquidity”, min\_asset\_1\_out, min\_asset\_2\_out]\
Foreign Assets: \[output\_asset\_id]\
Accounts: \[pool\_address]\
Fee: (3 \* min\_fee)

### **Side Effects**

#### **Local State Changes**

1. asset\_1\_reserves
2. asset\_2\_reserves
3. issued\_pool\_tokens
4. asset\_1\_protocol\_fees
5. asset\_2\_protocol\_fees
6. asset\_1\_cumulative\_price
7. asset\_2\_cumulative\_price
8. cumulative\_price\_update\_timestamp

#### **Logs**

1. input\_asset\_id
2. input\_amount
3. swap\_amount
4. output\_asset\_id
5. output\_amount
6. poolers\_fee\_amount
7. protocol\_fee\_amount
8. total\_fee\_amount

#### **Inner Transactions**

**1. App Call (to increase op code budget):**

It is for increasing the opcode (computational) [budget](https://developer.algorand.org/docs/get-details/dapps/avm/teal/?from_query=opcode%20budged#dynamic-operational-cost-of-teal-opcodes) which is required for internal swap calculations.

**2. AssetTransfer/Pay:**

Sender: pool\_address\
Receiver: user\_address\
Index: output\_asset\_id\
Amount: (See formula [III.B](https://docs.tinyman.org/v2-integration/protocol-methods/pages/RArypJMatkCdksZvFhuW#b.-single-asset-out))


# Swap

### **Transactions**

**1. AssetTransfer/Pay (Input):**

Sender: user\_address\
Receiver: pool\_address\
Index: asset\_1\_id or asset\_2\_id\
Amount: input\_amount

**2. AppCall:**

**a. Mode: Fixed Input**

Sender: user\_address\
Index: tinyman\_amm\_v2\_app\_id\
OnComplete: NoOp\
App Args: \[“swap”,  “fixed-input”, min\_output\_amount]\
Foreign Assets: \[asset\_1\_id, asset\_2\_id]\
Accounts: \[pool\_address]\
Fee: (2 \* min\_fee)

**b. Mode: Fixed Output**

Sender: user\_address\
Index: tinyman\_amm\_v2\_app\_id\
OnComplete: NoOp\
App Args: \[“swap”, “fixed-output”, output\_amount]\
Foreign Assets: \[asset\_1\_id, asset\_2\_id]\
Accounts: \[pool\_address]\
Fee: (3 \* min\_fee)

### **Side Effects**

#### **Local State Changes**

1. asset\_1\_reserves
2. asset\_2\_reserves
3. asset\_1\_protocol\_fees
4. asset\_2\_protocol\_fees
5. asset\_1\_cumulative\_price
6. asset\_2\_cumulative\_price
7. cumulative\_price\_update\_timestamp

#### **Logs**

1. input\_asset\_id
2. input\_amount
3. swap\_amount
4. change
5. output\_asset\_id
6. output\_amount
7. poolers\_fee\_amount
8. protocol\_fee\_amount
9. total\_fee\_amount

#### **Inner Transactions**

**1. AssetTransfer/Pay (Change):**\
***Change is possible, if the swap mode is fixed-output.***\
***This transaction is issued, If there is a change.***

Sender: pool\_address\
Receiver: user\_address\
Index: input\_asset\_id\
Amount: (See formula [IV.B](https://docs.tinyman.org/v2-integration/protocol-methods/pages/RArypJMatkCdksZvFhuW#b.-fixed-output))

**2. AssetTransfer/Pay (Output)**

Sender: pool\_address\
Receiver: user\_address\
Index: output\_asset\_id\
Amount: (See formula [IV](https://docs.tinyman.org/v2-integration/protocol-methods/pages/RArypJMatkCdksZvFhuW#iv.-swapping))


# Flash Loan

### **Transactions**

**1. AppCall:**

Sender: user\_address\
Index: tinyman\_amm\_v2\_app\_id\
OnComplete: NoOp\
App Args: \[“flash\_loan”, index\_diff, asset\_1\_amount, asset\_2\_amount]\
Foreign Assets: \[asset\_1\_id, asset\_2\_id]\
Accounts: \[pool\_address]\
Fee: (3 \* min\_fee)

**2. AppCall** *(Group Index: index of flash loan call + index diff specified in the arguments):*

Sender: user\_address\
Index: tinyman\_amm\_v2\_app\_id\
OnComplete: NoOp\
App Args: \[“verifiy\_flash\_loan”, index\_diff]\
Foreign Assets: \[]\
Accounts: \[pool\_address]\
Fee: min\_fee

### **Side Effects**

1\. Flash Loan

#### **Local State Changes**

1. asset\_1\_cumulative\_price
2. asset\_2\_cumulative\_price
3. cumulative\_price\_update\_timestamp

**Inner Transactions**

**1. AssetTransfer (If asset 1 amount is not 0):**

Sender: pool\_address\
Receiver: user\_address\
Index: asset\_1\_id\
Amount: asset\_1\_amount

**2. AssetTransfer/Pay (If asset 2 amount is not 0):**

Sender: pool\_address\
Receiver: user\_address\
Index: asset\_2\_id\
Amount: asset\_2\_amount

2\. Verify Flash Loan

#### **Local State Changes**

1. asset\_1\_reserves
2. asset\_2\_reserves
3. asset\_1\_protocol\_fees
4. asset\_2\_protocol\_fees

#### **Logs**

1. asset\_1\_output\_amount
2. asset\_1\_input\_amount
3. asset\_1\_donation\_amount
4. asset\_1\_poolers\_fee\_amount
5. asset\_1\_protocol\_fee\_amount
6. asset\_1\_total\_fee\_amount
7. asset\_2\_output\_amount
8. asset\_2\_input\_amount
9. asset\_2\_donation\_amount
10. asset\_2\_poolers\_fee\_amount
11. asset\_2\_protocol\_fee\_amount
12. asset\_2\_total\_fee\_amount


# Flash Swap

### **Transactions**

**1. AppCall:**

Sender: user\_address\
Index: tinyman\_amm\_v2\_app\_id\
OnComplete: NoOp\
App Args: \[“flash\_swap”, index\_diff, asset\_1\_amount, asset\_2\_amount]\
Foreign Assets: \[asset\_1\_id, asset\_2\_id]\
Accounts: \[pool\_address]\
Fee: (3 \* min\_fee)

**2. AppCall** *(Group Index: index of flash swap call + index diff specified in the arguments):*

Sender: user\_address\
Index: tinyman\_amm\_v2\_app\_id\
OnComplete: NoOp\
App Args: \[“verifiy\_flash\_swap”, index\_diff]\
Foreign Assets: \[asset\_1\_id, asset\_2\_id]\
Accounts: \[pool\_address]\
Fee: min\_fee

#### **Side Effects**

1. Flash Swap

#### **Local State Changes**

1. lock
2. asset\_1\_cumulative\_price
3. asset\_2\_cumulative\_price
4. cumulative\_price\_update\_timestamp

**Logs**

To able to share data between app calls, these logs are added:

1. asset\_1\_balance\_after\_transfer
2. asset\_2\_balance\_after\_transfer

#### **Inner Transactions**

**1. AssetTransfer (If asset 1 amount is not 0):**

Sender: pool\_address\
Receiver: user\_address\
Index: asset\_1\_id\
Amount: asset\_1\_amount

**2. AssetTransfer/Pay (If asset 2 amount is not 0):**

Sender: pool\_address\
Receiver: user\_address\
Index: asset\_2\_id\
Amount: asset\_2\_amount

2\. Verify Flash Swap

**Local State Changes**

1. lock
2. asset\_1\_reserves
3. asset\_2\_reserves
4. asset\_1\_protocol\_fees
5. asset\_2\_protocol\_fees

**Logs**

1. asset\_1\_output\_amount
2. asset\_1\_input\_amount
3. asset\_1\_poolers\_fee\_amount
4. asset\_1\_protocol\_fee\_amount
5. asset\_1\_total\_fee\_amount
6. asset\_2\_output\_amount
7. asset\_2\_input\_amount
8. asset\_2\_poolers\_fee\_amount
9. asset\_2\_protocol\_fee\_amount
10. asset\_2\_total\_fee\_amount


# State Data

#### Global State

1. fee\_setter (bytes)
2. fee\_collector (bytes)
3. fee\_manager (bytes)

#### Local State (Pool)

1. pool\_token\_asset\_id (uint)
2. asset\_1\_id (uint)
3. asset\_2\_id (uint)
4. total\_fee\_share (uint)
5. protocol\_fee\_ratio (uint)
6. asset\_1\_reserves (uint)
7. asset\_2\_reserves (uint)
8. issued\_pool\_tokens (uint)
9. asset\_1\_protocol\_fees (uint)
10. asset\_2\_protocol\_fees (uint)
11. lock (uint)
12. asset\_1\_cumulative\_price (bytes)
13. asset\_2\_cumulative\_price (bytes)
14. cumulative\_price\_update\_timestamp (uint)


# Oracle Data

The protocol computes and stores some data which can be consumed by external contracts to create TWAP price oracles for pools.  The oracle related data of the pool is updated with any operation which may change the price. It is updated at most once in a block. The first operation of the pool in that block updates the oracle data before any changes are made to the pool ratio.

Pools have 3 oracle related fields in their local state:

1. asset\_1\_cumulative\_price (bytes)
2. asset\_2\_cumulative\_price (bytes)
3. cumulative\_price\_update\_timestamp (uint)

Cumulative price fields are scaled by 2^64 to provide more precision. In the bootstrap operation \`asset\_1\_cumulative\_price\` and \`asset\_2\_cumulative\_price\` are set to zero and \`cumulative\_price\_update\_timestamp\` is set to the latest block timestamp.

time\_delta = (latest block timestamp) - (cumulative price update timestamp)

asset\_1\_cumulative\_price = asset\_1\_cumulative\_price + ((asset\_2\_reserves \* 2^64) \* time\_delta) / (asset\_1\_reserves)

asset\_2\_cumulative\_price =asset\_2\_cumulative\_price + ((asset\_1\_reserves \* 2^64) \* time\_delta) / (asset\_2\_reserves)

cumulative\_price\_update\_timestamp = latest block timestamp

The cumulative price fields accumulate uint128 values represented as bytes. Even if these values accumulate until the final possible block (max uint64 value) then the total cumulative price will never exceed a uint192 or 24 bytes. For this reason, these values do not overflow or wrap around.


# Calculating Quotes

Calculating quotes for swaps and other operations requires knowledge of the current pool state including fee parameters, reserves, issued protocol tokens, etc. This information can be retrieved from the local state of the Tinyman app in the pool account. It is important to use fresh state data when calculating quotes as pool ratios and prices can change quickly.

## Swap

### **Fixed Input**

See [Formula IV.A](https://docs.tinyman.org/v2-integration/pages/RArypJMatkCdksZvFhuW#a.-fixed-input)

Fixed Input Swap from asset 1 to asset 2

total\_fee = (input\_amount \* state\["total\_fee\_share"]) / 10000\
swap\_amount = input\_amount - total\_fee\
k = state\["asset\_1\_reserves"] \* state\["asset\_2\_reserves"]\
swap\_output = state\["asset\_2\_reserves"] - (floor(k / (state\["asset\_1\_reserves"] + swap\_amount)) + 1)

Allowing for a slippage of 1%, min\_output\_amount should be set as swap\_output \* 0.99

### **Fixed Output**

See[ Formula IV.B](https://docs.tinyman.org/v2-integration/pages/RArypJMatkCdksZvFhuW#b.-fixed-output)

Fixed Output Swap from asset 1 to asset 2

k = state\["asset\_1\_reserves"] \* state\["asset\_2\_reserves"]\
swap\_amount = (floor(k / (state\["asset\_2\_reserves"] - output\_amount)) + 1) - state\["asset\_1\_reserves"]\
input\_amount = floor((swap\_amount \* 10000) / (10000 - state\["total\_fee\_share"]))

Allowing for a slippage of 1%, input\_amount should be set as input\_amount \* 1.01


# Official SDKs

These are SDKs started and maintained by the Tinyman core development team.

{% hint style="warning" %}
Please note the [Disclaimer](/disclaimer) applies to these SDKs. Please review the Disclaimer and the Licenses of the individual SDKs. No warranty of any kind is provided for this software.&#x20;

Please review the code of each release carefully and do your own research before interacting with Algorand Mainnet using this software.
{% endhint %}

### Python SDK

{% embed url="<https://github.com/tinymanorg/tinyman-py-sdk>" %}

### JavaScript SDK

{% embed url="<https://github.com/tinymanorg/tinyman-js-sdk/tree/main>" %}

Please join us on [Discord](https://discord.gg/xJRKueQdrG) technical channels to give feedback and ask questions.


# Swap Router

Tinyman Swap Router is an application that relies on both on-chain and off-chain components to offer better prices for traders in the Tinyman protocol. It is developed by the Tinyman team and aims to maximize the amount of assets users will get when trading. In the normal swap function, a swap is always executed through a single pool in Tinyman. However, the Swap Router checks multiple pools and alternative routes to find the best exchange rate in order to provide better prices using a single transaction.&#x20;

E.g., The equivalent value of the output asset for a swap:

* Normal Swap: The exchange rate of the single pool minus a related transaction fee
* Swap by Swap Router: Exchange rates of multiple pools, subtracting all related transaction fees (swapping assets between multiple pools).

Using a Swap Router can result in higher transaction fees, as it must pay fees to multiple liquidity pools to execute the swap. Nevertheless, Swap Router aims to offer a better output amount using multi-hop swaps by taking those fees into account. The Swap Router is primarily useful when there is insufficient liquidity in a single pool to complete a swap at an optimal exchange rate. There is a common situation of deep liquidity ASA-Algo pools but low liquidity ASA-ASA pools on Tinyman. Using the route of ASA-ALGO-ASA can potentially provide a better exchange rate and lower price impacts compared to using a single pool, resulting in a better swap experience for the user.&#x20;

## Methodology

From a technical standpoint, using the Swap Router is essentially equivalent to executing the Normal Swap function multiple times. These swaps are being executed on the backend and on the chain without any additional steps required on the part of the user. So, the overall swap experience is vastly improved, and the user experience is still smooth. Since all of the resulting transactions are grouped by Swap Router into a single operation, it does not have any adverse effects or risks for the users. Additionally, the Swap Router feature is optional, and users can choose to enable or disable it.

Rather than trading on a single pool, the Swap router checks the single-hop routers for two assets and suggests a path that provides the best swap rate: higher output or lower input. If the swap amount is relatively high, the router tends to suggest a route with high liquidity and low price impact.&#x20;

E.g. Swap Asset-1 for Asset-2

* Option-1: Asset-1 / Asset-2 Tinyman v1 pool
* Option-2: Asset-1 / Asset-2 Tinyman v2 pool
* Option-3: Asset-1 / ASA-A and ASA-A / Asset-2 v2 pools (best output amount)
* Option-4: Asset-1 / ASA-B and ASA-B / Asset-2 v2 pools
* Option-5: ...

All these calculations and suggestions are powered by Tinyman API, and it always proposes the best option and benefits to the users. When users do not prefer to use the Swap Router, or it is not available for some reason, swaps will be executed in Tinyman v1 or v2 pools as Normal Swap.

These are the number of transactions for each swap type. Swap Router includes all these fees in the overall calculation and takes them into account when suggesting a route.&#x20;

* Normal Swap - Fixed Input: 3
* Normal Swap - Fixed Output: 4
* Swap Router - Fixed Input: 9&#x20;
* Swap Router - Fixed Output: 10

[Swap Router App Contract](https://github.com/tinymanorg/tinyman-periphery-contracts-v2)

[Tinyman Python SDK](https://github.com/tinymanorg/tinyman-py-sdk)


# Transaction Specification

### Asset Opt-in **Transactions**

**1. AppCall:** \
Sender: user\_address\
Index: router\_app\_id\
OnComplete: NoOp\
App Args: \[“asset\_opt\_in”]\
Foreign Assets: \[asset\_1\_id, asset\_2\_id, ….., asset\_n\_id]\
Fee: min\_fee \* (1 + number of assets)

### **Swap Transactions**

**1. AssetTransfer/Pay (Input):**

Sender: user\_address\
Receiver: pool\_address\
Index: asset\_1\_id or asset\_2\_id\
Amount: input\_amount

**2. AppCall:**

**a. Mode: Fixed Input**

Sender: user\_address\
Index: router\_app\_id\
OnComplete: NoOp\
App Args: \[“swap”, “fixed-input”, min\_output\_amount]\
Foreign Assets: \[asset\_in\_id, asset\_intermediary\_id, asset\_out\_id]\
Accounts: \[pool\_1\_address, pool\_2\_address]\
Foreign Apps: \[amm\_app\_id]\
Fee: (8 \* min\_fee)

**b. Mode: Fixed Output**

Sender: user\_address\
Index: router\_app\_id On\
Complete: NoOp\
App Args: \[“swap”, “fixed-output”, output\_amount]\
Foreign Assets: \[asset\_in\_id, asset\_intermediary\_id, asset\_out\_id]\
Accounts: \[pool\_1\_address, pool\_2\_address]\
Foreign Apps: \[amm\_app\_id]\
Fee: (9 \* min\_fee)


# Swap Widget

Tinyman Swap Widget aims to enable any project to integrate Tinyman Swap functionality into their applications easily and quickly. It is developed and maintained by the Tinyman core development team.

[Swap Widget](https://widget.tinyman.org) allows users to make swaps inside the main application (without switching the app) using the Tinyman pool seamlessly and securely. Tinyman Swap Router will ensure that users can make swaps at the best price, similar to the Tinyman Web Application.

<figure><img src="/files/CDrOCDxCjhQnzenpczyI" alt="" width="375"><figcaption><p>Swap Widget Example</p></figcaption></figure>

This document includes implementation details and helps you to integrate the Swap Widget into your app.&#x20;

[Customization Preferences](/swap-widget/customization-preferences)

[How to export your Widget](/swap-widget/how-to-export-your-widget)


# Customization Preferences

You can use our official configuration page to customize the widget and export the parameters for integration.

### Swap Widget - Configuration Page: <https://widget.tinyman.org>

### Swap Settings

1. **Swap Assets** - Set swap input and output assets by entering ASA IDs.
2. **Platform Name** - Specify the application name, which the swap widget will be integrated to.
3. **Service Fee \[Optional]** - Tinyman Swap Widget allows projects to cut extra fees from each swap. To be able to use this feature, you should enable it, set a fee percentage, and enter the wallet address you want to receive service fees. (Maximum Fee rate is 5%)

&#x20;       **Note**: Please ensure this address is opted into the swap input and output assets you specified.

<figure><img src="/files/bfCoITB2qp0jKHqJCBAr" alt=""><figcaption><p>Swap Settings</p></figcaption></figure>

### Styling

You can modify the color palette and appearance of your Widget.&#x20;

1. **Widget container** (Widget background, iframe background, header title, etc.)
2. **Swap container** (Dark/Light theme, button background, button text, etc.)
3. **Custom title**
4. **Border radius** (Large, Medium, Small, None)

<figure><img src="/files/JajQZVWhtsf3fplbcofC" alt=""><figcaption><p>Styling</p></figcaption></figure>

\ <br>


# How to export your Widget

There are two main ways of handling transaction signing: Local Signer and Parent Signer.

It is controlled by the "Use wallet connection inside the widget - Local Signer" switch on the export page. This choice determines the implementation method;

### 1. Local Signer

Local Signer, is an option with a separate session within the Widget for those looking for simplified implementation. The widget handles the wallet connection and the transaction signing.

### Steps

1. Configure the widget according to your preferences.
2. Copy the iframe embed code.
3. Paste the code in your application code.
4. That’s it!

### 2. Parent Signer:&#x20;

Parent Signer, is a more advanced option and aims to use the existing Parent App's session; it does not need a separate session for the users. If you want to use your existing wallet connection in the widget, you need to install our JS SDK for easy integration.

### Steps

1. First, install the SDK with npm:&#x20;

```
npm install @tinymanorg/tinyman-swap-widget-sdk
```

2. (optional) To get the function parameters easily, you can copy the `Parameters Object` on the export page.&#x20;
3. Then, you should use `generateIframeUrl` to generate the iframe URL, for example:

```
const widgetIframeUrl = WidgetController.generateWidgetIframeUrl({
  platformName: "Platform name",
  // should be `true` if you will use your own wallet
  useParentSigner: true,
  // :exclamation:update `accountAddress` value with the real value of the connected account address
  accountAddress: "ADDRESS_OF_SIGNER_ACCOUNT",
  network: "testnet", // "testnet" or "mainnet"
  themeVariables: {
    shouldDisplayTinymanLogo: true
    // you can customize more styles, please refer to configuration page
  },
  parentUrlOrigin: window.location.origin, // or your app url origin e.g. "https://myapp.com"
  assetIds: [0, 10458941]
});
```

4. Use this URL to add the iframe element to your page:

```
<iframe title="tinyman swap widget"
src=`${widgetIframeUrl}`
style="width: 415px; height: 440px; border: none;"
sandbox="allow-same-origin allow-scripts allow-popups allow-forms"
/>
```

5. Now you should be able to see the widget on your page, but still, you need to establish communication between the application and the widget. We use the `postMessage` API for this. Create an instance of `WidgetController` and set up event listeners with your own callbacks. This way, your application will get a message when the widget needs a signature on a transaction, or when there is an error. And you can send the transaction back to the widget after it’s signed.&#x20;

Please follow our quick start guide here: <https://github.com/tinymanorg/tinyman-swap-widget-sdk#quick-start>


# Lending Pools

Lending Pools - An innovative solution developed through the partnership of FolksFinance and Tinyman tailored for the Algorand ecosystem.

Lending Pools are designed to enhance the potential of your assets by integrating the mechanisms of DEXs and Lending platforms.

### Features of Tinyman Lending Pools:

* **Dual Yield**: Enjoy the benefits of accruing yield from both Folks Finance's lending protocol and Tinyman's liquidity pools simultaneously, e.g. Earn interest on ALGO and USDC deposits through Folks Finance.
* **DEX Pools**: Our pools are uniquely composed of interest-bearing assets, amplifying the utility of your deposits. Receive swap fees from the liquidity provided in the Tinyman DEX pool.
* **Asset Utilization**: With Tinyman's Lending Pools, your assets work harder, ensuring higher capital efficiency.

This synergy results in deeper liquidity, an increased Total Value Locked (TVL), and amplified yields.

### Getting Started with Tinyman Lending Pools:

1. Visit Tinyman UI – [Lending Pools ](https://app.tinyman.org/#/pool/all-pools?onlyVerified=true\&onlyLending=true)
2. Select the Lending Pool that you want to invest in.&#x20;
3. Click “Add Liquidity” to choose the amount for providing liquidity.
4. Now, you need to specify the amounts for Lending Pools:
   1. 1st, your assets will be deposited into the Folks Finance Lending Protocol
   2. 2nd, the fAssets representing your Lending Position will be added to respective Lending Pools in Tinyman.
5. So you can participate in the Lending Protocol and Pools with just one click and earn dual yields!

Ref: [Folks Finance - Lending Pools](https://www.youtube.com/watch?v=Lo9y-5Ir5Fc\&embeds_referring_euri=https%3A%2F%2Fcdn.iframe.ly%2F\&source_ve_path=MjM4NTE\&feature=emb_title)

### Special Note on Lending Assets in Tinyman Lending Pools:

When participating in Tinyman's Lending Pools, it's important to be aware of the specific assets used for lending purposes. These assets typically have names beginning with "f-", signifying their function as Folks Finance integrated assets. For example:

* **fALGO**: Represents ALGO deposited in Folks Finance, used for earning interest in lending pools.
* **fwBTC**: Represents wrapped Bitcoin (wBTC) in the Folks Finance lending ecosystem.

These "f-" prefixed assets are central to the operation of Lending Pools, allowing users to seamlessly earn interest on their deposits through Folks Finance, while simultaneously participating in liquidity pools on Tinyman.\ <br>


# Trigger Orders & Recurring Orders&#x20;

### Overview

Tinyman is introducing two powerful trading features on its decentralized exchange: Trigger Orders (Limit Orders) and Recurring Orders (DCA). These tools allow users to trade more strategically, automate purchases, and stay fully in control — all with the speed, security, and transparency of the Algorand blockchain.

### 1. Trigger Orders

#### Description

A Trigger Order (also known as Limit Order) lets users buy or sell a token at a specific price. The trade will only execute if the market reaches the price set by the user, within a timeframe they choose.

#### Benefits

* Set your preferred price for buy/sell orders
* Trade passively and strategically
* Avoid constant price monitoring
* Maintain full custody of funds at all times

#### Expiration Options

Users can choose when the order should expire:

* Never
* After 10 minutes
* After 1 hour
* After 1 day
* After 3 days
* After 7 days
* After 30 days

If the price condition is not met before the expiration, the order is canceled and the funds are returned to the user’s wallet.

#### Minimum Trade Amount

* $5 USD equivalent per order

#### Fees

* A 0.15% fee is charged when a Trigger Order is successfully executed.
* TINY governors enjoy a discounted fee of 0,1%. In order to be eligible, TINY governors need to hold a TINY power of at least 5000

#### Execution Flow

* When a user places a Trigger Order, the funds are locked into a dedicated smart contract.
* If the price target is reached, the order is executed and tokens are sent directly to the user’s wallet.
* If canceled or expired, the original funds are returned.
* Partial fills: If only part of the order is filled, the user will be able to claim the completed portion at a later stage (feature coming soon).
* Users can cancel the order at any time and funds will be returned to their wallet.

#### Example Use Case

A user places a Trigger Order to buy ALGO at $0.16, set to expire in 1 day.\
They commit $25 to the order, meeting the $5 minimum.\
If ALGO reaches $0.16 within 24 hours, the order executes automatically.\
If not, it expires and the $25 is returned.

### 2. Recurring Orders (DCA)

#### Description

A Recurring Order (also known as Dollar Cost Averaging) allows users to automate regular purchases of a token at predefined intervals. This strategy is especially useful for long-term accumulation and reducing exposure to short-term volatility.

#### Benefits

* Automate recurring token buys
* Reduce impact of market volatility
* Ideal for long-term investors
* Fully non-custodial and on-chain

#### Configuration Options

Users can define:

* Interval between orders:
  * Every minute
  * Every hour
  * Every day
  * Every week
  * Every month
* Number of executions (e.g., 5 purchases over 5 days)
* Price range (optional):
  * Users can specify a price range within which the recurring orders are allowed to execute.
  * This ensures that purchases are only made when the asset price is within a target zone, adding an extra layer of strategy.

#### Minimum Order Amount

* Each recurring execution must be at least $5 USD
* The total recurring order value must be at least $10 USD
* Example: If a user wants to schedule 5 recurring orders, they must commit at least $25 (5 x $5)

#### Fees

* A 0.15% fee is charged when a Recurring Order is successfully executed.
* TINY governors enjoy a discounted fee of 0,1%. In order to be eligible, TINY governors need to hold a TINY power of at least 5000

#### Execution Flow

* Full order value is deposited into a smart contract at creation
* The contract executes trades at the defined intervals and within the allowed price range
* After each execution, tokens are delivered directly to the user's wallet
* Orders can be canceled at any time, and unused funds will be returned

#### Example Use Case

A user sets up a Recurring Order to buy $10 of ALGO every day for 5 days, only if ALGO trades between $0.15 and $0.18.\
They commit $50 total, satisfying the $10 minimum per execution.\
Each day, if ALGO's price is within range, $10 is used to purchase tokens.\
After 5 days or 5 successful executions, the order completes automatically.

### 3. Security

Security is a top priority at Tinyman. Both Limit Orders and Recurring Orders are built on secure, transparent smart contracts.

* All contracts are internally reviewed and tested
* The contracts are open source
* The contracts are upgradable with user consent only
* Isolated smart contracts: each user has their own contract account, holding only the associated funds — no pooled risks
* Users retain full control over their assets at all times
* Transactions and states are fully on-chain and auditable
* All orders are executed atomically, ensuring there can be no loss of funds to partial execution
* Recurring Orders use the existing Tinyman Swap Router to ensure trades are made at the market price.&#x20;
* The contracts ensure Recurring Order executions are not at risk of sandwich attacks

### 4. Early Access for TINY Governors

Tinyman prioritizes community governance. TINY Governors — users who lock TINY in governance — will get early access to both Trigger Orders and Recurring Orders.

#### Eligibility

* Locking at least 5,000 TINY Power is required for early access

#### Additional Governance Benefits

* Weekly TINY rewards for participation
* Voting rights on farming rewards and protocol upgrades
* Early access to future feature rollouts
* Boosted staking: stake ALGO in the Stakepool, restake tALGO as a Governor, and earn additional TINY rewards on top of your ALGO staking returns

### 5. Additional Considerations&#x20;

* Trigger Orders & Recurring Orders are executed on a best effort basis. Off-chain components are required for triggering execution and despite redundancy these may fail to execute.
* Trigger Orders might not execute even when the trigger price is reached. This can be due to a number of factors including the trigger price falling again within a short timespan, the price impact of the order and the volume of orders.
* Note this is not an orderbook system. The orders are executed on the Tinyman AMM where the price moves independently of the trigger orders.
* Smaller order amounts have higher probability of successful execution than larger ones.


# Liquid Staking

### Overview of Liquid Staking

The liquid staking solution enables users to stake ALGO directly into the Tinyman Stake Pool through the Tinyman UI. By participating in staking, users contribute to the security and decentralization of the Algorand blockchain while earning staking rewards.

### Staking Rewards

Staking rewards are distributed in ALGO. The total rewards earned per ALGO decrease as more ALGO are staked, resulting in a lower Annual Percentage Rate (APR). Rewards for tALGO are derived from two primary sources:

1. ﻿﻿Block fees - 50% of transaction fees will be paid out as block reward
2. ﻿﻿Algorand Foundation-funded supplementary bonus - Starting at 10 Algo per block, this bonus will decay by 1% every 1 million blocks. The Foundation has committed to providing bonus rewards for a period of 24 months.

### Fee Structure

Tinyman employs a fee structure that automatically deducts a portion of the staking rewards to support the protocol's sustainability. A fee of 8% is applied to the total block rewards before distribution to users. The remaining rewards are added to the tALGO value.&#x20;

### Liquid Staking Process

Upon staking ALGO, users receive tALGO in return. tALGO is a liquid token that can be traded or transferred and can be utilized for additional yield opportunities, such as re-staking, liquidity provision, and farming. Importantly, tALGO automatically accrues Algorand staking rewards without requiring active management.

### Unstaking tALGO

tALGO can be redeemed for ALGO at any time, with no lock-up periods or penalties. Upon redemption, users receive the initial ALGO amount along with any accrued staking rewards.

### Re-Staking tALGO

Users have the option to re-stake tALGO. Upon re-staking, stALGO is issued at a 1:1 ratio. stALGO represents the re-staked tALGO and allows for the earning of additional TINY rewards. While stALGO remains in the user's wallet, it cannot be transferred or traded. Holding stALGO enables continuous accumulation of TINY rewards, which can be claimed at any time from the re-staking page—unstaking is not required to access these rewards. Re-staking provides an opportunity to generate extra yield without active management.

### Re-Staking Requirements

To re-stake tALGO, a minimum of 5000 TINY power is required, which can be earned by locking TINY tokens in governance. Locking TINY qualifies users as Tinyman governors and provides various benefits, including additional TINY rewards and voting rights. For further details, please refer to this [link](https://docs.tinyman.org/token-and-governance/governance-details/governance-vault).

### Unstaking stALGO

stALGO can be unstaked at any time and redeemed for tALGO on a 1:1 basis. Any accrued TINY rewards can be claimed at any time. A minimum of 5000 TINY power is required in order to claim TINY rewards. &#x20;

### Swapping ALGO

When a user swaps ALGO to tALGO, the "stake ALGO" process is applied, staking the ALGO and issuing tALGO.

When a user swaps tALGO back to ALGO, the "unstake tALGO" process is applied, unstaking the tALGO and returning the original ALGO.

### Implementation Details & Contracts

The contract sources are available to view in the Github repo.

The repo also contains [audit reports](https://github.com/tinymanorg/tinyman-consensus-staking/tree/main/audits) and the [protocol specification](https://github.com/tinymanorg/tinyman-consensus-staking/blob/main/docs/Tinyman_Liquid_Staking_Protocol_Specification.pdf).

Github repo: <https://github.com/tinymanorg/tinyman-consensus-staking>

### On-Chain Details

tAlgo ASA:  [2537013734](https://lora.algokit.io/mainnet/asset/2537013734)\
tAlgo App ID: [2537013674](https://lora.algokit.io/mainnet/application/2537013674)

Re-Staking App: [2537022861](https://lora.algokit.io/mainnet/application/2537022861)\
stAlgo ASA: [2537023208](https://lora.algokit.io/mainnet/asset/2537023208)


# Overview

The Tinyman V1 Docs

[Tinyman](https://tinyman.org/) is a next-generation decentralized AMM on the Algorand blockchain.

{% hint style="info" %}
Tinyman is live on Algorand Mainnet. See [app.tinyman.org](https://app.tinyman.org)
{% endhint %}

Tinyman announced the AMM V2 protocol. Please refer to the links below for more details:\
\
**Blog about V2 Protocol:** [**Tinyman Medium**](https://medium.com/@tinymanorg/tinyman-amm-v2-0-protocol-201e0f32f58d) \
**Tinyman AMM V2 Protocol Specification:** [**Tinyman GitHub**](https://github.com/tinymanorg/tinyman-amm-contracts-v2/blob/main/docs/Tinyman%20AMM%20V2%20Protocol%20Specification.pdf)\
**Smart Contracts on GitHub Repo:** [**Tinyman Github**](https://github.com/tinymanorg/tinyman-amm-contracts-v2/tree/main/contracts)\
\
\
**Website**: <https://tinyman.org/>\
**Web** **App**: <https://app.tinyman.org>\
**Github**: <https://github.com/tinymanorg>\
**Twittter**: [@tinymanorg](https://twitter.com/tinymanorg)

This documentation describes the [design](/tinyman-v1/design-doc) of the system, provides an explanation of the [core concepts](/tinyman-v1/faq), and documents the technical details to enable integration with the protocol.

{% content-ref url="/pages/-MaZ0o8Sckd0RaSWerS-" %}
[FAQ](/tinyman-v1/faq)
{% endcontent-ref %}

{% content-ref url="/pages/-MaZ1DshbbnMkhiFA3oe" %}
[Design Doc](/tinyman-v1/design-doc)
{% endcontent-ref %}

{% content-ref url="/pages/-MaZw878Ul4Tb50BAH1a" %}
[Transaction Specifications](/v1-integration/transactions)
{% endcontent-ref %}

{% content-ref url="/pages/-MabxT30lvniAf\_hB3Zi" %}
[Contracts](/tinyman-v1/contracts)
{% endcontent-ref %}

{% content-ref url="/pages/-Ma\_4oKN2Z\_7rIhthl3B" %}
[V1 Integration](/v1-integration/pool-lookup)
{% endcontent-ref %}

{% content-ref url="/pages/-MgQtJJcZDflRB14dohr" %}
[Tinyman Testnet](/tinyman-v1/tinyman-testnet)
{% endcontent-ref %}


# Tinyman AMM Basics

A basic overview of the Tinyman AMM

## Overview

Tinyman is a decentralised exchange (DEX) on Algorand. More specifically it is an Automated Market Maker (AMM) exchange employing the Constant Product Market Maker algorithm. This is the same concept pioneered by Uniswap V2.

The web based app (`app.tinyman.org`) is a visual interface for interacting with a set of smart contracts deployed to the Algorand blockchain.&#x20;

The exchange is fully **decentralized** and **non custodian**. Funds are held in permissionless smart contract accounts. This means the only methods to withdraw funds from the pool accounts are those encoded in the smart contract. At a high level this code only allows withdrawals in exchange for an appropriate amount of another asset or by the liquidity owners in exchange for their Pool Tokens.&#x20;

Furthermore the contracts are fully **permissionless**. This means that any account can create a pool by issuing the correct set of transactions. It means that no account has authority over the pool's assets or functionality. This also means there is *no mechanism to revert or adjust transactions even if they are made in error.*

The contracts are also fully **immutable**. This means no account has the authority to update or delete the contracts that control the pools. This means that funds cannot be stolen by an update to the contracts.


# Creating Pools

For a user to be able to swap between two assets there must be a Pool for those two assets and that pool must have 'liquidity' (funds in both assets). A large amount of liquidity is required for users to be able to swap close to the mid price.

As a permissionless protocol any user can create a pool for an asset pair or provide liquidity for a pool.&#x20;

There are some important considerations when creating a pool:

* Assets in pools should only be currencies - assets with large total supply.
* Assets in pools should NOT be collectables, NFTs, or similar assets with low total supply.
* The system is designed with the expectation that the minimum input and output amount of a swap is 1000 microunits.
* A small quantity of each asset is permanently locked in the pool. This amount is displayed the first time liquidity is added.
* The initial liquidity must be provided at an appropriate ratio that matches the market rates to avoid losses to arbitrage.


# Slippage & Excess

**Slippage** refers to the slip or movement in price between the time a transaction was prepared and the transaction was executed.

When you sign a swap transaction you agree to receive an exact amount of one asset in exchange for an exact amount of the other. If the price slips your transaction would fail because the ratio of the input and output is no longer valid. Even if it slips by a miniscule amount your transaction would fail. To handle this situation the concept of **slippage tolerance** is used.

With **slippage tolerance** you agree to accept a slightly less amount (a slightly poorer price) in the *worst case*. The default is a tolerance of 0.5%. This swap is more likely to succeed because it has some tolerance included. You will immediately receive the exact amounts you sign for. However the contract calculates the exact amount you should receive, which is usually better than the worst case you agreed to, and stores the difference for you as **excess**.

**Excess** is simply an IOU (I owe you) from the Pool. The amount is stored in the Pool account rather than your account but you and only you can **redeem** it at any time to move it to your account. You can let the excess amounts accumulate over multiple swaps or redeem after each swap if you wish.

The same concepts of slippage and excess apply to **adding/removing liquidity** operations also.

### Examples

#### Swapping

Bob wishes to swap 100 USDC for Algo. He is quoted 50.00 Algo at a rate of 2.0. With 0.5% slippage tolerance he agrees to receive 49.75 Algo at minimum. The swap executes and he receives exactly 49.75 Algo. He is then informed that he has 0.24 Algo in *excess* which he decides to *redeem* later. The total received was 49.75 + 0.24 = 49.99. With a no slippage tolerance this swap would have failed but with 0.05% tolerance Bob was very satisfied.

Alice wishes to swap 50 Algo for USDC. She is quoted 100.00 USDC at a rate of 0.5. With 0.5% slippage tolerance she agrees to receive 99.50 USDC at minimum. The swap executes and she receives exactly 99.50 USDC. She is then informed that he has 1.00 USDC in *excess.* The total received was 100.50 USDC because the price shifted to 2.01 just before her swap executed. Alice was delighted with this result as the amount received is even better than she expected when she first got her quote.

Carol wishes to swap 100 USDC for Algo. She is quoted 50.00 Algo at a rate of 2.0. With 0.5% slippage tolerance she agrees to receive 49.75 Algo at minimum. The swap fails to execute. A large swap before hers made the price jump to 2.1. If her swap was exectuted at this rate she would have received 47.61 Algo which she wouldn't have been happy with. Carol was glad her slippage tolerance was not too high. She waited a bit for the rate to return and did her swap again.

#### Adding Liquidity

Dan wishes to add liquidity to the Algo-USDC pool. For adding 100 USDC and 50 Algo he is quoted 70 Pool Tokens to represent his share of the pool. With 0.5 slippage tolerance he agrees to receive 69.65 Pool Tokens at minimum. The mint operation executes and he receives exactly 69.65 Pool Tokens. He is then informed he as 0.30 Pool tokens in *excess.* The total received was 69.95 Pool Tokens due to a slight change in the pools liquidity. Dan chooses not to redeem the excess right now. He will still earn profits from swap fees proportional to his *total* Pool Tokens, including the amount in excess. However, he will need to redeem the excess before being able to withdraw his entire liquidity share.


# Farming

#### Overview <a href="#docs-internal-guid-cc253a8b-7fff-e763-4b36-c841dab7a1c0" id="docs-internal-guid-cc253a8b-7fff-e763-4b36-c841dab7a1c0"></a>

* The concept of the farming (staking) program is one of the core elements of DeFi, especially AMM platforms.
* Staking is pretty similar to Liquidity Provision, but also it allows Poolers to get “extra” rewards by a staking process.
* Poolers that agree to keep their liquidity in pre-determined Tinyman pools for a “certain amount of time”, will be eligible to earn rewards in addition to fees.&#x20;
* Tinyman will support this functionality by listing staking opportunities for those certain pools, enabling Poolers to commit to a staking program, track commitment activities, and distribute rewards on behalf of the program manager.
* The first Staking Program on the Tinyman belongs to Algorand Foundation. Therefore, all the components of the program, such as the start and end dates of the program, participation conditions, reward distribution rules, cycle durations etc. are determined by the Algorand Foundation.

#### How to Participate?&#x20;

* Users need to apply for the Staking Program in order to participate, whether they are already in the pool or not.
* Applying for a staking program is simply a commitment from a Pooler to keep a minimum balance of Pool Tokens during the whole staking period.
* Applying for a staking program requires signing an app call transaction that doesn’t transfer any assets elsewhere or alters their pool positions. By doing that, users only declare their intention to be part of the program.&#x20;
* Users can apply and participate in the program anytime as long as the program is available.&#x20;
* There will be some conditions for participation eligibility such as committing a minimum specific amount of pool tokens or its USD equivalent. Details to these specifications will be announced with each staking program.
* When users apply for a program, all available pool tokens will be recognized and utilized for the staking program by Tinyman.&#x20;

#### What are cycles?

* Cycles are the duration of staking commitment that must be completed to be eligible for the rewards.
* The cycle duration is 24-hours – it starts and ends at a specific time (UTC 00:00) every day. When one cycle ends, the other cycle starts automatically.
* Users are only able to earn rewards when they complete an entire cycle.&#x20;
* Rewards will be allocated per cycle. So, after completing a cycle successfully, users will be eligible to receive rewards per cycle based on their staked liquidity.
* The total reward amount is open to changes between cycles by the program owner.

#### How to Earn Rewards?

* Users can earn rewards only if they have applied for the program and completed the entire cycle successfully.
* Users must maintain a balance of at least the committed amount of Pool Tokens at all times throughout the cycle to remain eligible.
* As a specific amount of rewards is set for each cycle, rewards are distributed to the eligible stakers proportionally to their share of the total eligible staked amounts.
* Pooler commitments are accepted before the cycle starts. When the new cycle starts, rewards will be allocated as “Accumulated Rewards” per user according to their pool shares. They won’t be able to earn these rewards until the cycle ends. &#x20;
* The earned rewards will be credited from “Accumulated Rewards” to “Rewards to be Distributed” as users complete cycles.
* Users will receive rewards based on the number of cycles they complete successfully.&#x20;
* Users can add pool tokens to the Tinyman pools at any time. When they do so, they need to update their position in the staking program manually. That way, they will start earning rewards in the upcoming cycles according to their new commitment.

#### Leaving a Program and Ineligibility&#x20;

* Users can “leave the program” or “unstake” any time. If they do so, they won’t be eligible to earn rewards for the ongoing cycle. This does not affect the rewards previously earned by the user.
* Users have to keep the committed amount of Pool Tokens at all times during an ongoing cycle. If the Pool Token amount in the wallet goes below the committed amount, the user loses eligibility for the cycle. In case of multiple transactions of the Pool Tokens, users will only be eligible if the minimum amount stays above the committed amount at all times.
* In order to participate again, you will have to commit your pool tokens once more.
* Users can stake pool tokens any time, but earning rewards only applies to complete cycles. Therefore, users cannot qualify for rewards until the next cycle starts.&#x20;

#### How will the rewards be distributed?

* When users successfully complete cycles, their rewards will gradually accumulate in the “Rewards to be Distributed” section. Here, users will see the rewards they earned but not yet transferred to their accounts.
* Rewards to be Distributed will be (automatically) sent by the program manager to the stakers within 7-days, then it will be shown as Paid Rewards. Users do not need to claim them.

#### What are the risks? <a href="#docs-internal-guid-d45df23a-7fff-7bd0-e94e-36d8f2749715" id="docs-internal-guid-d45df23a-7fff-7bd0-e94e-36d8f2749715"></a>

* There are no additional risks in participating in the staking program because users' pool tokens never leave their accounts.
* The usual risks of providing liquidity to AMM pools apply as always.

#### What is the commitment transaction?

* The commitment transaction is an Application Call that records the users' commitment on-chain if it is valid and meets the requirements of the program.
* As with all Algorand Application Call transactions, it cannot transfer users' funds or take authority of users' accounts.

<br>


# FAQ

*Tinyman is in ongoing development and the following FAQs will continue to be updated as the Tinyman protocol continues to be defined.*

## **What service does Tinyman offer?**

Tinyman enables users to trade/swap Assets (Tokens/Currencies) at market rates.

## Who are the users of Tinyman?

There are two classes of users of Tinyman: Swappers who trade assets and Poolers who provide asset liquidity for the trading Pools.&#x20;

Poolers are individuals/organisations who hold reasonably large amounts of assets.&#x20;

Swappers are individuals/organizations who wish to exchange tokens. They may be interested in doing this in an automated way with bots or they may use an app interface.

## What are Pools?

Pools are Accounts holding two different Assets contributed by Poolers. Swappers transfer assets to and from pools.

## Who sets the exchange rates?

The exchange rate for a swap is determined from the ratio of the pair of Assets in the Pool and the amount to be swapped. The precise rate will be different for every transaction but will always ensure the total product of the Pool stays constant (+ fees). This type of exchange is known as a Constant Product Market Maker, a type of Automated Market Maker.

## How is the exchange rate enforced?

The smart contracts of the Pool ensure that only a group of transactions for the correct amounts succeed.

## Why do Poolers provide assets?

In return for providing assets, they receive a share of transaction fees.

## How are Poolers fee shares calculated?

A Pooler is issued an amount of Pool Token proportional to their Pool contribution. This can be cashed in at any time in return for a portion of the Pools assets.

## How often does the Pooler receive fees?

Poolers only receive fees when they withdraw liquidity (assets) from the Pool by exchanging their Pool Tokens.

## Who controls withdrawals from the Pools?

The assets are held in a contract account that only allows withdrawals in two cases:

1. As one transaction of a swap where an equal value of the other asset is deposited
2. As one transaction of a withdrawal where an equal value of Pool Tokens are deposited

## Who owns the assets in a Pool?

Only the Pool Token holders have the right to withdraw assets and only in proportion to their contribution so they collectively own the Pool assets.

## Can a Pooler withdraw one asset from a Pool?

No, the Pool’s balance must be maintained so an equal value of both currencies must be withdrawn in exchange for Pool Tokens.

## How does a Swapper interact with Tinyman?

A Swapper may swap assets with the Tinyman pools using either of three methods:

1. Manually/programatically creating, signing and submitting a set of transactions that satisfy the smart contracts
2. Signing and submitting the transactions created by the helper functions of the Tinyman JS library
3. Using the web app interface to do the swap, signing the transactions with a wallet browser extension. Current available wallets and browser extensions are [Pera Wallet](https://perawallet.app/), [My Algo Wallet](https://wallet.myalgo.com/), [Exodus Wallet](https://www.exodus.com/), [Defly](https://defly.app/), [Fireblocks](https://www.fireblocks.com/) and other WalletConnect and AlgoSigner compatible wallets.

## How does a Pooler interact with Tinyman?

Using any of the 3 methods described above for Swappers.

## How can I connect to Tinyman with my Ledger account?&#x20;

Wallets that support atomic transactions for Ledger accounts can operate flawlessly with the Tinyman platform. At the moment only My Algo Wallet supports this. Hopefully other wallets will support this in the near future.

## How will the exchange rate track the general market rate?

Certain Swappers will monitor discrepancies between Tinyman rates and rates on other exchanges and trade these to their profit until the rates are equalized. This is known as arbitrage trading.

## How are Pools created?

Pools are created by submitting a specific set of transactions. The logic of the contracts ensures that only one Tinyman Pool can exist for a pair of assets.

## Who can create Pools?

Anyone can create a Pool by issuing the correct set of transactions.

## Can Pools be created for any pair of Algorand Standard Assets?

Yes, the protocol is fully permissionless so no restrictions are in place. However it is not at all advisable to create pools with assets that have a low total supply. Pools should not be created with assets that represent collectables, NFTs or similar.\
The system is designed with the expectation that the minimum input and output amount of a swap is 1000 microunits. Swapping smaller amounts than this may lead to rounding errors that negatively affect users.

## Can Pools be created with Algo as one of the ‘assets’?

Yes. Algo is not an ASA but it may be used as one of the assets in a Pool.

## Can Tinyman be used to swap NFTs?

No, AMM protocols like Tinyman are not suitable for swapping assets like NFTs.

## How is the exchange rate set at the time of Pool creation?

The Pool creation contracts do not enforce an exchange rate as they have no knowledge of the current market rates. However, it is in the Pooler's interest to ensure the ratio of assets deposits matches the market rates. Pools can always be traded against from both sides so Swappers will take advantage of any rates that don't match the overall market.

## What currency/asset is the swap fee paid in?

The fee is paid in the currency of input/sell asset. The fee amount is added to the liquidity in the pool.

## Does the platform/protocol earn fees?

The platform earns fees at %0.05 of the input amount. Pool tokens are allocated to the protocol representing the platform's share of each swap.

## Who will control the protocol fee account?

The protocol fee account will eventually be controlled by a governance process encoded in smart contracts. Holders of a governance token will be able to participate in this process and control how the fee account’s assets are used. The details of this governance system are TBD. It will not be in place at the time of the initial product launch.&#x20;

The protocol fees are claimable only by the creator of the Tinyman Validator app, a MultiSig account controlled by team members.

## Can Pool tokens be traded?

Yes they are standard assets and can be traded freely. Only the pool token is necessary to redeem liquidity from the associated Pool.

## Can't the Tinyman team change the rules of contracts and take all the assets?

No. The contracts will be published with rules that forbid anyone to change them. The team will have no way of taking assets from Pool accounts or modifying any of the contract code.

## Does that mean the Tinyman product will never change or improve?

No. The contracts themselves cannot be updated but the interface may be improved and may even interact with new contracts. If the team persuades the community that the new contracts offer advantages, the Poolers will want to move their assets to the new accounts. The old contracts will still exist and Swappers and Poolers will still be free to use them as they wish.

## What transactions are needed for a Swap?

A Swap is made by transferring some of "Asset A" to a Pool and transferring some of "Asset B" from the Pool. Algorand smart contracts only allow or reject transactions but do not initiate any transfers themselves. The Tinyman SDK/Web App will prepare a group of transactions that will be approved by the Tinyman smart contracts.

The specific group of transactions needed for a Swap are as follows:

&#x20;   0: Pay - pay fees in Algo from Swapper to Pool

&#x20;   1: App Call - NoOp call to Pair App with args 'swap'

&#x20;   2: AssetTransfer - transfer sell asset from Swapper to Pool

&#x20;   3: AssetTransfer - transfer buy asset from Pool to Swapper

The app call transaction (1) verifies that the amounts of transactions 2 and 3 satisfy the constraint of the Pool.&#x20;

The Pay transaction (0) is required to transfer enough Algos to the Pool to cover the fees of transactions 1 and 3.

Transactions 0 and 2 must be signed by the Swapper.

## What happens if the Pool exchange rate changes between the time of preparing the transactions and execution (slippage)?

This will be a common occurrence in Pools with high volume. Tinyman handles this by including slippage tolerance in the preparation of the transactions to reduce the possibility of asking for more of an asset than allowed by the rate. If the initial set of swap transactions succeed, the minimum amount will be received. The Pool will likely hold some excess that can be reclaimed with a subsequent transaction. The excess is redeemed with a Redeem transaction group.<br>

## What transactions are needed to Redeem excess?

The specific group of transactions needed for a Redeem is as follows:

&#x20;   0: Pay - pay fees in Algo from Swapper to Pool

&#x20;   1: App Call - NoOp call to Pair App with args 'redeem'&#x20;

&#x20;   2: AssetTransfer - transfer asset from Pool to Swapper

The app call transaction (1) verifies that the amount in transaction 2 is the same as the amount of excess stored in the Pool for the Swapper.

The Pay transaction (0) is required to transfer enough Algos to the Pool to cover the fees of transactions 1 and 2.

Transaction 0 must be signed by the Swapper.

## Is Excess a type of reward or profit?

No, excess is simply an IOU or change from some operations with the pool due to slippage tolerance. Read more about it [here](/tinyman-v1/tinyman-amm-basics/slippage-and-excess).

## Are any additional transactions required to Swap on Tinyman?

The Swapper must Opt-In to the Tinyman Validation app once. They must also Opt-In to receive Assets that they have not previously received.

As with all Apps and Assets on Algorand, each Opt-In increases the minimum balance of Algos required. This is not a fee but a minimum balance that must be held.

## How does the Swapper know the correct amounts to include in their Swap transactions?

The Tinyman SDK/Web App will calculate these based on the Swapper input amounts using information retrieved from the network on the current asset amounts held by the Pool account. The formula to determine the swap amounts including fees is publicly known and encoded in the SDK/Web App.&#x20;

## How does Tinyman mark Assets as Verified?

Tinyman does not "Verify" any Asset and does not play any role in the verification process. This process is done by Algorand. Tinyman only pulls this verification information from the Algorand Wallet. Beware that Algorand's official verification mark is different than the verification mark in [http://algoexplorer.io](http://algoexplorer.io/).

## **What is impermanent loss?**

CoinMarketCap defines impermanent loss as “the temporary loss of funds occasionally experienced by liquidity providers because of volatility in a trading pair.” To put this into perspective, if you are holding an LP token, and one of the assets depreciates in value in the short term, but gradually returns to the original price, then you would have lost value "impermanently." Alternatively, if the same asset appreciated in value before reverting to the mean, you would have had "impermanent gains." These metrics can help liquidity providers balance their portfolios for optimal ratios. For instance, if you think a token will appreciate, and then revert to the mean, you might provide liquidity before it appreciates, just to accumulate the fees for that duration.\
\
If you'd like to learn more about impermanent loss, the following articles may be useful:\
<https://pintail.medium.com/understanding-uniswap-returns-cc593f3499ef>\
<https://blog.bancor.network/beginners-guide-to-getting-rekt-by-impermanent-loss-7c9510cb2f22> <br>

## Does Tinyman earn commission when I add Algo with Moonpay?

No, Tinyman has setup an integration with Moonpay with 0 fees/commission for Tinyman. This integration is provided purely as a convience for Tinyman users.

## **How can I get help with buying Algo with Moonpay ?**

For any issues related to Moonpay please checkout their support page here: <https://support.moonpay.com/hc/en-gb/categories/360001595097-Customer-Support-Help-Centre>


# Fees

## Swapping

A fee of 0.3% is added to all swaps.&#x20;

* 5/6ths of this fee (0.25%) is paid to Poolers
* 1/6th of this fee (0.05%) is paid to the protocol (Tinyman Treasury)

Algorand transaction fees: 4 \* min fee = 0.004 Algo

## Minting & Burning (Adding & Removing Liquidity)

There are no extra fees charged by Tinyman for Minting or Burning.

Algorand transaction fees: 5 \* min fee = 0.005 Algo

## Redeeming

There are no extra fees charged by Tinyman for Reedeming.

Algorand transaction fees: 3 \* min fee = 0.003 Algo

## Pool Creation

There are no extra fees charged by Tinyman for Pool Creation.

There are additional Algo costs to cover the minimum balance required for the Pool account:\
ASA-ASA Pool: 0.956 Algo\
ASA-Algo Pool: 0.856 Algo

Algorand transaction fees: \
ASA-ASA Pool: 5 \* min fee = 0.005 Algo\
ASA-Algo Pool: 4 \* min fee = 0.004 Algo

**Total costs for Pool Creation:**\
ASA-ASA Pool: 0.961 Algo\
ASA-Algo Pool: 0.86 Algo<br>


# Design Doc

This document outlines the design for a permissionless distributed exchange on Algorand conducted by an automated market maker (AMM).

This document outlines the design for a permissionless distributed exchange on Algorand conducted by an automated market maker (AMM). This exchange is modeled after [Uniswap](https://uniswap.org/docs/v2/protocol-overview/how-uniswap-works) on Ethereum. The AMM will be implemented on-chain as Algorand TEAL smart contracts.&#x20;

### Terminology <a href="#docs-internal-guid-27dcd091-7fff-6e35-771b-03aac678291a" id="docs-internal-guid-27dcd091-7fff-6e35-771b-03aac678291a"></a>

* Pools - liquidity pools holding 2 assets
* Poolers - users who provide assets to the Pools
* Swappers - users who trade/swap assets through Pools
* Assets - Algorand Standard Assets (ASAs) and Algo
* Liquidity Token - An ASA that represents a share of the value of a Pool

### Assumptions <a href="#docs-internal-guid-da766dec-7fff-b58e-6213-9a4d50dcc401" id="docs-internal-guid-da766dec-7fff-b58e-6213-9a4d50dcc401"></a>

* The exchange will be permissionless, meaning that anyone can use it.
* The exchange is fully decentralized and immutable - nobody can update/delete/freeze the Pools or assets.
* The exchange is non-custodial. Only the Poolers have access to their shares of the Pools.
* The AMM will be a [constant product market maker](https://github.com/runtimeverification/verified-smart-contracts/blob/uniswap/uniswap/x-y-k.pdf), like Uniswap.
* The Pools hold assets in a 50/50 ratio.
* The AMM will allow exchange between pairs of Algorand Standard Assets (ASAs) or ASA and Algo.
* The ASAs should have high liquidity - a large total supply (not NFTs or collectables).
* The minimum swap/mint/burn size is expected to be 1000 microunits.
* A percentage based fee is charged on every trade, called the swap fee. This fee increases a Pool’s liquidity and benefits liquidity providers (Poolers).

### Users <a href="#docs-internal-guid-cedc7258-7fff-7f6b-a90f-41441302267f" id="docs-internal-guid-cedc7258-7fff-7f6b-a90f-41441302267f"></a>

This exchange is designed to be used by two parties: Swappers and Poolers (liquidity providers).

* Swappers - use the exchange to swap one asset for another.
* Poolers - contribute assets to a Pool in the exchange, and in return, they are given liquidity tokens.
  * Liquidity tokens can be returned at any time to the Pool for a proportion of the Pool’s assets equal to the proportion of liquidity tokens being returned.

### Architecture <a href="#docs-internal-guid-3a27668b-7fff-b3b3-3307-3ad573eee481" id="docs-internal-guid-3a27668b-7fff-b3b3-3307-3ad573eee481"></a>

Liquidity Pools are implemented as contract accounts controlled by LogicSignatures. A stateful smart contract, the Validator app, implements the validation and state changing logic for all Pools.

The Validator app is deployed to the network by the Tinyman team. The Pool contract accounts are created from the Pool LogicSig template by the first Pooler who wishes to provide liquidity.

![System Overview](/files/-MaZ6Ghb9OWG8YgvdwIV)

#### Validator App <a href="#docs-internal-guid-b18fd459-7fff-aa47-087b-2bcfdededbc5" id="docs-internal-guid-b18fd459-7fff-aa47-087b-2bcfdededbc5"></a>

* Stateful smart contract
* Created by Tinyman core team
* Fully immutable
  * No updates allowed
  * No deletion allowed
* No global state
* Local state in Pool, Pooler, Swapper accounts (16 ints, 0 bytes)
* Contains validation and state manipulation logic for all operations

#### Pool Logic Signature Template

* A stateless smart contract template
* Template variables for asset 1 and asset 2 ids
* Pool contract account address retrieved by hashing the completed template
* Contains logic to ensure only transactions part of expected transaction groups are signed
* Delegates most logic responsibility to the Validator app by ensuring the transaction group contains a call to the Validator App with appropriate arguments

#### Pool Contract Account

* One Pool account per asset pair
* Exclusively controlled by the Pool Logic Signature (No associated private key)
* Creates/owns the Liquidity Token asset for the Pool

#### Liquidity Token Asset

* An Algorand Standard Asset (ASA)
* One liquidity token asset per Pool
* Created by the Pool
* Fully permissionless
  * No freeze permission
  * No clawback permission
  * No management permission

## Operations <a href="#docs-internal-guid-69e5be6f-7fff-594a-4eb8-acbc2d43c420" id="docs-internal-guid-69e5be6f-7fff-594a-4eb8-acbc2d43c420"></a>

This section describes how Pools are found, created, and used.

### Lookup

In order to use a Pool, users must know the address of the LogicSig account.

To get the address of the Pool LogicSig account, we make its TEAL contract template publicly available. Users can then fill out the template with the two assets IDs that they want to exchange and then hash it to get its address. This provides a deterministic way to find the address of a Pool and ensures that only one Pool exists for an asset pair.

Once the user knows the Pool LogicSig account address, they can query the account state to find the only asset created by the Pool, the Liquidity Token.

The current balances (and thus exchange rate) of the Pool are found by querying the Pool account state to find the asset balances and the Validator app local state. This information can be combined to retrieve the current balances and exchange rate.

### Creation

In case an address for a Pool with certain assets represents an account that has not yet been created, any user can create that Pool by funding that address and executing some bootstrap transactions. The address needs funding because of the minimum balance associated with opting into the Validator App, opting into the assets, creating its own liquidity token asset, and paying for transaction fees. If there is sufficient interest in a Pool, some user should be willing to donate these funds. The account that bootstraps the Pool does not need to be the account that mints the first liquidity. These are separate operations. The bootstrapper does not have any form of ownership or privilege over the Pool.

#### Bootstrap Process

The goal of the bootstrap process is to allow any user to create a new Pool without the possibility that the Pool could get stuck in an invalid state.

The bootstrap operation consists of a single atomic group of 5 transactions:

1. Pay Algo to cover fees and minimum balance&#x20;
2. Opt-In to Validator app, with args \['bootstrap', asset1ID, asset2ID]&#x20;
3. AssetConfig - create asset for liquidity token
4. Asset OptIn - Pool opt in to Asset 1
5. (Optional) Asset OptIn - Pool opt in to Asset 2

Transaction 0 must cover the minimum balance + the fees for the subsequent 3 (or 4) transactions (3 (or 4) \* 1000 microAlgo).&#x20;

The calculation for the minimum balance is as follows:

`minBalance = 100000 // min account balance`\
&#x20;          `+ 100000 // min balance to create asset`\
&#x20;          `+ 100000 // fee + min balance to opt into asset 1`\
&#x20;          `+ (asset2Optin ? 100000 : 0) // min balance to opt into asset 2`\
&#x20;          `+ 100000 + (25000+3500)*numLocalInts`\
&#x20;          `+ (25000+25000)*numLocalByteSlices; // min balance to opt into validator app`

The Validator App has numLocalInts=16 and numLocalByteSlices=0 so the minBalance is 956000 for a ASA-ASA pool and 856000 for a ASA-Algo pool.

Transactions 1-4 must be signed by the Pool LogicSig which will verify that the provided values are correct. The Validator app will store the asset IDs in its local state in the Pool account, so that they can be referenced later.

Because this is an atomic group, if any of these transactions do not meet the criteria defined in the Validator contract or the Pool LogicSig contract, all transactions will fail.

Once the Pool account is created and bootstrapped, the Pool is ready to mint liquidity tokens.

### Mint Liquidity

A user (Pooler) can mint liquidity by contributing equivalent values of each asset in a pair to that pair’s Pool account. In return, the Pool rewards the user with liquidity tokens in proportion to the amount of assets they contributed.&#x20;

The initial liquidity token amount is calculated as the geometric mean of the two asset amounts provided: `initial liquidity token amount = sqrt(asset1 * asset2)`

The first 1000 units of the liquidity token are ‘locked’ to prevent rounding errors in the calculation so the first minter receives `sqrt(asset1 * asset2) - 1000` liquidity tokens.

Subsequent minting should maintain the current ratio of the two assets.

Liquidity tokens are minted according to the following formula:

`liquidity_token_out = Min(`\
&#x20;   `(asset1_amount / asset1_supply) * issued_liquidity_tokens,`\
&#x20;   `(asset2_amount / asset2_supply) * issued_liquidity_tokens`\
`)`

Note: A Pooler may provide assets in another ratio but they will only be minted liquidity tokens for the smaller amount so they would effectively be providing a donation to the Pool.&#x20;

Aside from Algorand transaction fees, there are no fees charged to Poolers for minting.

### Burn Liquidity

Any user in possession of liquidity tokens can ‘burn’ them (some or all) at any time by exchanging them with the Pool for the corresponding proportion of the Pool’s assets.

For example, if a Pool has a balance of 10 asset A, 100 asset B and has issued 10 outstanding liquidity tokens, 1 liquidity token can be burnt for 1 asset A and 10 asset B. The Pool would then have a balance of 9 asset A, 90 asset B and have issued 9 outstanding liquidity tokens.

If a user wants to mint/burn liquidity and only wants to send/receive one asset from a pair, a convenience method can be implemented that swaps half the amount of the asset for them before a mint or after a burn. This method will only be practical for insignificant amounts of liquidity, since larger additions/subtractions would skew the exchange rate unfavorably.

Aside from Algorand transaction fees, there are no fees charged to Poolers for burning.

The asset out amounts are calculated as follows:

`asset1_out = asset1_supply * (burn_amount / issued_liquidity_tokens)`\
`asset2_out = asset2_supply * (burn_amount / issued_liquidity_tokens)`

### Swap <a href="#docs-internal-guid-6e57d876-7fff-754b-4cea-1a20397e3434" id="docs-internal-guid-6e57d876-7fff-754b-4cea-1a20397e3434"></a>

Given a Pool account for assets A and B that has non-zero liquidity, a user can use this Pool to swap some amount of asset A for asset B, or some amount of asset B for asset A. The exact exchange rate is determined by the ratio of assets A and B that the Pool account holds and the amount of assets the user wants to swap, in addition to the exchange fee. Since a swap changes the ratio of assets that the Pool account holds, every swap has an effect on the exchange rate. Small swaps on Pools with lots of liquidity have the least effect.

#### Slippage Tolerance

The exchange rate between a pair of assets changes constantly due to transactions in the Pool. Between the time the Swapper prepares their swap transaction and the time the swap is executed, the exchange rate may have changed, or ‘slipped’. The concept of ‘slippage tolerance’ defines how much of a slippage the Swapper is willing to tolerate. The tolerance is defined as a percentage. 0% means the Swapper does not tolerate any slippage and wants the exact quoted amounts or the transaction should fail. A slippage of 100% would allow the received amounts to drop to 0. Usually this value is somewhere around 1%.

#### Swap Types

There are two types of swaps that the Swapper can choose from when submitting a swap transaction group. These two types determine which side of the swap the slippage is applied to:

* Fixed input swaps: this swap involves a fixed amount of the input asset and requests a variable amount of the output asset. For example, a user might want to exchange exactly 10 USDC for any amount of Planet Tokens at the current market rate.
* Fixed output swaps: this swap involves a variable amount of the input asset and requests a fixed amount of the output asset. For example, a user might want to exchange any amount of USDC for exactly 50 Planet Tokens at the current market rate.

#### Fixed input calculation <a href="#docs-internal-guid-b98e8001-7fff-deb1-b032-f1b22a668e9d" id="docs-internal-guid-b98e8001-7fff-deb1-b032-f1b22a668e9d"></a>

amount\_out = (asset\_in\_amount \* 997 \* output\_supply) / ((input\_supply \* 1000) + (asset\_in\_amount \* 997))

#### Fixed output calculation

amount\_in = ((asset\_out\_amount \* input\_supply \* 1000) / ((output\_supply - asset\_out\_amount) \* 997)) + 1<br>

#### Swap Fees <a href="#docs-internal-guid-5e2aa69c-7fff-2dbc-0f56-86313afa2a52" id="docs-internal-guid-5e2aa69c-7fff-2dbc-0f56-86313afa2a52"></a>

Aside from Algorand transaction fees, Swappers must pay a swap fee of 0.3% to the Pool. This fee is deducted from the input or output amount depending on the swap type. The fee is calculated into the swap quote returned by the Web UI or SDK.

Note: The fees paid in Algo in the first transaction of a Swap transaction group cover the transaction fees of the subsequent transactions, NOT the swap fee.

The swap fees increase the assets of the Pool and thus increase the value of the Pool shares owned by the Poolers. Swap fees cannot be redeemed by Poolers separately from their Pool shares.&#x20;

**Protocol Fees**

A portion of the swap fees (1/6th) are granted to the system and are known as Protocol Fees. Liquidity tokens proportionate to 1/6th of the fee amount are minted and set aside. These are redeemable only by a specific account (the creator of the Validator App) and are intended to fund a treasury.

**Protocol fee calculation for fixed input swap:**

`protocol_fee_portion = asset_out_amount * 0.05%`\
`protocol_fee_portion = (asset_out_amount * 5) / 10000`

The protocol is granted a share of the pool for half of this amount because it's a 50/50 pool:

`protocol_fee_asset_out_amount = (asset_out_amount * 5) / 20000`\
`protocol_fee_liquidity_tokens = issued_liquidity_tokens * (protocol_fee_asset_out_amount / output_supply)`

## Implementation <a href="#docs-internal-guid-81783b89-7fff-56ff-0dc2-b31544925331" id="docs-internal-guid-81783b89-7fff-56ff-0dc2-b31544925331"></a>

Algorand smart contracts have some limitations that the AMM implementation must work around. The primary one is that smart contracts cannot directly send assets to users; they can only approve or deny transactions sent by users. However, stateful smart contracts can manipulate local account state.&#x20;

The user interacts with a Pool by preparing a set (atomic group) of transactions specific to the operation they wish to perform. If the structure and values of all parameters of all transactions in the group match the expectations of the contracts, the operation is executed. The expected values of the parameters depend on hard coded values in the contracts and also local app state stored in the Pool account. The user must lookup the current balances and app state values to determine the correct inputs for each operation.  (This is handled for the actual end user by the Web App of course.)

It is expected that there will be highly concurrent use of the Pools so the Pool balances and state values will constantly be in flux. This presents a (frustrating) challenge for a user that needs to submit transactions with exactly correct values. It is highly probable that the expected values will have changed by the time the transactions are executed, even if only a couple of seconds pass.

To handle this issue the Pool supports a form of slippage tolerance in Mint, Burn and Swap operations. The user specifies the minimum amount they expect to receive in the asset out transfer. The contract allows the transaction group to succeed if this can be satisfied but it also calculates and records any excess asset that is owed to the user in a fair trading scenario. This excess is stored and can be redeemed with a subsequent Redeem operation.

![](/files/-MaZ74kVLE35WeuhXYyV)

#### Excess and Outstanding Amounts

The excess amounts for all pools are stored in the local state of the Validator app. The state keys for each asset are prefixed by the Pool address to allow for excess amounts of the same asset from multiple pools.

The user must Opt-In to the Validator app so that it may store excess amounts in the local state. There is a limit of 16 state variables available. These are shared by all Pools. It is possible that a User will interact with many Pools and exhaust the available state slots available. In this case the user will be prompted to Redeem (and thus clear) excess amounts before continuing.

The Pool also needs to track the total outstanding amounts of each asset that are owed to users and subtract these from the asset balances to determine the actual asset supply when calculating swap/mint/burn amounts. These outstanding amounts for each asset are held in local state variables of the Pool (one for each of asset 1, asset 2 and the liquidity token). The outstanding amounts are reduced when a user redeems assets.

#### Fixed Input Swaps <a href="#docs-internal-guid-d451f557-7fff-fb8b-b5b2-93faaed9c54f" id="docs-internal-guid-d451f557-7fff-fb8b-b5b2-93faaed9c54f"></a>

Instead of asking the Pool account to send the exact amount of an asset the Swapper wants from the swap, this transaction would specify the minimum amount of the asset the Swapper wants. If the swap executes, the Swapper is guaranteed to get this minimum amount by the nature of atomic transaction groups. However, in most cases when a swap executes, the amount of the asset the Swapper is due to receive would exceed the minimum amount they asked for. This excess amount would be recorded in their local state by the Validator App contract. In a subsequent transaction group, the Swapper can claim this amount from the Pool account.

For example, consider a Swapper who submits a swap exchanging exactly 1 of asset A for at least 2 of asset B. When their swap transaction executes, the exchange rate is such that 1 of asset A is equivalent to 3 of asset B, so their transaction is approved and 1 unit of asset B is recorded as an excess balance in their local state. The Swapper can then submit a transaction immediately after they see the result of their swap to claim the additional 1 unit of asset B.

#### Fixed Output Swaps

Instead of the asset in transaction declaring the exact amount of the input asset they wish to swap, that transaction would specify the maximum amount of the asset they want to swap. The amount specified by the asset out transaction from the Pool account still represents the exact amount of the asset the Swapper wants to receive. If the desired amount of the output asset can be exchanged using less than the maximum input asset amount, this difference would be recorded in the Swapper’s local state by the Validator App contract, similar to the excess amount in a fixed input swap. This reduced amount of input assets can be claimed by the Swapper in a subsequent transaction group.

For example, consider a Swapper who submits a swap exchanging at most 2 of asset A for exactly 1 of asset B. When their swap transaction executes, the exchange rate is such that 1.5 of asset A is equivalent to 1 of asset B, so their transaction is approved and 0.5 units of asset A is recorded as an excess balance in their local state. The Swapper can then submit a transaction immediately after they see the result of their swap to claim the 0.5 units of asset A that were not needed in the swap.

This mechanism allows for the output assets to be sent to a different account if the sender wishes to do so and the recipient is able to receive the asset. This enables use cases like the following: I have a balance of 500 asset A and I need to pay my friend exactly 10 asset B. I can submit a fixed output swap for exactly 10 asset B in exchange for at most 500 asset A and change the recipient of the asset out transaction to my friend’s address. When the operation succeeds, my friend will receive exactly 10 asset B and I will have paid an equivalent amount of asset A.

#### Liquidity

A similar procedure also applies to minting and burning liquidity tokens, since frequent small fluctuations in liquidity necessitate the need to have a slippage tolerance in these situations too.

#### Redeeming

To redeem excess amounts from a Pool the user must submit a transaction group for the Redeem operation. This consists of a transaction to pay translation fees, a call to the Validator app and a transaction to transfer assets from the Pool to the user. The transactions will only be successful if the requested amount in the transfer is less than or equal to the current excess assets of the Pool. The redeemed amount is deducted from both the excess asset amount in the user’s local state and the outstanding asset amount in the Pool’s local state.

If the excess amount for an asset is reduced to 0 by a redeem operation, the corresponding slot of local state is cleared rather than set to 0. This prevents issues with exhausting the available slots when interacting with multiple pools.

The redeem operation is used by both Swappers and Poolers to claim excess amounts of Asset 1, Asset 2 and the Liquidity Token for Poolers.

Aside from Algorand transaction fees, there are no fees charged to Users for redeeming. A redemption requires 3 transactions with a total fee of 3000 microAlgos (currently), so it may not always be cost effective to redeem excess amounts immediately.

#### Protocol Fees

The protocol Treasury account accumulates liquidity tokens proportional to 1/6th of the swap fee ( 5/10000ths of the swap value). These liquidity token assets cannot be transferred inline to the treasury account, so they are stored in a local state variable in the Pool account and added to the outstanding liquidity token amount state variable. The creator of the validator app can redeem these amounts as liquidity tokens using a ‘fees’ operation. This account is the only account that can retrieve these assets.

#### Transaction Group Structure

All interactions with the Pool involve the use of atomic transaction groups. These have a common basic structure to make validation easier in the contract code.&#x20;

* The first transaction (gtxn 0) is always a Pay transaction from the User to the Pool to pay fees for the subsequent transactions that the Pool will make.&#x20;
* The second transaction (gtxn 1) is always an Application Call to the validator app with at least one argument. The first argument determines the type of the operation; bootstrap, mint, burn, swap, redeem. This transaction is always signed by the Pool LogicSig. This ensures both the Validator App and the LogicSig participate in validation of the transaction group.

#### Handling of Algo

Algo is the native currency of Algorand and is not represented as an Algorand Standard Asset. This has some implications for the handling of Algo as one of the assets of a pair in a Pool. The general formulae remain the same for Pools with Algo, but the implementation has to explicitly handle the case. The Algo has a special asset id of 0 and this is checked in various places in the code.

Transfers of Assets are made using an AssetTransfer transaction while an Algo transfer is made using a Pay transaction. This requires the code to check the fields of either AssetTransfer or Pay transactions. Similarly, the Algo balance is accessed differently from ASA balances. The Pool’s Algo asset reserves must be separated from it’s actual balance by subtracting Algo amounts that are held for other reasons. The Pool must hold a minimum balance of Algo to Opt-In to assets and the Validator app. This minimum balance is not considered part of the reserves of the Pool. Similarly, the transaction fees are transferred to the Pool in the first transaction of each group. These temporarily inflate the balance of the Pool and need to be subtracted to determine the actual reserve amount.&#x20;

## User Flows

### Swapper

1. Opt-In to Validator App (once)
   1. Prepare, sign, submit, wait for completion
2. Opt-In to Asset Out if necessary
   1. Prepare, sign, submit, wait for completion
3. Lookup Pool info for asset pair
4. Do Swap
   1. Prepare, sign, submit, wait for completion
5. Do Redeem (for excess amounts)
   1. Prepare, sign, submit, wait for completion

### Pooler

1. Opt-In to Validator App (once)
   1. Prepare, sign, submit, wait for completion
2. Lookup Pool info for asset pair
3. Create Pool if it doesn’t exist
   1. Prepare, sign, submit, wait for completion
4. Opt-In to Pool Liquidity Token Asset
   1. Prepare, sign, submit, wait for completion
5. Do Mint
   1. Prepare, sign, submit, wait for completion
6. Do Redeem (for excess liquidity Token)
   1. Prepare, sign, submit, wait for completion

### <br>


# Contracts

Source code on Github: <https://github.com/tinymanorg/tinyman-contracts-v1>

Audit Report by [Runtime Verification](http://runtimeverification.com/): <https://github.com/runtimeverification/publications/blob/main/reports/smart-contracts/Tinyman.pdf>

### Overview

The Tinyman contracts consist of a single stateful smart contract (the **Validator App**) and a template for a stateless smart contract for each Pool, the **Pool LogicSig**. The Validator app is created/deployed to the network by the Tinyman team. The Pool contract accounts are created from the Pool LogicSig template by the first Pooler who wishes to provide liquidity. Pool contract account addresses are discovered or verified by Swappers/Poolers using the Pool LogicSig template to generate a specific Pool LogicSig and retrieving the address.

#### Validator App <a href="#docs-internal-guid-b18fd459-7fff-aa47-087b-2bcfdededbc5" id="docs-internal-guid-b18fd459-7fff-aa47-087b-2bcfdededbc5"></a>

* Stateful smart contract
* Created by Tinyman core team
* Fully immutable
  * No updates allowed
  * No deletion allowed
* No global state
* Local state in Pool, Pooler, Swapper accounts (16 ints, 0 bytes)
* Contains validation and state manipulation logic for all operations

#### Pool Logic Signature Template

* A stateless smart contract template
* Template variables for asset 1 id, asset 2 id, and Validator App id
* Pool contract account address retrieved by hashing the completed template
* Contains logic to ensure only transactions part of expected transaction groups are signed
* Delegates most logic responsibility to the Validator app by ensuring the transaction group contains a call to the Validator App with appropriate arguments

### Version 1.1&#x20;

Source Code: <https://github.com/tinymanorg/tinyman-contracts-v1/tree/13acadd1a619d0fcafadd6f6c489a906bf347484>

Mainnet Validator App ID: [552635992](https://algoexplorer.io/application/552635992)

Testnet Validator App ID: [62368684](https://testnet.algoexplorer.io/application/62368684)

### Version 1.0

Source Code: <https://github.com/tinymanorg/tinyman-contracts-v1/tree/d1090f16d755b3898d2b8e03a2efa86133c30346>

Mainnet Validator App ID: [350338509](https://algoexplorer.io/application/350338509)

Testnet Validator App ID: [21580889](https://testnet.algoexplorer.io/application/21580889)


# Tinyman Testnet

Tinyman has launched on Algorand Mainnet ([app.tinyman.org](https://app.tinyman.org)) but Testnet is still available try things out without risks!

The contracts have been deployed to Algorand Testnet and the user interface is available at <https://testnet.tinyman.org>. This interface allows users to try out the UI and do pooling and swapping operations using Testnet assets (Algo & ASAs with no real world value).&#x20;

Please be aware that some features may appear on the testnet version before they are fully tested and complete.&#x20;

We do welcome feedback from all users of Tinyman Testnet/Mainnet so please let us know your thoughts and feelings on Discord or Telegram.

## Getting Started

*Some of these steps may not be necessary if you have previously used Algorand Testnet.*

1. Create/import an Algorand account to [MyAlgo](https://wallet.myalgo.com/) wallet.
2. Switch the MyAlgoWallet UI from Mainnet to Testnet in the top right corner.
3. Check your Algo balance and if necessary add some Testnet Algo to your account from <https://dispenser.testnet.aws.algodev.network/>
4. Opt-In to the Tiny USDC asset by clicking **Add Asset** <img src="/files/-MgRAvx0GZRpLclaF4ei" alt="" data-size="original">&#x20;
5. Enter the ID 21582668 and sign the transaction.
6. Within a minute you will receive some Tiny USDC in your account. You are welcome.
7. Go to <https://testnet.tinyman.org> and click **Connect to a Wallet**.
8. Watch out for blocked popups in the browser. You may need to allow popups from wallet.myalgo.com.
9. Now you can use the UI to swap your hard earned Tiny USDC or Algo for the other available assets.

## Testnet FAQ

### What about using other wallets?

We will be introducing other wallet options soon but the integrations are currently still in development so rather than frustrate you with them we have disabled them until they are ready.

### Why Tiny USDC?

We created the Tiny USDC ASA to have an ASA on Testnet that everyone can easily get their hands on. It is intended to mimic the USDC stable coin. In theory you could just start off with Algo and swap into other ASAs on Tinyman but unfortunately the supply of Algo is relatively limited on Testnet so each account can only receive a small amount at a time. As we created this ASA we control the full supply and so can provide much larger amounts without causing problems for the larger Algorand Testnet network.

If you wish to create new pools with other ASAs we encourage you to create a `TinyUSDC - Your ASA` pool too so that everyone has a way of swapping through the pools.

### What are the other Tiny\* ASAs?

We have also created Tiny USDt and Tiny Gold (so far) modeled on Mainnet assets to have a variety of assets available with various differences. Tiny Gold has 5 decimal places unlike the majority of assets which use 6. Tiny USDt should be roughly equivalent to Tiny USDC so that pool might be fun. It also is unusual in that it has a lower case letter in its Unit Name. We may add more assets to our collection as we find more test scenarios to reproduce.

### I love Tinyman so much I'm gonna HODL these even though this is Testnet!!!

A: Sure, ok. You do you.\
B: We might take them back. Yeah. We reserve the right to do that if we somehow run out of our 2^64 supply and need them for something more worthwhile.\
C: That's not a question.&#x20;

### I found a UI/UX issue. What should I do?

That's great. That's what Testnet is for. Please let us know in Discord/Telegram with as much detail as possible. Include screenshots/recordings if it helps.&#x20;

### I think I found a contract vulnerability! What should I do?

That's not so great. Please DO NOT exploit the vulnerbility on testnet if possible. Please test it on a private network where the transactions will not be seen by others.

Please email us at <security@tinyman.org> with the details of any possible vulnerability you find with specific references to the source code. DO NOT use this email for UI issues.

### Where are the contracts?

For technical users wishing to create an integration or examine the transactions:\
The stateful [Validator App](/tinyman-v1/design-doc#docs-internal-guid-b18fd459-7fff-aa47-087b-2bcfdededbc5) Id is currently [62368684](https://testnet.algoexplorer.io/application/62368684).\
See [Contracts](/tinyman-v1/contracts) for more details including links to the annotated source and audits.


# Disclaimer

Your use of the Tinyman protocol involves various risks, including, but not limited to, losses while digital assets are being supplied to the Tinyman protocol and losses due to the fluctuation of prices of tokens in a trading pair or liquidity pool. Before using the Tinyman protocol, you should review the relevant documentation to understand how the Tinyman protocol works. You are responsible for doing your diligence on the risks involved.

AS DESCRIBED IN THE TINYMAN PROTOCOL LICENSES, THE TINYMAN PROTOCOL IS PROVIDED "AS IS", AT YOUR OWN RISK, AND WITHOUT WARRANTIES OF ANY KIND. Although TM Distributed Development Ltd. ( "Tinyman" ) developed much of the initial code for the Tinyman protocol, it does not provide, own, or control the Tinyman protocol, which is run by smart contracts deployed on the Algorand blockchain. Accordingly, no developer or entity involved in creating the Tinyman protocol will be liable for any claims or damages whatsoever associated with your use, inability to use, or your interaction with other users of the Tinyman protocol, including any direct, indirect, incidental, special, exemplary, punitive or consequential damages, or loss of profits, cryptocurrencies, tokens, or anything else of value.


# Audits

### Runtime Verification

#### September 2021

Blog Post: <https://runtimeverification.com/blog/runtime-verification-audits-tinyman/>

Audit Report: <https://github.com/runtimeverification/publications/blob/main/reports/smart-contracts/Tinyman.pdf>

#### January 2022

Audit Report: <https://github.com/runtimeverification/publications/blob/main/reports/smart-contracts/Tinyman-security-review.pdf>

### Coinspect

#### January 2022

Audit Report: <https://github.com/coinspect/publications/blob/master/Coinspect%20-%20Smart%20Contract%20Update%20Review%20-%20Tinyman%20v220107.pdf>


# Security

## Bug Bounty Program

Tinyman has a bug bounty program for responsible disclosure of vulnerabilities in the V1.1 Contracts. See the blog post for further details: <https://tinymanorg.medium.com/tinyman-bug-bounty-campaign-b6c5e1ba7d6c>

## Contact

For sensitive security issues and responsible disclosure of *contract related bugs* please contact <security@tinyman.org>.


# Pool Lookup

Tinyman pools are discovered by generating a Pool LogicSig contract from the published template and computing the address associated with that LogicSig. The following variables must be replaced in the template to generate the LogicSig for a pool; Asset 1 ID, Asset 2 ID and Validator App ID.

See the Python SDK for the [reference implementation](https://github.com/tinymanorg/tinyman-py-sdk/blob/main/tinyman/v1/pools.py#L19) of this lookup.

{% hint style="danger" %}
All clients interacting with Tinyman pools MUST generate pool addresses in this way. It is not safe to assume any address is a Pool if it is not verified with this method.
{% endhint %}


# Transaction Specifications

Documentation on the transaction groups for each operation on Tinyman

## Pooler/Swapper Operations

{% content-ref url="/pages/-MaZwL6t55KUqMjqVoIZ" %}
[Bootstrap Pool](/v1-integration/transactions/bootstrap-pool)
{% endcontent-ref %}

{% content-ref url="/pages/-Ma\_2Qw1hlbQ14KithQl" %}
[OptIn](/v1-integration/transactions/optin)
{% endcontent-ref %}

{% content-ref url="/pages/-MaZyuuX-Ys-1fnfK--4" %}
[Mint](/v1-integration/transactions/mint)
{% endcontent-ref %}

{% content-ref url="/pages/-MaZzjoiDueUbaQ16vlu" %}
[Burn](/v1-integration/transactions/burn)
{% endcontent-ref %}

{% content-ref url="/pages/-Ma\_0J-2R1dZTCMehg92" %}
[Swap](/v1-integration/transactions/swap)
{% endcontent-ref %}

{% content-ref url="/pages/-Ma\_-Lr7zBURb5yEpK-0" %}
[Redeem](/v1-integration/transactions/redeem)
{% endcontent-ref %}

## Other&#x20;

{% content-ref url="/pages/-Ma\_1vdXp6YP\_Tmok8-b" %}
[Create Validator App](/v1-integration/transactions/create-validator-app)
{% endcontent-ref %}

{% content-ref url="/pages/-Ma\_2fahbk3JkNbc4Sxy" %}
[Redeem Protocol Fees](/v1-integration/transactions/redeem-protocol-fees)
{% endcontent-ref %}


# Bootstrap Pool

Setup a Pool for a pair of assets. The Pool account should be a LogicSig contract account.

### Transaction Group

0\. Pay - pay fees from Pooler to Pool

* fees to cover Tx 1,2,3,4
* Signed by Pooler

```
{
  "txn": {
    "type": "pay",
    "rcv": "{POOL_ADDRESS}",
    "snd": "{POOLER_ADDRESS",
    "amt": 960000,
    "fee": 1000,
    "note": "",
    ...
  },
  "sig": "{POOLER_SIG}",
}
```

1. App Call - OptIn call to Validator App with args \['bootstrap', asset1ID, asset2ID]

* signed by Pool LogicSig

```
{
  "txn": {
    "type": "appl",
    "snd": "{POOL_ADDRESS}",
    "apid": {VALIDATOR_APP_ID},
    "apan": 1, // OnComplete: OptIn
    "apaa": ['Ym9vdHN0cmFw', '{ASSET1_ID}', '{ASSET2_ID}'], // ['bootstrap', asset1ID, asset2ID]
    "apas": [{ASSET1_ID}, {ASSET2_ID}], // or just [{ASSET1_ID}] if asset 2 is Algo
    "fee": 1000,
    ...
  },
  "lsig": "{POOL_LOGICSIG}",
}
```

2\. AssetConfig - create asset for liquidity token

* signed by Pool LogicSig

```
{
  "txn": {
    "type": "acfg"
    "snd": "{POOL_ADDRESS}",
    "fee": 1000,
    "apar": {
      "an": "Tinyman Pool USDC-ALGO",
      "un": "TM1POOL"
      "au": "https://tinyman.org",
      "t": 18446744073709551615, // 0xFFFFFFFFFFFFFFFF
      "dc": 6,
    },
    ...
  },
  "lsig": "{POOL_LOGICSIG}",
}
```

3\. Asset OptIn - Pool opt in to Asset 1

* signed by Pool LogicSig

```
{
  "txn": {
    "type": "axfer",
    "arcv": "{POOL_ADDRESS}",
    "snd": "{POOL_ADDRESS}",
    "fee": 1000,
    "xaid": {ASSET_1_ID},
    ...
  },
  "lsig": "{POOL_LOGICSIG}",
}
```

4\. (Optional) Asset OptIn - Pool opt in to Asset 2

* Only if Asset 2 is not Algo
* signed by Pool LogicSig

```
{
  "txn": {
    "type": "axfer",
    "snd": "{POOL_ADDRESS}",
    "arcv": "{POOL_ADDRESS}",
    "fee": 1000,
    "xaid": {ASSET_2_ID},
    ...
  },
  "lsig": "{POOL_LOGICSIG}",
}
```

### Validator App State Changes

#### **Global State**

None

#### **Pool Account Local State**

* `a1: {int}` // ASSET1\_ID
* `a2: {int}` // ASSET2\_ID


# OptIn

OptIn to the Validator App for Poolers/Swappers. The user must OptIn to the app once before doing any mint/burn/swap/redeem transactions.

### Transaction:

1. App Call - OptIn to the Validator App
   * signed by Pooler/Swapper

```
{
  "txn": {
    "type": "appl",
    "snd": "{POOOLER/SWAPPER_ADDRESS}",
    "apid": {VALIDATOR_APP_ID},
    "apan": 1, // OnComplete: OptIn
    "apaa": []
    ...
  },
}
```

### Validator App State Changes

**Global State**

None

**User Account Local State**

None


# Swap

Swap one asset (ASA or Algo) for another with the Pool.

### Transaction Group

0\. Pay - pay fees in Algo from Swapper to Pool

* fees to cover Tx 1,2
* Signed by Swapper

```
{
  "txn": {
    "type": "pay",
    "rcv": "{POOL_ADDRESS}",
    "snd": "{SWAPPER_ADDRESS",
    "amt": 2000,
    "fee": 1000,
    ...
  },
  "sig": "{SWAPPER_SIG}",
}
```

1. App Call - NoOp call to Validator App with args \['swap', (fixed-input) or 'fo' (fixed-output)], with Swapper account
   * Signed by Pool LogicSig
   * Argument 1 'fi' specifies that the input (sell) is fixed but the output may vary with slippage
   * Argument 1 'fo' specifies that the output (buy) is fixed but the input may vary with slippage

```
{
  "txn": {
    "type": "appl",
    "snd": "{POOL_ADDRESS}",
    "apid": {VALIDATOR_APP_ID},
    "apan": 0, // OnComplete: NoOp
    "apaa": ['c3dhcA==', 'Zmk=' or 'Zm8='], // ['swap', 'fi' (fixed-input) or 'fo' (fixed-output)]
    "apas": [{ASSET1_ID}, {ASSET2_ID}, {LIQUIDITY_ASSET_ID}], // or just [{ASSET1_ID}, {LIQUIDITY_ASSET_ID}] if asset 2 is Algo
    "apat": [{SWAPPER_ADDRESS}],
    "fee": 1000,
    ...
  },
  "lsig": "{POOL_LOGICSIG}",
}
```

2\. (a) AssetTransfer - Transfer of sell asset from Swapper to Pool

* If sell asset is an ASA
* Signed by Swapper

```
{
  "txn": {
    "type": "axfer",
    "arcv": "{POOL_ADDRESS}",
    "snd": "{SWAPPER_ADDRESS}",
    "xaid": {SELL_ASSET_ID},
    "aamt": {SELL_ASSET_AMOUNT},
    "fee": 1000,
    ...
  },
  "sig": "{SWAPPER_SIG}",
}
```

2\. (b) Pay - Transfer of Algo from Swapper to Pool

* If sell asset is Algo
* Signed by Swapper

```
{
  "txn": {
    "type": "pay",
    "rcv": "{POOL_ADDRESS}",
    "snd": "{SWAPPER_ADDRESS}",
    "amt": {SELL_ASSET_AMOUNT},
    "fee": 1000,
    ...
  },
  "sig": "{SWAPPER_SIG}",
}
```

3\. (a) AssetTransfer - Transfer of buy asset from Pool to Swapper

* If buy asset is an ASA
* Signed by Pool LogicSig

```
{
  "txn": {
    "type": "axfer",
    "arcv": "{SWAPPER_ADDRESS}",
    "snd": "{POOL_ADDRESS}",
    "xaid": {BUY_ASSET_ID},
    "aamt": {BUY_ASSET_AMOUNT},
    "fee": 1000,
    ...
  },
  "lsig": "{POOL_LOGICSIG}",
}
```

3\. (b) Pay - Transfer of buy asset from Pool to Swapper

* If buy asset is Algo
* Signed by Pool LogicSig

```
{
  "txn": {
    "type": "pay",
    "rcv": "{SWAPPER_ADDRESS}",
    "snd": "{POOL_ADDRESS}",
    "amt": {BUY_ASSET_AMOUNT},
    "fee": 1000,
    ...
  },
  "lsig": "{POOL_LOGICSIG}",
}
```

#### Validator App State Changes

**Global State**

None

**Pool Account Local State**

* `o{ASSET1_ID}: {int}` // total outstanding unredeemed asset 1 amount
* `o{ASSET2_ID}: {int}` // total outstanding unredeemed asset 2 amount
* `p: {int}` // total unclaimed protocol fees amount

**Swapper Account Local State**

* `{POOL_ADDRESS}e{ASSET1_ID}: {int}` // excess asset 1 amount available for redemption
* `{POOL_ADDRESS}e{ASSET2_ID}: {int}` // excess asset 2 amount available for redemption


# Mint

Mint Pool assets in exchange for transferring assets to the Pool account.

### Transaction Group

0\. Pay - pay fees in Algo from Pooler to Pool

* fees to cover Tx 1,4
* Signed by Pooler

```
{
  "txn": {
  "type": "pay",
  "rcv": "{POOL_ADDRESS}",
  "snd": "{POOLER_ADDRESS",
  "amt": 2000,
  "fee": 1000,
  ...
  },
  "sig": "{POOLER_SIG}",
}
```

1. App Call - NoOp call to Validator App with args \['mint'], with Pooler account
   * Signed by Pool LogicSig

```
{
  "txn": {
    "type": "appl",
    "snd": "{POOL_ADDRESS}",
    "apid": {VALIDATOR_APP_ID},
    "apan": 0, // OnComplete: NoOp
    "apaa": ['bWludA=='], // ['mint']
    "apas": [{ASSET1_ID}, {ASSET2_ID}, {LIQUIDITY_ASSET_ID}], // or just [{ASSET1_ID}, {LIQUIDITY_ASSET_ID}] if asset 2 is Algo
    "apat": [{POOLER_ADDRESS}],
    "fee": 1000,
    ...
  },
  "lsig": "{POOL_LOGICSIG}",
}
```

2\. AssetTransfer - Transfer of asset 1 from Pooler to Pool

* Signed by Pooler

```
{
  "txn": {
    "type": "axfer",
    "arcv": "{POOL_ADDRESS}",
    "snd": "{POOLER_ADDRESS}",
    "xaid": {ASSET_1_ID},
    "aamt": {ASSET_1_AMOUNT},
    "fee": 1000,
    ...
  },
  "sig": "{POOLER_SIG}",
}
```

3\. (a) AssetTransfer - Transfer of asset 2 from Pooler to Pool

* If asset 2 is an ASA
* Signed by Pooler

```
{
  "txn": {
    "type": "axfer",
    "arcv": "{POOL_ADDRESS}",
    "snd": "{POOLER_ADDRESS}",
    "xaid": {ASSET_2_ID},
    "aamt": {ASSET_2_AMOUNT},
    "fee": 1000,
    ...
  },
  "sig": "{POOLER_SIG}",
}
```

3\. (b) Pay - Transfer of Algo from Pooler to Pool

* If asset 2 is Algo
* Signed by Pooler

```
{
  "txn": {
    "type": "pay",
    "rcv": "{POOL_ADDRESS}",
    "snd": "{POOLER_ADDRESS}",
    "amt": {ASSET_2_AMOUNT},
    "fee": 1000,
    ...
  },
  "sig": "{POOLER_SIG}",
}
```

4\. AssetTransfer - Transfer of liquidity token asset from Pool to Pooler

* Signed by Pool LogicSig
* Amount is minimum expected amount of liquidity token allowing for slippage

```
{
  "txn": {
    "type": "axfer",
    "arcv": "{POOLER_ADDRESS}",
    "snd": "{POOL_ADDRESS}",
    "xaid": {LIQUIDITY_ASSET_ID},
    "aamt": {LIQUIDITY_ASSET_AMOUNT},
    "fee": 1000,
    ...
  },
  "lsig": "{POOL_LOGICSIG}",
}
```

### Validator App State Changes

**Global State**

None

**Pool Account Local State**

* `o{LIQUIDITY_ASSET_ID}: {int}` // total outstanding unredeemed liquidity asset amount

**Pooler Account Local State**

* `{POOL_ADDRESS}e{LIQUIDITY_ASSET_ID}: {int}` // excess liquidity asset amount available for redemption


# Burn

Burn Pool liquidity assets in exchange for removing assets from the Pool.

### Transaction Group

0\. Pay - pay fees in Algo from Pooler to Pool

* fees to cover Tx 1,2,3
* Signed by Pooler

```
{
  "txn": {
  "type": "pay",
  "rcv": "{POOL_ADDRESS}",
  "snd": "{POOLER_ADDRESS",
  "amt": 3000,
  "fee": 1000,
  ...
  },
  "sig": "{POOLER_SIG}",
}
```

1. App Call - NoOp call to Validator App with args \['burn'], with Pooler account

```
{
  "txn": {
    "type": "appl",
    "snd": "{POOL_ADDRESS}",
    "apid": {VALIDATOR_APP_ID},
    "apan": 0, // OnComplete: NoOp
    "apaa": ['YnVybg=='], // ['burn']
    "apas": [{ASSET1_ID}, {ASSET2_ID}, {LIQUIDITY_ASSET_ID}], // or just [{ASSET1_ID}, {LIQUIDITY_ASSET_ID}] if asset 2 is Algo
    "apat": [{POOLER_ADDRESS}],
    "fee": 1000,
    ...
  },
  "lsig": "{POOL_LOGICSIG}",
}
```

2\. AssetTransfer - Transfer of asset 1 from Pool to Pooler

* Signed by Pool LogicSig
* Amount is minimum expected amount allowing for slippage

```
{
  "txn": {
    "type": "axfer",
    "arcv": "{POOLER_ADDRESS}",
    "snd": "{POOL_ADDRESS}",
    "xaid": {ASSET_1_ID},
    "aamt": {ASSET_1_AMOUNT},
    "fee": 1000,
    ...
  },
  "lsig": "{POOL_LOGICSIG}",
}
```

3\. (a) AssetTransfer - Transfer of asset 2 from Pool to Pooler

* If asset 2 is an ASA
* Signed by Pool LogicSig
* Amount is minimum expected amount allowing for slippage

```
{
  "txn": {
    "type": "axfer",
    "arcv": "{POOLER_ADDRESS}",
    "snd": "{POOL_ADDRESS}",
    "xaid": {ASSET_2_ID},
    "aamt": {ASSET_2_AMOUNT},
    "fee": 1000,
    ...
  },
  "lsig": "{POOL_LOGICSIG}",
}
```

3\. (b) Pay - Transfer of Algo from Pool to Pooler

* If asset 2 is Algo
* Signed by Pool LogicSig
* Amount is minimum expected amount allowing for slippage

```
{
  "txn": {
    "type": "pay",
    "rcv": "{POOLER_ADDRESS}",
    "snd": "{POOL_ADDRESS"},
    "amt": {ASSET_2_AMOUNT},
    "fee": 1000,
    ...
  },
  "lsig": "{POOL_LOGICSIG}",
}
```

4\. AssetTransfer - Transfer of liquidity token asset from Pooler to Pool

* Signed by Pooler

```
{
  "txn": {
    "type": "axfer",
    "arcv": "{POOL_ADDRESS}",
    "snd": "{POOLER_ADDRESS}",
    "xaid": {LIQUIDITY_ASSET_ID},
    "aamt": {LIQUIDITY_ASSET_AMOUNT},
    "fee": 1000,
    ...
  },
  "sig": "{POOLER_SIG}",
}
```

### Validator App State Changes

**Global State**

None

**Pool Account Local State**

* `o{LIQUIDITY_ASSET_ID}: {int}` // total outstanding unredeemed liquidity asset amount
* `o{ASSET1_ID}: {int}` // total outstanding unredeemed asset 1 amount
* `o{ASSET2_ID}: {int}` // total outstanding unredeemed asset 2 amount

**Pooler Account Local State**

* `{POOL_ADDRESS}e{LIQUIDITY_ASSET_ID}: {int}` // excess liquidity asset amount available for redemption
* `{POOL_ADDRESS}e{ASSET1_ID}: {int}` // excess asset 1 amount available for redemption
* `{POOL_ADDRESS}e{ASSET2_ID}: {int}` // excess asset 2 amount available for redemption


# Redeem

Claim back 'change' due to slippage in Mint/Burn/Swap process.

### Transaction Group

0\. Pay - pay fees in Algo from PoolerSwapper to Pool

* fees to cover Tx 1,2
* Signed by Pooler

```
{
  "txn": {
   "type": "pay",
   "rcv": "{POOL_ADDRESS}",
   "snd": "{POOLER/SWAPPER_ADDRESS",
   "amt": 2000,
   "fee": 1000,
   ...
  },
  "sig": "{POOLER/SWAPPER_SIG}",
}
```

1. App Call - NoOp call to Validator App with args \['redeem'], with Pooler/Swapper account
   * Signed by Pool LogicSig

```
{
  "txn": {
    "type": "appl",
    "snd": "{POOL_ADDRESS}",
    "apid": {VALIDATOR_APP_ID},
    "apan": 0, // OnComplete: NoOp
    "apaa": ['cmVkZWVt'], // ['redeem']
    "apas": [{ASSET1_ID}, {ASSET2_ID}, {LIQUIDITY_ASSET_ID}], // or just [{ASSET1_ID}, {LIQUIDITY_ASSET_ID}] if asset 2 is Algo
    "apat": [{POOLER/SWAPPER_ADDRESS}],
    "fee": 1000,
    ...
  },
  "lsig": "{POOL_LOGICSIG}",
}
```

2\. (a) AssetTransfer - Transfer of asset from Pool to Pooler/Swapper

* If asset is an ASA
* Signed by Pool LogicSig

```
{
  "txn": {
    "type": "axfer",
    "arcv": "{POOLER/SWAPPER_ADDRESS}",
    "snd": "{POOL_ADDRESS}",
    "xaid": {ASSET_ID},
    "aamt": {ASSET_AMOUNT},
    "fee": 1000,
    ...
  },
  "lsig": "{POOL_LOGICSIG}",
}
```

2\. (b) Pay - Transfer of Algo from Pool to Pooler/Swapper

* If asset is Algo
* Signed by Pool LogicSig

```
{
  "txn": {
    "type": "pay",
    "rcv": "{POOLER/SWAPPER_ADDRESS}",
    "snd": "{POOL_ADDRESS"},
    "amt": {ASSET_AMOUNT},
    "fee": 1000,
    ...
  },
  "lsig": "{POOL_LOGICSIG}",
}
```

### Validator App State Changes

**Global State**

None

**Pool Account Local State**

* `o{LIQUIDITY_ASSET_ID}: {int}` // total outstanding unredeemed liquidity asset amount
* `o{ASSET1_ID}: {int}` // total outstanding unredeemed asset 1 amount
* `o{ASSET2_ID}: {int}` // total outstanding unredeemed asset 2 amount

**Pooler/Swapper Account Local State**

* `{POOL_ADDRESS}e{LIQUIDITY_ASSET_ID}: {int}` // excess liquidity asset amount available for redemption
* `{POOL_ADDRESS}e{ASSET1_ID}: {int}` // excess asset 1 amount available for redemption
* `{POOL_ADDRESS}e{ASSET2_ID}: {int}` // excess asset 2 amount available for redemption


# Create Validator App

Create/deploy the Validator App.

{% hint style="info" %}
This transaction is sent once to create the Tinyman Validator App. No user should ever send this.
{% endhint %}

### Transaction

1. App Call - Create Validator App
   * signed by Creator

```
{
  "txn": {
    "type": "appl",
    "snd": "{CREATOR_ADDRESS}",
    "apid": 0,
    "apan": 0, // OnComplete: NoOp
    "apaa": ['Y3JlYXRl'] // ['create']
    "apls": {"nui": 16}, // Local State Schema: num_uints=16
    "apap": {APPROVAL_PROGRAM_BYTES},
    "apsu": {CLEAR_STATE_PROGRAM_BYTES},
    ...
  },
}
```

### Validator App State Changes

**Global State**

None

**Creator Account Local State**

None


# Redeem Protocol Fees

Transfer collected protocol fees to the CREATOR account.

{% hint style="info" %}
Note: The CREATOR must opt-in to the liquidity assets separately before receiving them.
{% endhint %}

### Transaction Group:

0\. Pay - pay fees in Algo from User to Pool

* fees to cover Tx 1,2
* Signed by User

```
{
  "txn": {
    "type": "pay",
    "rcv": "{POOL_ADDRESS}",
    "snd": "{USER_ADDRESS",
    "amt": 2000,
    ...
  },
  "sig": "{USER_SIG}",
}
```

1. App Call - NoOp call to Validator App with args \['fees']

* Signed by Pool LogicSig

```
{
  "txn": {
    "type": "appl",
    "snd": "{POOL_ADDRESS}",
    "apid": {VALIDATOR_APP_ID},
    "apan": 0, // OnComplete: NoOp
    "apaa": ['ZmVlcw=='], // ['fees']
    "apas": [{ASSET1_ID}, {ASSET2_ID}, {LIQUIDITY_ASSET_ID}], // or just [{ASSET1_ID}, {LIQUIDITY_ASSET_ID}] if asset 2 is Algo
    ...
  },
  "lsig": "{POOL_LOGICSIG}",
}
```

2\. AssetTransfer - Transfer of liquidity asset from Pool to CREATOR account

* Signed by Pool LogicSig

```
{
  "txn": {
    "type": "axfer",
    "arcv": "{CREATOR_ADDRESS}",
    "snd": "{POOL_ADDRESS}",
    "xaid": {LIQUIDITY_ASSET_ID},
    "aamt": {ASSET_AMOUNT},
    ...
  },
  "lsig": "{POOL_LOGICSIG}",
}
```

### Validator App State Changes

**Global State**

None

**Pool Account Local State**

* `o{LIQUIDITY_ASSET_ID}: {int}` // total outstanding unredeemed liquidity asset amount
* `p: {int}` // unclaimed protocol fee liquidity asset amount

**Creator Local State**

None


# Official SDKs

These are SDKs started and maintained by the Tinyman core development team.

{% hint style="warning" %}
Please note the [Disclaimer](/tinyman-v1/disclaimer) applies to these SDKs. Please review the Disclaimer and the Licenses of the individual SDKs. No warranty of any kind is provided for this software.&#x20;

Please review the code of each release carefully and do your own research before interacting with Algorand Mainnet using this software.
{% endhint %}

### Python SDK

{% embed url="<https://github.com/tinymanorg/tinyman-py-sdk>" %}

Please join us on [Discord](https://discord.gg/wvHnAdmEv6) to give feedback and ask questions.

### Javascript SDK

An official Javascript/Typescript SDK will be published in the coming months


# Community SDKs

These are unofficial SDKs started and maintained by community contributors outside of the  Tinyman core developer team.

### .NET SDK

<https://github.com/geoffodonnell/dotnet-tinyman-sdk>


# Tinyman Presentations

### Algorand Developer Office Hours - 5th October 2021

{% embed url="<https://www.youtube.com/watch?v=cSTdnnkOhyE>" %}

{% file src="/files/-MlG4FkX3ubfW\_I6xJ6t" %}
Presentation PDF
{% endfile %}


# Known Issues

This page lists issues with the contracts that became known since the deployment of the contracts. This page does not include known design limitations and assumptions detailed elsewhere.

### Latest Version ([V1.1](https://docs.tinyman.org/pages/-MabxT30lvniAf_hB3Zi#version-1.1))

There are currently no known issues.

### Previous Versions

{% content-ref url="/pages/4mG6UEkhlzaGjZsinNGb" %}
[2021-11-12 - Pool overflow errors](/known-issues/2021-11-12-pool-overflow-errors)
{% endcontent-ref %}


# 2021-11-12 - Pool overflow errors

{% hint style="warning" %}
This issue applies only to a previous version of the contracts ([V1.0](https://docs.tinyman.org/known-issues/pages/-MabxT30lvniAf_hB3Zi#version-1.0))
{% endhint %}

### The Problem

We have discovered that some small pools in Tinyman have become stuck and unable to process swaps/mints/burns. This happens because of an overflow error in the calculations in the contracts when the price (asset ratio) is extremely high. This currently affects pools with a price ratio greater than 10,000,000:1, in the microunits of the assets.

Unfortunately the calculation occurs at the start of the swap/mint/burn code block and uses the previously stored price value so this error affects all swap/mint/burn operations on these pools and cannot be fixed by adding extra assets to the pool. Pools that currently give these errors are unfortunately unrecoverable and any assets in these pools are permanently stuck as burn (remove liquidity) operations no longer work.

Asset ratios of this magnitude are outside the design limits of the system but the system does not enforce limits to prevent a problem occurring.

There are currently 95 affected pools with a total value of approximately $4000, according to Tinyman's own price information. The majority of the value in the assets in the pools belong to the asset creators so the true value lost is significantly less than this.

#### Details

The [calculation in question](https://github.com/tinymanorg/tinyman-contracts-v1/blob/main/contracts/validator_approval.teal#L390) involves a time component so the susceptibility of a pool to this issue is a function of price and time since the last swap/mint/burn. If `seconds_since_last_op * (price*10^6) >= 2**64` this problem occurs. A pool with a price of `100,000,000:1` must have an operation at least every 2 days to avoid this issue. For `10,000,000:1` it is 21 days, for `1,000,000:1` it is 213 days and for `100,000:1` it more than 2135 days (>5 years) days. For `USDC-Algo` at `1.98:1` it is 107332174 days (> 294,000 years).

The full list of all pools is it at the following link. The highlighted pools are currently stuck. The TTL columns indicate the time till becoming stuck for each pool:&#x20;

<https://docs.google.com/spreadsheets/d/e/2PACX-1vSItQ-wh5V57jV3o6sjB2nBmQ2VSqH_yn3TVlcGN6twzsox4Cew2Yecgx4nNmzVYzQIxL8Ferh9wS_U/pubhtml?gid=2124112322&single=true>

### FAQ

#### Can Tinyman recover these funds?

No, as a fully permissionless and trustless protocol the Tinyman developers have no special permissions on any pools. There is no way to recover the assets in these pools.

#### Can new pools be created with these assets?

The same asset pair cannot be used to create a new pool with the current contracts. This is because there is a unique deterministic pool address per asset pair.

#### Can Tinyman fix this issue?

The Tinyman developers cannot fix the current contracts but will aim to avoid this issue in future versions. There is no plan to migrate to new contracts immediately due to this issue.

#### What will Tinyman do to prevent this affecting more users?

* We will add more information to our documentation about the design limits of the system and the potential problems when those limits are exceeded.&#x20;
* We will update the web app UI to prevent the creation of pools with initial asset ratios that are likely to cause problems in short term.&#x20;
* We will update the UI to inform users when adding liquidity that their is a potential for liquidity to be lost of the price becomes greater than `1,000,000:1`


