🔬
JediSwap
  • 👋Welcome to JediSwap
  • 🛠️Become a contributor
  • 🎁DeFi spring STRK incentives for v2
  • 🎁DeFi Spring STRK incentives for v1
  • FAQ
  • How to use JediSwap
    • How to set up a Starknet wallet
      • How to set up an Argent X wallet
      • How to set up an Argent Web Wallet
      • How to set up a Braavos wallet
    • How to bridge assets to Starknet
      • How to bridge to Starknet using Starkgate
      • How to bridge to Starknet using Orbiter Finance
      • How to bridge to Starknet using LayerSwap
    • How to make a swap
    • How to add liquidity
      • How to add liquidity V1
      • How to add liquidity V2
    • How to ZAP
      • How to ZAP from Ethereum L1 to Starknet
      • How to ZAP on Starknet
    • Points
      • LP Leaderboard
      • Volume Leaderboard
  • For Developers
    • Jediswap v2
      • Core
        • jediswap_v2_factory
        • jediswap_v2_pool
      • Periphery
        • jediswap_v2_nft_position_manager
        • jediswap_v2_swap_router
      • Contract Addresses
      • Deprecated Contract Addresses
    • Jediswap v1
      • Smart Contract integration
        • Implement a swap
        • Providing liquidity
        • Pair Addresses
      • Smart contract reference
        • Router
        • Pair
        • Factory
        • Pair (ERC 20)
  • Risks associated with JediSwap
Powered by GitBook
On this page
  • Using the Router contract
  • Example
  • 1. transferFrom
  • 2. approve
  • 3. swap_exact_tokens_for_tokens
  • Safety Considerations
  1. For Developers
  2. Jediswap v1
  3. Smart Contract integration

Implement a swap

PreviousSmart Contract integrationNextProviding liquidity

Last updated 1 year ago

When trading from a smart contract, an external price source is required. Without this, trades can be front-run to make a hefty loss.

Read for more.

Using the Router contract

The easiest way to safely swap tokens is to use the router, which provides a variety of methods to safely swap to and from different assets. There are two functions for swapping to/from an exact amount of tokens.

First, you must use an external price source to calculate the safety parameters for the function you'd like to call. This is either the minimum amount received when selling an exact input or the maximum amount you are willing to pay when buying an exact output amount

It is also important to ensure that your contract controls enough tokens to make the swap and has granted approval to the router to withdraw these many tokens.

Example

Imagine you want to swap exactly 100 DAI for as much ETH as possible from your smart contract. These are the steps your smart contract needs to follow.

1. transferFrom

Before swapping, your smart contract needs to be in control of 100 DAI. The easiest way to accomplish this is by calling transferFrom on DAI with the owner set to caller:

let (caller) = get_caller_address()
let (contract_address) = get_contract_address()
IERC20.transferFrom(contract_address=DAI_address, sender=caller, recipient=contract_address, amount=amount)

2. approve

Now that your contract owns 100 DAI, you need to approve the router contract to withdraw this DAI:

 _IERC20.approve(contract_address= DAI_address, spender= router, amount= amount)_ 

3. swap_exact_tokens_for_tokens

Now we're ready to swap:

 _let (deadline) = get_block_timestamp()
let (local path : felt*) = alloc()
assert [path] = DAI_address
assert [path+1] = ETH_address
let path_len = 2_ 
 _IRouter.swap_exact_tokens_for_tokens(contract_address = router, amountIn = amount, amountOutMin = amountOutMin, path_len = path_len, path = path, to = contract_address, deadline = deadline)_ 

Safety Considerations

Because Starknet transactions occur in an adversarial environment, smart contracts that do not perform safety checks can be exploited for profit. If a smart contract assumes that the current price on JediSwap is a "fair" price without performing safety checks, it is vulnerable to manipulation. Exp: A bad actor could easily insert transactions before and after the swap (a "sandwich" attack), causing the smart contract to trade at a much worse price, profit from this at the trader's expense, and then return the contracts to their original state. (One important caveat is that these types of attacks are mitigated by trading in extremely liquid pools and/or at low values.)

The best way to protect against these attacks is to use an external price feed or "price oracle". The best "oracle" is simply traders' off-chain observation of the current price, which can be passed into the trade as a safety check. This strategy is best for situations where users initiate trades on their own behalf

However, when an off-chain price can't be used, an on-chain oracle should be used instead. Determining the best oracle for a given situation is not within the scope of this guide.

safety considerations