# ATM Contracts

As part of the Teller protocol, depositors provide liquidity to decentralized, non-custodial markets within the Teller ATM to earn passive income or interest. Teller's non-custodial markets are, in essence, liquidity pools designated to an underlying asset. Assets within the ATM's liquidity pools can be borrowed through unsecured loans by connecting a bank account, or secured loans, by providing 20% collateral or more.‌

Developers can build applications that integrate with these liquidity pools. In order to allow users to deposit or withdraw their assets into a pool, the developer's application must call the functions located in the [lending pool smart contract](https://github.com/teller-protocol/teller-protocol-v1/blob/develop/contracts/base/LendingPool.sol).‌

## deposit()

`function deposit( uint256 amount )`‌

`amount` represents the amount of an asset that a user wishes to deposit into the liquidity pool.

Please note, the contract call should be made from the depositors' wallet address, as the minted tokens will be transferred to`msg.sender`

| Parameter Name | Type    | Description                |
| -------------- | ------- | -------------------------- |
| `amount`       | uint256 | The amount to be deposited |

‌

Upon depositing assets to the protocol, tTokens representing proof of deposit are minted and given to the depositor in exchange.

![](https://gblobscdn.gitbook.com/assets%2F-MCFeD1LoLRehnuodvA7%2F-MEJecqJsBjSIlzYVZnU%2F-MEJezsqitcc8vseNQIL%2FATM%20Deposit%20Diagram.png?alt=media\&token=3b8f3b60-ffe6-4c7d-80f3-8a316fdea8c6)Deposit process flow

{% tabs %}
{% tab title="Solidity" %}

```javascript
/* Interfaces */
import "@teller-protocol-v1/contracts/interfaces/LendingPoolInterface.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

/* Retrieve contract */
LendingPoolInterface public lendingPool; 
lendingPool = LendingPoolInterface(address("0x36633E18592e30eDfC7ffe1FD4B5EA7BA21ac20E")); // Ropsten address 

/* Approve LendingPool to move user's funds */
address usdc = address("0x20572e4c090f15667cf7378e16fad2ea0e2f3eff"); // Ropsten address
uint256 amount = 1000;
IERC20(usdc).approve(lendingPool.address, amount, { from: user });

/* Deposit user funds into lending pool */
lendingPool.deposit(amount, { from:user });
```

{% endtab %}

{% tab title="Web3.js" %}

```javascript
/* Import contract artifact */
import LendingPool from "./LendingPool.json";
import TUSDC from "./TUSDC.json";

/* Initialize contract instance */
const lendingPoolAddress = "0x36633E18592e30eDfC7ffe1FD4B5EA7BA21ac20E"; // Ropsten address
const lendingPoolInstance = new web3.eth.Contract(LendingPool.abi, lendingPoolAddress);

/* Approve ERC20 transfer from user */
const usdcAddress = "0x20572e4c090f15667cf7378e16fad2ea0e2f3eff";
const usdcInstance = new web3.eth.Contract(ZUSDC.abi, usdcAddress);
const depositAmount = 1000;
await usdcInstance.methods.approve(lendingPoolAddress, depositAmount).send( {from: user});

/* Deposit assets into LendingPool */
await lendingPoolInstance.methods.deposit(depositAmount, { from: user });
```

{% endtab %}
{% endtabs %}

## withdraw()

`function withdraw( uint256 amount )`‌

Contrary to the deposit() method, and as the function's name suggests, `amount` here represents the amount of an asset that a user wishes to withdraw from the liquidity pool.

| Parameter Name | Type    | Description                |
| -------------- | ------- | -------------------------- |
| `amount`       | uint256 | The amount to be withdrawn |

Similar to the deposit() method, the contract call needs to be made from the depositors' address as the assets will be sent to`msg.sender`‌

When a user initiates a withdrawal of their asset, their tTokens will be burned and their assets subsequently sent to their wallet address.\
![](https://gblobscdn.gitbook.com/assets%2F-MCFeD1LoLRehnuodvA7%2F-MEJf2I9Z_hJ1oXw2a8F%2F-MEJjK-s-SljaiIfi5Na%2FATM%20Withdrawal%20Diagram.png?alt=media\&token=c69e0350-f198-44c3-b3fe-d84c10c2af2a)Withdrawal process flow

{% tabs %}
{% tab title="Solidity" %}

```javascript
/* Interfaces */
import "@teller-protocol-v1/contracts/interfaces/LendingPoolInterface.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

/* Retrieve contract */
LendingPoolInterface public lendingPool; 
lendingPool = LendingPoolInterface(address("0x36633E18592e30eDfC7ffe1FD4B5EA7BA21ac20E)); // Ropsten address 

/* Deposit user funds into lending pool */
lendingPool.withdraw(amount, { from:user });
```

{% endtab %}

{% tab title="Web3.js" %}

```javascript
/* Import contract artifact */
import LendingPool from "./LendingPool.json";

/* Initialize contract instance */
const lendingPoolAddress = "0x36633E18592e30eDfC7ffe1FD4B5EA7BA21ac20E"; // Ropsten address
const lendingPoolInstance = new web3.eth.Contract(LendingPool.abi, lendingPoolAddress);

/* Deposit assets into LendingPool */
const withdrawalAmount = 1000;
await lendingPoolInstance.methods.withdraw(withdrawalAmount, { from: user });
```

{% endtab %}
{% endtabs %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.teller.org/teller-docs/protocol/core-contracts/atm-contracts.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
