Skip to content

noelialuz/Swapping

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

3 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ”„ Swapping

GitHub Repository Solidity License: MIT EVM Foundry

A minimal Solidity wrapper around Uniswap V2 Router02 that lets users swap ERC-20 tokens through a single swapTokens entry point.

Swapping is a learning-oriented Foundry project that integrates with an existing Uniswap V2–compatible router (Router02). Users approve the contract, call swapTokens with a token path and slippage parameters, and receive output tokens directly in their wallet. The contract pulls input tokens via OpenZeppelin SafeERC20, approves the router, and delegates the swap to swapExactTokensForTokens.

Key features:

  • πŸ” Single swapTokens() function wrapping swapExactTokensForTokens
  • 🧩 Minimal IV2Router02 interface β€” no full router dependency in source
  • πŸ›‘οΈ SafeERC20 for transferFrom and approve
  • πŸ“£ SwapTokens event with input/output token addresses and amounts
  • πŸ§ͺ Foundry test suite with optional Arbitrum mainnet fork
  • πŸ”— Configurable router address set at deploy time

πŸ“‹ Table of Contents

  1. Prerequisites & Dependencies
  2. Technologies & Versions
  3. Project Structure
  4. Quick Start
  5. Testing the Contract
  6. Architecture
  7. Security Policy
  8. Scripts & Commands
  9. Versioning
  10. License
  11. About the Author

πŸ“¦ Prerequisites & Dependencies

System requirements

Requirement Notes
πŸ–₯️ OS macOS, Linux, or Windows
πŸ”§ Git Required for cloning and submodules
βš’οΈ Foundry forge, cast, and anvil for build and test
🌐 RPC URL (optional) Arbitrum (or target chain) endpoint for fork tests

Quick minimum: Foundry installed and Solidity compiler 0.8.35.

Install Foundry

curl -L https://foundry.paradigm.xyz | bash
foundryup

Verify:

forge --version
cast --version

Project dependencies

Dependency Role
forge-std Foundry testing utilities and cheatcodes
OpenZeppelin Contracts IERC20 and SafeERC20 for safe token transfers

After cloning, install submodules if needed:

git clone https://github.com/noelialuz/Swapping.git
cd Swapping
forge install

πŸ›  Technologies & Versions

Technology Version Role
Solidity 0.8.35 Smart contract language
Foundry latest (foundryup) Build, test, and CLI interaction
OpenZeppelin Contracts vendored in lib/ ERC-20 interfaces and SafeERC20
Uniswap V2 Router02 external (on-chain) DEX router for token swaps
EVM β€” Execution environment (Ethereum-compatible chains)
SPDX MIT License identifier in source

πŸ“ Project Structure

Swapping/
β”œβ”€β”€ foundry.toml                    # Foundry configuration
β”œβ”€β”€ README.md                       # Project documentation
β”œβ”€β”€ lib/
β”‚   β”œβ”€β”€ forge-std/                  # Foundry standard library
β”‚   └── openzeppelin-contracts/     # OpenZeppelin (IERC20, SafeERC20)
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ SwapApp.sol                 # Main swap wrapper contract
β”‚   └── interfaces/
β”‚       └── IV2Router02.sol         # Minimal Router02 interface
β”œβ”€β”€ test/
β”‚   └── SwapApp.t.sol               # Unit and fork tests
└── .vscode/                        # Editor remappings (optional)

This repository is a Foundry-first project. The router itself is not deployed here β€” you point SwapApp at an existing V2-compatible Router02 address on your target network.


πŸš€ Quick Start

1. Clone and build

git clone https://github.com/noelialuz/Swapping.git
cd Swapping
forge build

2. Deploy

Deploy SwapApp with the Router02 address for your network.

Example β€” Arbitrum mainnet Router02:

Field Value
Contract SwapApp
V2Router02Address_ 0x4752ba5DBc23f44D87826276BF6Fd6b1C372aD24

Using Foundry (local or scripted):

# Example: deploy to a local Anvil node
anvil &
forge create src/SwapApp.sol:SwapApp \
  --rpc-url http://127.0.0.1:8545 \
  --private-key <DEPLOYER_PRIVATE_KEY> \
  --constructor-args 0x4752ba5DBc23f44D87826276BF6Fd6b1C372aD24

Use the correct Router02 address for your chain. The address above is for reference in the included Arbitrum fork tests.

3. Swap tokens

// 1. User approves SwapApp to spend tokenIn.
IERC20(tokenIn).approve(swapAppAddress, amountIn);

// 2. Build path: [tokenIn, tokenOut] (add intermediates for multi-hop).
address[] memory path = new address[](2);
path[0] = tokenIn;
path[1] = tokenOut;

// 3. Call swapTokens with slippage and deadline.
swapApp.swapTokens(amountIn, amountOutMin, path, deadline);
// Output tokens are sent directly to msg.sender by the router.

Example β€” USDT β†’ DAI on Arbitrum (test constants):

Token Address
USDT 0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9
DAI 0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1

πŸ§ͺ Testing the Contract

Option A β€” Local tests (no fork)

Runs deployment smoke test only:

forge test -vv

Expected: testHasBeenDeployedCorrectly passes. The swap integration test requires a mainnet fork (see below).

Option B β€” Arbitrum fork test (recommended)

The swap test forks Arbitrum mainnet and uses a funded address with USDT:

forge test -vvvv \
  --fork-url https://arb1.arbitrum.io/rpc \
  --match-test testSwapTokensCorrectly

Or run the full suite on a fork:

forge test -vv --fork-url https://arb1.arbitrum.io/rpc

What the fork test verifies:

Step Action
1 Deploy SwapApp with Arbitrum Router02
2 Impersonate a USDT holder on Arbitrum
3 Approve SwapApp and call swapTokens(USDT β†’ DAI)
4 Assert USDT balance decreased and DAI balance increased

