> For the complete documentation index, see [llms.txt](https://docs.pharos.xyz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.pharos.xyz/developer-guide/foundry/write-your-first-uniswap-contract.md).

# Write Your First Uniswap Contract

This guide will walk you through the process of creating and deploying a simple Uniswap-like decentralized exchange (DEX) contract on the Pharos blockchain. By the end of this guide, you will have a basic understanding of how automated market makers (AMMs) work and how to implement a simple DEX.

### Prerequisites

Before you begin, ensure you have the following:

* Git: Used for code management and obtain examples.
* Node.js: Install it from [nodejs.org](https://nodejs.org/).
* Pharos Devnet/Testnet Access: Access to a Pharos node (local or remote) for interacting with the blockchain.

### Setup 1: Install Foundry

* [Foundry](https://book.getfoundry.sh/getting-started/installation)

### Setup 2: Set Up the Project

Clone the example repo:

```shell
git clone https://github.com/PharosNetwork/examples
cd examples/uniswap/foundry/contract
```

Install OpenZeppelin Contracts:

* Foundry uses forge to manage dependencies. Install OpenZeppelin contracts:

```shell
forge install OpenZeppelin/openzeppelin-contracts --no-git
```

### Step 3: Write the Uniswap Contract

Create a New Solidity File:

* Create a new file for your uniswap contract:

```shell
touch src/Uniswap.sol
```

Write the uniswap Contract:

* Open `src/Uniswap.sol` in your favorite text editor and add the following code:

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";

contract Uniswap {
    address public tokenA;
    address public tokenB;
    uint256 public reserveA;
    uint256 public reserveB;

    constructor(address _tokenA, address _tokenB) {
        tokenA = _tokenA;
        tokenB = _tokenB;
    }

    function addLiquidity(uint256 amountA, uint256 amountB) external {
        require(IERC20(tokenA).transferFrom(msg.sender, address(this), amountA), "Transfer failed");
        require(IERC20(tokenB).transferFrom(msg.sender, address(this), amountB), "Transfer failed");

        reserveA += amountA;
        reserveB += amountB;
    }

    function removeLiquidity(uint256 amountA, uint256 amountB) external {
        require(reserveA >= amountA && reserveB >= amountB, "Insufficient reserves");

        reserveA -= amountA;
        reserveB -= amountB;

        require(IERC20(tokenA).transfer(msg.sender, amountA), "Transfer failed");
        require(IERC20(tokenB).transfer(msg.sender, amountB), "Transfer failed");
    }

    function swapAToB(uint256 amountA) external {
        uint256 amountB = (amountA * reserveB) / reserveA;
        require(IERC20(tokenA).transferFrom(msg.sender, address(this), amountA), "Transfer failed");
        require(IERC20(tokenB).transfer(msg.sender, amountB), "Transfer failed");

        reserveA += amountA;
        reserveB -= amountB;
    }

    function swapBToA(uint256 amountB) external {
        uint256 amountA = (amountB * reserveA) / reserveB;
        require(IERC20(tokenB).transferFrom(msg.sender, address(this), amountB), "Transfer failed");
        require(IERC20(tokenA).transfer(msg.sender, amountA), "Transfer failed");

        reserveB += amountB;
        reserveA -= amountA;
    }
}
```

Compile the Smart Contract:

* Use forge to compile the contract:

```shell
forge build
```

Test the Smart Contract

* Use forge to test the contract:

```shell
forge test
```

### Step 4: Deploy the Uniswap Contract

Create a Deployment Script:

* Create a new file for the deployment script:

```shell
touch script/DeployUniswap.s.sol
```

Write the Deployment Script:

* Open script/DeployUniswap.s.sol and add the following code:

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "forge-std/Script.sol";
import "../src/Uniswap.sol";

contract DeployUniswap is Script {
    function run() external {
        uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY");
        vm.startBroadcast(deployerPrivateKey);

        address tokenA = address(0xAA); // Replace with the address of token A
        address tokenB = address(0xBB); // Replace with the address of token B

        Uniswap uniswap = new Uniswap(tokenA, tokenB);

        vm.stopBroadcast();
    }
}
```

Set the private key:

```shell
export PRIVATE_KEY=<your private key>
```

Deploy the Contract:

* Use forge to deploy the contract to the Pharos Testnet:

```shell
forge script script/DeployUniswap.s.sol --rpc-url <PHAROS_RPC_URL> --broadcast
```

### Step 5: Interact with the Uniswap Contract

Open `script/InteractUniswap.s.sol` and add the following code:

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "forge-std/Script.sol";
import "../src/Uniswap.sol";
import "../test/Uniswap.t.sol";

contract DeployUniswap is Script {
    function run() external {
        uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY");
        vm.startBroadcast(deployerPrivateKey);

        MockERC20 tokenA = new MockERC20("TokenA", "TKA");
        MockERC20 tokenB = new MockERC20("TokenB", "TKB");

        Uniswap uniswap = new Uniswap(address(tokenA), address(tokenB));

        console.log("TokenA deployed at:", address(tokenA));
        console.log("TokenB deployed at:", address(tokenB));
        console.log("Uniswap deployed at:", address(uniswap));

        vm.stopBroadcast();
    }
}
```

Execute the script using forge:

```shell
forge script script/InteractUniswap.s.sol --rpc-url <PHAROS_RPC_URL> --broadcast
```

### Troubleshooting

* **Contract Deployment Fails**: Ensure you have enough testnet tokens to cover the deployment cost.
* **Interaction Issues**: Verify that the contract address and ABI are correct.
* **Test Failures**: Check the test output for detailed error messages and adjust the tests accordingly.

### Conclusion

This guide provides a comprehensive introduction to creating and deploying a Uniswap-like contract on the Pharos blockchain using Foundry. If you encounter any issues, refer to the Foundry documentation or the troubleshooting section. Happy building! 🚀


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://docs.pharos.xyz/developer-guide/foundry/write-your-first-uniswap-contract.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