Note: Fork tests depend on live chain state (token balances, liquidity). If the hard-coded holder address no longer has USDT, update user in test/SwapApp.t.sol.

Option C β€” Manual interaction with cast

After deploying SwapApp on a testnet or fork:

# Approve SwapApp (from user wallet)
cast send $USDT "approve(address,uint256)" $SWAP_APP $AMOUNT_IN --private-key $USER_PK

# Swap USDT for DAI
cast send $SWAP_APP \
  "swapTokens(uint256,uint256,address[],uint256)" \
  $AMOUNT_IN \
  $AMOUNT_OUT_MIN \
  "[$USDT,$DAI]" \
  $DEADLINE \
  --private-key $USER_PK

Option D β€” Remix (optional)

  1. Copy src/SwapApp.sol and src/interfaces/IV2Router02.sol into Remix.
  2. Add OpenZeppelin imports via Remix GitHub import or flatten the contract.
  3. Compile with Solidity 0.8.35.
  4. Deploy with your network's Router02 address.
  5. Approve tokens to the deployed contract, then call swapTokens.

πŸ—„ Architecture

Swapping consists of a thin wrapper contract that sits between the user and an on-chain DEX router:

flowchart LR
    User["πŸ‘€ User"]
    SA["πŸ”„ SwapApp"]
    R["πŸ“‘ V2 Router02"]
    Pool["πŸ’§ Uniswap V2 Pools"]

    User -->|"approve + swapTokens()"| SA
    SA -->|"transferFrom (tokenIn)"| SA
    SA -->|"approve + swapExactTokensForTokens"| R
    R --> Pool
    R -->|"tokenOut to user"| User
Loading

Contract responsibilities

Contract / Interface Responsibility
SwapApp Pulls input tokens, approves router, executes swap, emits event
IV2Router02 Minimal interface for swapExactTokensForTokens

Core state

Variable Visibility Description
V2Router02Address public Address of the Uniswap V2–compatible router

Write functions

Function Access Description
swapTokens(uint256 amountIn_, uint256 amountOutMin_, address[] path_, uint256 deadline_) external Transfers path_[0] from caller, swaps via router, sends output to caller

Events

event SwapTokens(address tokenIn, address tokenOut, uint256 amountIn, uint256 amountOut);

Swap flow

  1. Approve β€” User grants SwapApp allowance on the input ERC-20.
  2. Transfer in β€” SwapApp pulls amountIn_ from msg.sender using SafeERC20.
  3. Router approve β€” Contract approves the router to spend the input token.
  4. Swap β€” Router executes swapExactTokensForTokens; output goes to msg.sender.
  5. Event β€” SwapTokens logs token addresses and amounts.

Parameters

Parameter Description
amountIn_ Exact input token amount
amountOutMin_ Minimum acceptable output (slippage protection)
path_ Token addresses from input to output (e.g. [USDT, DAI])
deadline_ Unix timestamp after which the swap reverts

πŸ” Security Policy

⚠️ This project is intended for learning and demonstration purposes only. It has not undergone a professional security audit.

Known considerations

Area Detail
πŸŽ“ Educational scope Not production-ready; use at your own risk
πŸ”— External router trust Swaps depend entirely on the configured Router02 and underlying pools
πŸ’Έ No fee-on-transfer handling Assumes standard ERC-20 behavior; deflationary/rebasing tokens may break swaps
⏱️ Deadline & slippage Caller must set sensible deadline_ and amountOutMin_; no defaults enforced
πŸ”“ Unlimited approve Contract approves the router for the full amountIn_ per swap
🌐 Network-specific Router and token addresses differ per chain β€” verify before deployment
πŸ§ͺ Test first Use fork tests or a testnet before mainnet

Before using in production

  • Review all logic in src/SwapApp.sol
  • Run fork tests against your target chain and router
  • Consider a professional audit
  • Add pausing, access control, or router upgrade patterns if needed
  • Validate token paths and liquidity on-chain

Reporting vulnerabilities

If you discover a security issue, please do not open a public GitHub issue. Contact the repository owner directly (see About the Author).

Smart contracts carry inherent technical and financial risk. Use this repository at your own responsibility.


πŸ“œ Scripts & Commands

Command Description
forge build Compile contracts
forge test -vv Run tests locally
forge test --fork-url <RPC_URL> Run tests against a forked network
forge test -vvvv --fork-url https://arb1.arbitrum.io/rpc --match-test testSwapTokensCorrectly Verbose Arbitrum swap test
forge create src/SwapApp.sol:SwapApp --constructor-args <ROUTER> Deploy via CLI
anvil Start a local Ethereum node
cast send ... "swapTokens(...)" Execute a swap on a deployed contract

πŸ“Œ Versioning

This project follows Semantic Versioning 2.0.0:

Segment Meaning
MAJOR Breaking changes to contract interface or behavior
MINOR New features, backward-compatible
PATCH Bug fixes, docs, no breaking API changes

Release history

Version Status Notes
0.1.0 Current Initial release: SwapApp, IV2Router02, Foundry tests with Arbitrum fork

Tag releases on GitHub:

git tag -a v0.1.0 -m "Initial SwapApp release with V2 router integration"
git push origin v0.1.0

πŸ“„ License

Swapping is released under the MIT License β€” see the SPDX header in src/SwapApp.sol.

SPDX identifier: // SPDX-License-Identifier: MIT


πŸ‘€ About the Author

Name Noelia Luz FernΓ‘ndez
GitHub @Noelialuz
LinkedIn https://www.linkedin.com/in/noelia-luz-fernandez-03404440/
Email noelia_luz_fernandez@hotmail.com

πŸ“š Learn More

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors