<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: esteblock</title>
    <description>The latest articles on DEV Community by esteblock (@esteblock).</description>
    <link>https://dev.to/esteblock</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1026679%2Fdf4fef99-0b4f-4829-8320-443f2ba16f73.png</url>
      <title>DEV Community: esteblock</title>
      <link>https://dev.to/esteblock</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/esteblock"/>
    <language>en</language>
    <item>
      <title>Fullstack Blockchain Job Offer</title>
      <dc:creator>esteblock</dc:creator>
      <pubDate>Mon, 05 Aug 2024 23:12:09 +0000</pubDate>
      <link>https://dev.to/paltalabs/fullstack-blockchain-job-offer-4k2j</link>
      <guid>https://dev.to/paltalabs/fullstack-blockchain-job-offer-4k2j</guid>
      <description>&lt;p&gt;Full-time Position (Internships also accepted)&lt;/p&gt;

&lt;p&gt;🧑‍💻 𝗝𝗼𝗶𝗻 𝗣𝗮𝗹𝘁𝗮𝗹𝗮𝗯𝘀 𝗮𝗻𝗱 𝗯𝗲 𝗽𝗮𝗿𝘁 𝗼𝗳 𝘁𝗵𝗲 𝗕𝗹𝗼𝗰𝗸𝗰𝗵𝗮𝗶𝗻 𝗿𝗲𝘃𝗼𝗹𝘂𝘁𝗶𝗼𝗻!&lt;/p&gt;

&lt;p&gt;🥑 𝗣𝗮𝗹𝘁𝗮𝗹𝗮𝗯𝘀 excels in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;dApp Creation: Innovative decentralized applications.&lt;/li&gt;
&lt;li&gt;Blockchain Consulting: Expert guidance in integration.&lt;/li&gt;
&lt;li&gt;Continuous Learning: Deep knowledge in Blockchain.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What have we done? We created the first Decentralized Exchange with Smart Contracts on the Stellar Blockchain. See &lt;a href="https://soroswap.finance/" rel="noopener noreferrer"&gt;Soroswap.Finance Webpage&lt;/a&gt; | &lt;a href="https://github.com/soroswap/" rel="noopener noreferrer"&gt;Soroswap Github&lt;/a&gt;. We also have another DeFi investment project and are constantly creating tools for developers. Additionally, we are creating content and educating.&lt;/p&gt;

&lt;p&gt;Learn more on our &lt;a href="https://www.linkedin.com/company/paltalabs" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;, &lt;a href="https://x.com/PaltaLabs" rel="noopener noreferrer"&gt;Twitter/X&lt;/a&gt;, &lt;a href="https://paltalabs.io/" rel="noopener noreferrer"&gt;Website&lt;/a&gt;, and &lt;a href="https://github.com/orgs/paltalabs/repositories" rel="noopener noreferrer"&gt;Github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;📝 Benefits of joining us:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🤑 Intern Salary USD 500-1200 &lt;/li&gt;
&lt;li&gt;🤑 Professional Salary USD 1200-3500&lt;/li&gt;
&lt;li&gt;🌍 Remote Work: Flexibility to work from anywhere.&lt;/li&gt;
&lt;li&gt;🕒 Flexible Hours: Adapt your schedule.&lt;/li&gt;
&lt;li&gt;🏋️‍♀️ Activity Bonus: Stay active with incentives.&lt;/li&gt;
&lt;li&gt;🌴 24 Vacation Days: Generous time off.&lt;/li&gt;
&lt;li&gt;🤓 Learning Environment: Support and collaboration.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🔍 𝗪𝗵𝗮𝘁 𝘆𝗼𝘂 𝘄𝗶𝗹𝗹 𝗱𝗼:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;📱 dApp Development: Build decentralized applications.&lt;/li&gt;
&lt;li&gt;🤖 Bot Construction: Design automation bots.&lt;/li&gt;
&lt;li&gt;📝 Script Development: Create functional scripts.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🔧 𝗥𝗲𝗾𝘂𝗶𝗿𝗲𝗱 𝗧𝗲𝗰𝗵𝗻𝗶𝗰𝗮𝗹 𝗦𝗸𝗶𝗹𝗹𝘀:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🧠🔗 Blockchain Knowledge: Understand how a Blockchain works.&lt;/li&gt;
&lt;li&gt;🖥️💼 Backend Proficiency: Competence in backend languages like Python, Typescript, or Javascript.&lt;/li&gt;
&lt;li&gt;🌐⚛️ Frontend with React: Skill in frontend development using React.&lt;/li&gt;
&lt;li&gt;📂🔄 Version Control with Git: Mastery of Git for version control.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🧠 𝗥𝗲𝗾𝘂𝗶𝗿𝗲𝗱 𝗦𝗼𝗳𝘁 𝗦𝗸𝗶𝗹𝗹𝘀:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;⏳📅 Time Management: Ability to manage your time well.&lt;/li&gt;
&lt;li&gt;🧘‍♂️😌 Stress Management: Ability to work under pressure and handle stress.&lt;/li&gt;
&lt;li&gt;🎯🔍 Focus: Great ability to concentrate and pay attention to detail.&lt;/li&gt;
&lt;li&gt;💬📖 Communication: Fluent in Spanish and proficient in reading and writing in English.&lt;/li&gt;
&lt;li&gt;🌟🚀 Motivation for Web3: Highly motivated and enthusiastic about working in the Web3 ecosystem.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;✨ 𝗗𝗲𝘀𝗶𝗿𝗲𝗱 𝗦𝗸𝗶𝗹𝗹𝘀 (𝗡𝗼𝘁 𝗥𝗲𝗾𝘂𝗶𝗿𝗲𝗱):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;💻🔐 Smart Contract Development: Experience writing Smart Contracts in Solidity or Rust.&lt;/li&gt;
&lt;li&gt;🪐⭐ Knowledge of Stellar and Soroban.&lt;/li&gt;
&lt;li&gt;🧪✔️ Testing Frameworks Knowledge: Familiarity with testing frameworks.&lt;/li&gt;
&lt;li&gt;🌍🔧 Open Source Contributions: Experience contributing to open source projects.&lt;/li&gt;
&lt;li&gt;📁🌟 GitHub Portfolio: Demonstrable projects or courses on GitHub.&lt;/li&gt;
&lt;li&gt;🎨🎸 Hobbies: We value work-life balance and diverse interests.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;📋 𝗛𝗼𝘄 𝘁𝗼 𝗔𝗽𝗽𝗹𝘆:&lt;br&gt;
1.- Review the offer in detail and complete the form at &lt;a href="https://tally.so/r/mBZze4" rel="noopener noreferrer"&gt;https://tally.so/r/mBZze4&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2.- Join our Discord and check out the challenge we have for you in #technical-challenge. Join here: &lt;a href="https://discord.gg/5sAHXCr4dV" rel="noopener noreferrer"&gt;https://discord.gg/5sAHXCr4dV&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is very important that in addition to filling out the form, you complete the challenge. If you have questions, ask in #technical-challenge and we will respond.&lt;/p&gt;

&lt;p&gt;We look forward to your application!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Oferta de Trabajo Fullstack Blockchain</title>
      <dc:creator>esteblock</dc:creator>
      <pubDate>Mon, 05 Aug 2024 22:10:16 +0000</pubDate>
      <link>https://dev.to/paltalabs/oferta-de-trabajo-fullstack-blockchain-24pp</link>
      <guid>https://dev.to/paltalabs/oferta-de-trabajo-fullstack-blockchain-24pp</guid>
      <description>&lt;p&gt;Puesto Full-time (También aceptamos prácticas)&lt;/p&gt;

&lt;p&gt;🧑‍💻 𝗨́𝗻𝗲𝘁𝗲 𝗮 𝗣𝗮𝗹𝘁𝗮𝗹𝗮𝗯𝘀 𝘆 𝘀𝗲 𝗽𝗮𝗿𝘁𝗲 𝗱𝗲 𝗹𝗮 𝗿𝗲𝘃𝗼𝗹𝘂𝗰𝗶𝗼́𝗻 𝗱𝗲𝗹 𝗕𝗹𝗼𝗰𝗸𝗰𝗵𝗮𝗶𝗻!&lt;/p&gt;

&lt;p&gt;🥑 𝗣𝗮𝗹𝘁𝗮𝗹𝗮𝗯𝘀 se destaca en:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creación de dApp: Aplicaciones descentralizadas innovadoras.&lt;/li&gt;
&lt;li&gt;Consultoría Blockchain: Orientación experta en integración.&lt;/li&gt;
&lt;li&gt;Aprendizaje Continuo: Profundos conocimientos en Blockchain.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Que hemos hecho? Creamos el primer Exchange Descentralizado con Smart Contracts en la Blockchain de Stellar &lt;a href="https://soroswap.finance" rel="noopener noreferrer"&gt;Soroswap.Finance Webpage&lt;/a&gt; | &lt;a href="https://github.com/soroswap/" rel="noopener noreferrer"&gt;Soroswap Github&lt;/a&gt;. También tenemos otro proyecto de inversión DeFi yestamos constantemente creando herramientas para desarrolladores. También estamos creando contenido y educando.&lt;/p&gt;

&lt;p&gt;Consulta más en nuestro &lt;a href="https://www.linkedin.com/company/paltalabs" rel="noopener noreferrer"&gt;Linkedin&lt;/a&gt;, &lt;a href="https://x.com/PaltaLabs" rel="noopener noreferrer"&gt;Twitter/X&lt;/a&gt;, &lt;a href="https://paltalabs.io/" rel="noopener noreferrer"&gt;Sitio Web&lt;/a&gt; y &lt;a href="https://github.com/orgs/paltalabs/repositories" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📝 Beneficios de unirse a nosotros:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🤑 Salario Practicante USD 500-1200 &lt;/li&gt;
&lt;li&gt;🤑 Salario Profesional USD 1200-3500&lt;/li&gt;
&lt;li&gt;🌍 Trabajo Remoto: Flexibilidad para trabajar desde cualquier lugar.&lt;/li&gt;
&lt;li&gt;🕒 Horarios Flexibles: Adapta tu horario.&lt;/li&gt;
&lt;li&gt;🏋️‍♀️ Bono de Actividad: Mantente activo con incentivos.&lt;/li&gt;
&lt;li&gt;🌴 24 Días de Vacaciones: Generoso tiempo libre.&lt;/li&gt;
&lt;li&gt;🤓 Entorno de Aprendizaje: Apoyo y colaboración.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🔍 𝗤𝘂𝗲 𝗵𝗮𝗿𝗮́𝘀:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;📱 Desarrollo de dApp: Construir aplicaciones descentralizadas.&lt;/li&gt;
&lt;li&gt;🤖 Construcción de Bots: Diseñar bots de automatización.&lt;/li&gt;
&lt;li&gt;📝 Desarrollo de Scripts: Crear scripts funcionales.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🔧 𝗛𝗮𝗯𝗶𝗹𝗶𝗱𝗮𝗱𝗲𝘀 𝗧𝗲́𝗰𝗻𝗶𝗰𝗮𝘀 𝗥𝗲𝗾𝘂𝗲𝗿𝗶𝗱𝗮𝘀:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🧠🔗 Conocimiento de Blockchain: Comprender cómo funciona una Blockchain.&lt;/li&gt;
&lt;li&gt;🖥️💼 Dominio de Backend: Competencia en lenguajes de backend como Python, Typescript, o Javascript.&lt;/li&gt;
&lt;li&gt;🌐⚛️ Frontend con React: Habilidad en desarrollo frontend utilizando React.&lt;/li&gt;
&lt;li&gt;📂🔄 Gestión de Versiones con Git: Dominio de Git para control de versiones.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🧠 𝗛𝗮𝗯𝗶𝗹𝗶𝗱𝗮𝗱𝗲𝘀 𝗕𝗹𝗮𝗻𝗱𝗮𝘀 𝗥𝗲𝗾𝘂𝗲𝗿𝗶𝗱𝗮𝘀:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;⏳📅 Gestión del Tiempo: Capacidad para manejar bien su tiempo.&lt;/li&gt;
&lt;li&gt;🧘‍♂️😌 Manejo del Estrés: Habilidad para trabajar bajo presión y manejar el estrés.&lt;/li&gt;
&lt;li&gt;🎯🔍 Concentración: Gran capacidad de concentración y atención al detalle.&lt;/li&gt;
&lt;li&gt;💬📖 Comunicación: Hablar español y tener habilidades de lectura y escritura en inglés.&lt;/li&gt;
&lt;li&gt;🌟🚀 Motivación para Web3: Estar muy motivado y entusiasta por trabajar en el ecosistema Web3.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;✨ 𝗛𝗮𝗯𝗶𝗹𝗶𝗱𝗮𝗱𝗲𝘀 𝗗𝗲𝘀𝗲𝗮𝗯𝗹𝗲𝘀 (𝗡𝗼 𝗥𝗲𝗾𝘂𝗶𝘀𝗶𝘁𝗼𝘀):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;💻🔐 Desarrollo de Smart Contracts: Experiencia en escribir Smart Contracts en Solidity o Rust.&lt;/li&gt;
&lt;li&gt;🪐⭐ Conocimiento de Stellar y Soroban.&lt;/li&gt;
&lt;li&gt;🧪✔️ Conocimiento de Frameworks de Testing: Familiaridad con frameworks de testing.&lt;/li&gt;
&lt;li&gt;🌍🔧 Contribuciones a Proyectos Open Source: Experiencia en contribuciones a proyectos de código abierto.&lt;/li&gt;
&lt;li&gt;📁🌟 Portafolio en GitHub: Tener proyectos o cursos demostrables en GitHub.&lt;/li&gt;
&lt;li&gt;🎨🎸 Tener Hobbies: Valorizamos el balance vida-trabajo y la diversidad de intereses.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;📋 𝗖𝗼́𝗺𝗼 𝗣𝗼𝘀𝘁𝘂𝗹𝗮𝗿:&lt;br&gt;
1.- Revisa la oferta en detalle y completa el formulario en &lt;a href="https://tally.so/r/mBZze4" rel="noopener noreferrer"&gt;https://tally.so/r/mBZze4&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2.- Únete a nuestro Discord y revisa en #tecnical-challenge el desafío que tenemos para ti. Untete aqui: &lt;a href="https://discord.gg/5sAHXCr4dV" rel="noopener noreferrer"&gt;https://discord.gg/5sAHXCr4dV&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Es muy importante que además de llenar el formulario, hagas el desafío. Si tienes dudas, pregunta en #tecnical-challenge y te responderemos.&lt;/p&gt;

&lt;p&gt;¡Esperamos tu postulación!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Costs, DoS Risks, and Instance vs Persistent Data Types in Soroban</title>
      <dc:creator>esteblock</dc:creator>
      <pubDate>Fri, 19 Jan 2024 19:45:30 +0000</pubDate>
      <link>https://dev.to/soroswap/-costs-dos-risks-and-instance-vs-persistent-data-types-in-soroban-421o</link>
      <guid>https://dev.to/soroswap/-costs-dos-risks-and-instance-vs-persistent-data-types-in-soroban-421o</guid>
      <description>&lt;p&gt;In the development journey of the &lt;a href="https://soroswap.finance"&gt;Soroswap.Finance&lt;/a&gt; protocol, critical decisions regarding data types for Smart Contracts were made. The choice of storage impacts the risk of Denial of Service (DoS), increases contract interaction costs, or introduces both risks simultaneously.&lt;/p&gt;

&lt;p&gt;This article explores the advantages and drawbacks of four design patterns for storing an increasing amount of information on the Soroban blockchain. Additionally, it delves into the associated costs for each scenario.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Context:&lt;/strong&gt; &lt;a href="https://soroswap.finance"&gt;Soroswap.Finance&lt;/a&gt; is an Automated Market Maker in the Soroban Smart Contract Platform within the Stellar Blockchain, developed by the &lt;a href="https://paltalabs.io"&gt;PaltaLabs 🥑&lt;/a&gt; team.&lt;/p&gt;

&lt;p&gt;Follow the code here: &lt;a href="https://github.com/paltalabs/instance-persistent-dos-soroban/"&gt;Instance-Persistent-Dos-Soroban&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  TLDR;
&lt;/h2&gt;

&lt;p&gt;This article demonstrates that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Instance data types share a common Ledger Entry, leading to contract failure if the total stored information reaches 64kb.&lt;/li&gt;
&lt;li&gt;Instance storage Ledger Entry is independent of contract size, with a fixed 64kb reserved regardless of contract dimensions.&lt;/li&gt;
&lt;li&gt;Instance data types are read on every interaction, making any contract interaction more costly.&lt;/li&gt;
&lt;li&gt;Unbounded data storage in Vectors or Mappings risks reaching 64kb and becoming vulnerable to DoS attacks.&lt;/li&gt;
&lt;li&gt;The variable DataKey technique is the recommended approach for storing unbounded data.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Instance and Persistent Data Types.
&lt;/h2&gt;

&lt;p&gt;From Soroban documentation, we know that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Instance storage has its data limit determined by the ledger entry size (&lt;a href="https://docs.rs/soroban-sdk/latest/soroban_sdk/storage/struct.Storage.html#method.instance"&gt;Source&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;All instance storage is kept in a single contract instance LedgerEntry with a 64kb size (&lt;a href="https://soroban.stellar.org/docs/soroban-internals/state-archival"&gt;Source&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;The Ledger Entry Size is capped at 64kb (&lt;a href="https://soroban.stellar.org/docs/soroban-internals/fees-and-metering#resource-limits"&gt;Source&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  The Challenge: Store Unbounded Information
&lt;/h1&gt;

&lt;p&gt;The example challenge involves creating a Smart Contract that stores two collections of an increasing amount of 32-byte addresses, representing buyers and sellers. Two separate collections are used, as the choice of data type can impact one collection when the other grows.&lt;/p&gt;

&lt;p&gt;Externally, interactions with this contract are intended to follow this pattern for each collection:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Call a function to store a new address (number n).&lt;/li&gt;
&lt;li&gt;Retrieve the address for a given number n.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Indeed, tests for each design are the same, and they all pass! So be aware dev, passing your test does not means that your code is safe!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the following sections, four design patterns will be explained, with only one proving to be DoS-free and not increasing the cost of interacting with the contract.&lt;/p&gt;

&lt;h3&gt;
  
  
  Design 1: Store a Vector in an Instance Data Type. The Case of a Light Smart Contract.
&lt;/h3&gt;

&lt;p&gt;With this technique, a vector is stored in an instance storage slot. Each time a new element is pushed, the current vector value is read, the new element is added, and the updated vector is written back to the same instance storage slot. The code looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="nf"&gt;.storage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.instance&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="nf"&gt;.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;VECTOR_A&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap_or&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Vec&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// If no value set, assume an empty vector.&lt;/span&gt;

&lt;span class="c1"&gt;// Push the current contract address in the vector&lt;/span&gt;
&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="nf"&gt;.push_back&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="nf"&gt;.current_contract_address&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

&lt;span class="c1"&gt;// Save the updated vector to instance storage&lt;/span&gt;
&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="nf"&gt;.storage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.instance&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;VECTOR_A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A DoS attack simulation reveals that this design causes the contract to fail with a &lt;code&gt;ResourceLimitExceeded&lt;/code&gt; error after the sum of the collections reaches 64kb, equivalent to 818 pushes of addresses on each collection. Further details, including code, simulation, and results, can be found in the &lt;a href="https://github.com/paltalabs/instance-persistent-dos-soroban/"&gt;repository&lt;/a&gt;. Additionally, this design increases the cost of every call to the smart contract, even for unrelated functions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Design 2: Store a Vector in an Instance Data Type.. The Case of a Heavy Smart Contract.
&lt;/h3&gt;

&lt;p&gt;Similar to Design 1, this approach demonstrates that instance storage is stored in an independent LedgerEntry from the Smart Contract itself. With this design, the cost of reading the contract increases with every push operation, even for unrelated functions. This design also results in a &lt;code&gt;ResourceLimitExceeded&lt;/code&gt; error.&lt;/p&gt;

&lt;h3&gt;
  
  
  Design 3: Store a Vector in a Persistent Data Type..
&lt;/h3&gt;

&lt;p&gt;This design involves storing a vector in a persistent data type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="nf"&gt;.storage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.persistent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="nf"&gt;.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;VECTOR_A&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap_or&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Vec&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// If no value set, assume an empty vector.&lt;/span&gt;
&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="nf"&gt;.push_back&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="nf"&gt;.current_contract_address&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="nf"&gt;.storage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.persistent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;VECTOR_A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While it avoids sharing storage size with other variables, it is still limited to 64kb of information. Details of an &lt;a href="https://github.com/paltalabs/instance-persistent-dos-soroban/#situation-3-persistent-vector-heavy"&gt;attack simulation&lt;/a&gt; show that it allows reaching twice the number of entries compared to the previous examples. However, the cost of reading the contract does not increase for unrelated functions, as persistent data type is not retrieved every time the contract is called.&lt;/p&gt;

&lt;h3&gt;
  
  
  Design 4: Use Variable DataKeys with Persistent Data Type..
&lt;/h3&gt;

&lt;p&gt;This design introduces the &lt;strong&gt;Variable DataKey&lt;/strong&gt; technique, where the name of the storage slot depends on a parameter. The DataKey is defined as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[contracttype]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;DataKey&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;StoredAddressesA&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This technique is commonly used to store an increasing amount of data, as seen in the &lt;a href="https://github.com/stellar/soroban-examples/blob/9ae2d834059e8898291b5cf41a8d04dd33251640/token/src/balance.rs#L6"&gt;token contract for storing user balances&lt;/a&gt;. The information is stored as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u32&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="nf"&gt;.storage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.instance&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;COUNTER_A&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap_or&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="nf"&gt;.storage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.persistent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nn"&gt;DataKey&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;StoredAddressesA&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="nf"&gt;.current_contract_address&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="nf"&gt;.storage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.persistent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;COUNTER_A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This design, including the storage of a &lt;strong&gt;COUNTER&lt;/strong&gt; to track the number of stored addresses, is considered the best option. It successfully avoids DoS attacks and minimizes the cost of reading the contract.&lt;/p&gt;

&lt;p&gt;Using u32 provides 2^32 different storage slots for StoredAddressA, which is more than sufficient. Even if an attacker were to call the push function 2^32 times, the associated cost is calculated to be around 439,289 stroops (0.044 XLM). This cost limitation makes it practically infeasible for an attacker, even with the entire Total Supply of XLM (50,001,787,051), to add more than 2,196,523,503 entries (2^21).&lt;/p&gt;

&lt;h3&gt;
  
  
  Design 5: Use Variable DataKeys with Instance Data Type.
&lt;/h3&gt;

&lt;p&gt;Lastly, using Variable DataKeys as a solution with instance data type is a &lt;strong&gt;mistake&lt;/strong&gt;. This design is as inefficient as using a vector because storing in different slots shared in a single Ledger Entry is almost equivalent to storing everything in one slot, similar to a vector. This situation can lead to a DoS attack and result in a &lt;code&gt;ResourceLimitExceeded&lt;/code&gt; error.&lt;/p&gt;

&lt;h1&gt;
  
  
  Contact us:
&lt;/h1&gt;

&lt;p&gt;Did you like the article? Contact us in our Discord &lt;a href="https://discord.gg/HFkBquZNNg"&gt;https://discord.gg/HFkBquZNNg&lt;/a&gt; or reach us in &lt;a href="https://paltalabs.io"&gt;https://paltalabs.io&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Managing different Soroban CLI versions</title>
      <dc:creator>esteblock</dc:creator>
      <pubDate>Tue, 26 Dec 2023 13:08:14 +0000</pubDate>
      <link>https://dev.to/esteblock/managing-different-soroban-cli-versions-57g3</link>
      <guid>https://dev.to/esteblock/managing-different-soroban-cli-versions-57g3</guid>
      <description>&lt;p&gt;Sometimes you might want to manage different soroban CLI versions, in order to work with different projects in your computer.&lt;/p&gt;

&lt;p&gt;Or maybe, sometimes there is a last minute upgrade you want to try, but you don't want to change your computer's configuration. &lt;/p&gt;

&lt;p&gt;How can we solve this?&lt;/p&gt;

&lt;h2&gt;
  
  
  The Soroban Preview Docker Image
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://github.com/esteblock/soroban-preview-docker"&gt;&lt;code&gt;soroban-preview-docker&lt;/code&gt;&lt;/a&gt; images are Docker images with the 4 main necessary configurations in order to run soroban CLI: 1) An Ubuntu Linux manchine 2) Rust &amp;amp; Cargo installed, 3) Node installed, and 4) The desired soroban CLI version.&lt;/p&gt;

&lt;p&gt;You can check how this images are built, by checking this &lt;a href="https://github.com/esteblock/soroban-preview-docker/blob/main/preview_20.1.0/Dockerfile"&gt;&lt;code&gt;esteblock/soroban-preview:20.1.0&lt;/code&gt;&lt;/a&gt; &lt;strong&gt;Dockerfile&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How to use this together with a Quickstart Image node?
&lt;/h2&gt;

&lt;p&gt;Check how we do it in &lt;strong&gt;Soroswap&lt;/strong&gt;: We have 3 files:&lt;/p&gt;

&lt;p&gt;1.- The &lt;a href="https://github.com/soroswap/core/blob/main/preview_version.json"&gt;&lt;code&gt;preview_version.json&lt;/code&gt;&lt;/a&gt; file, where we fix both the quickstart and the soroban-preview docker images versions&lt;/p&gt;

&lt;p&gt;2.- The &lt;a href="https://github.com/soroswap/core/blob/main/scripts/quickstart.sh"&gt;&lt;code&gt;quickstart.sh&lt;/code&gt;&lt;/a&gt; bash script that Creates a common docker network and opens both Docker containers.&lt;/p&gt;

&lt;p&gt;3.- The &lt;a href="https://github.com/soroswap/core/blob/main/scripts/run.sh"&gt;&lt;code&gt;run.sh&lt;/code&gt;&lt;/a&gt; bash script that helps us open the desired (and already running) soroban preview docker container&lt;/p&gt;

&lt;h2&gt;
  
  
  Run the Containers:
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bash scripts/quickstart.sh
bash scripts/run.sh

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Do it your self.
&lt;/h2&gt;

&lt;p&gt;1) Create a common Docker Network, so both Docker containers (Stellar Quickstart &amp;amp; Soroban Preview) can talk to each other&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker network create soroban-network
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2) Open a Docker Container with the Soroban Preview Docker image&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-dti&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--volume&lt;/span&gt; &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;currentDir&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;:/workspace &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; soroban-preview-&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;previewVersion&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-p&lt;/span&gt; 8001:8000 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--ipc&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;host &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--network&lt;/span&gt; soroban-network &lt;span class="se"&gt;\&lt;/span&gt;
  esteblock/soroban-preview:&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;previewVersion&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3) Open a Stellar Quickstart Docker Container&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Run the stellar quickstart image&lt;/span&gt;
docker run &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;-ti&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; stellar &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--network&lt;/span&gt; soroban-network &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-p&lt;/span&gt; 8000:8000 &lt;span class="se"&gt;\&lt;/span&gt;
  stellar/quickstart:&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;quickstartHash&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nv"&gt;$ARGS&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--enable-soroban-rpc&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--protocol-version&lt;/span&gt; 20 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--enable-soroban-diagnostic-events&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$@&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="c"&gt;# Pass through args from the CLI&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>Installing Freighter</title>
      <dc:creator>esteblock</dc:creator>
      <pubDate>Wed, 15 Nov 2023 22:16:32 +0000</pubDate>
      <link>https://dev.to/soroswap/installing-freighter-4d1c</link>
      <guid>https://dev.to/soroswap/installing-freighter-4d1c</guid>
      <description>&lt;h1&gt;
  
  
  1. Installing Freighter
&lt;/h1&gt;

&lt;p&gt;In this section, we will guide you through the installation process of Freighter, a non-custodial Stellar wallet extension that will empower you to engage with Soroswap.Finance&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Installing Freighter on your Browser
&lt;/h2&gt;

&lt;p&gt;Freighter works as a Extension in Chrome (Google Chrome, Brave) and Firefox:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Visit the &lt;a href="https://www.freighter.app/"&gt;Freighter Official Website&lt;/a&gt;, to install Freighter into your browser.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click on "Create Account" and choose a secure password.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Step 2: Safeguarding Your Wallet
&lt;/h2&gt;

&lt;p&gt;Upon creating your account, you will be presented with a secret recovery phrase. This phrase acts as a backup for your wallet's private key, allowing you to restore your wallet in case of loss, theft, or device damage.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--I9obpaJa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d422wt6rbd7t2nncjvtd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--I9obpaJa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d422wt6rbd7t2nncjvtd.png" alt="Image description" width="800" height="354"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Follow these important guidelines to protect your funds:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Save the Seed Phrase&lt;/strong&gt;: Keep your seed phrase in a safe place. Treat it as a valuable key to your funds and store it confidentially.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Secure Storage&lt;/strong&gt;: Store the seed phrase in a secure location, such as a locked drawer or a password-protected digital storage solution. Ensure it is shielded from unauthorized access and potential loss.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Exercise Caution&lt;/strong&gt;: Remember, anyone with access to your seed phrase can gain control over your wallet and its contents. Take the necessary precautions to safeguard it diligently.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 3: Confirming Your Seed Phrase
&lt;/h2&gt;

&lt;p&gt;To ensure accuracy, you will be asked to confirm your seed phrase in the same order. This step guarantees that you have correctly noted down your recovery phrase.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Xk4o3cDW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/urjix82iycg5677h7vay.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Xk4o3cDW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/urjix82iycg5677h7vay.png" alt="Image description" width="647" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Accessing Your Wallet
&lt;/h2&gt;

&lt;p&gt;Congratulations! You are now ready to use your Freighter wallet. Follow these final steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the Freighter extension in your browser.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cRxh6iCD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0zj2j4k4lify7g1busr0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cRxh6iCD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0zj2j4k4lify7g1busr0.png" alt="Image description" width="346" height="582"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Your account will be displayed, labeled as "Account 1," along with your unique account address. This address serves as an identifier for receiving funds or transactions from other users or entities on the blockchain network.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click on the "Main Net" button located at the top right corner to explore the networks:&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Mainnet&lt;/strong&gt;: The live and fully operational blockchain network where real transactions occur.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Testnet&lt;/strong&gt;: A simulated environment for testing and experimentation&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Since Soroswap is currently in the Soroban Testnet environment, we will proceed with the tutorial using the Testnet setting. By utilizing the testnet, we can safely explore and demonstrate the functionalities of Soroswap without any concerns about real-world financial implications.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2GCH7Vfg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a49jnyfsjhbgsx0g5203.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2GCH7Vfg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a49jnyfsjhbgsx0g5203.png" alt="Image description" width="346" height="582"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Let's Dive into the Tutorial
&lt;/h2&gt;

&lt;p&gt;Congratulations! You are now fully equipped to embark on an exciting journey with Soroswap on the testnet. Get ready to explore and make the most of Soroswap's comprehensive range of features within this secure testing environment. Let's dive right into the tutorial and unlock the full potential of your Soroswap experience!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Soroswap 🪐 on Testnet Overview</title>
      <dc:creator>esteblock</dc:creator>
      <pubDate>Wed, 15 Nov 2023 20:53:15 +0000</pubDate>
      <link>https://dev.to/soroswap/soroswap-on-testnet-overview-3eed</link>
      <guid>https://dev.to/soroswap/soroswap-on-testnet-overview-3eed</guid>
      <description>&lt;h1&gt;
  
  
  Soroswap Testnet Overview
&lt;/h1&gt;

&lt;p&gt;Soroswap is an Automated Market Maker (AMM) built on Soroban, designed to facilitate token trading and liquidity provision. With its user-friendly interface, Soroswap offers a seamless and intuitive experience for users to engage with decentralized finance (DeFi) on the Soroban and Stellar&lt;/p&gt;

&lt;p&gt;Check it in &lt;a href="https://soroswap.finance/"&gt;https://soroswap.finance/&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  User-Friendly Interface
&lt;/h2&gt;

&lt;p&gt;Soroswap boasts a user-friendly interface that ensures a smooth and enjoyable trading experience. The intuitive design caters to both beginners and experienced traders, making it easy to navigate the platform and interact with its features.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Features and Benefits
&lt;/h2&gt;

&lt;p&gt;** Currently Soroswap works only on Soroban Testnet**, and provides several key features and benefits for users:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Balance Section:&lt;/strong&gt; Conveniently view your test token balances in the Balance section. This feature allows you to keep track of your assets and monitor their availability for transactions within the app.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Swap Section:&lt;/strong&gt; Easily exchange one token for another within the liquidity pool using Soroswap's Swap section. This feature provides a straightforward and efficient solution for diversifying your portfolio or making specific token swaps.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Liquidity Section:&lt;/strong&gt; Empowers users to add or remove liquidity from the pools. By participating in liquidity provision, you contribute to the stability and efficiency of the Soroswap ecosystem. Effectively manage your liquidity positions in the Liquidity section for a smooth and rewarding experience.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Soroswap on the Sorosban Testnet allows users to fully explore and test the platform using test tokens. This enables you to experience the complete functionality of the app without risking real funds. It provides an opportunity to familiarize yourself with the features, understand the process of adding liquidity, performing swaps, and removing liquidity.&lt;/p&gt;

&lt;p&gt;By utilizing Soroswap on the testnet, you can gain hands-on experience with decentralized exchanges and DeFi concepts. It serves as a valuable learning tool and a safe environment to experiment with different trading strategies and liquidity provision.&lt;/p&gt;

&lt;p&gt;In the following sections, we will provide step-by-step instructions on how to use Soroswap on the testnet, including installing the Freighter wallet, adding liquidity, performing swaps, and removing liquidity. These instructions will help you navigate the platform and make the most of the features and benefits offered by Soroswap. Let's dive in!&lt;/p&gt;

&lt;p&gt;Did you like it?&lt;br&gt;
Please give us feedback. Join our Discord channel: &lt;a href="https://discord.gg/wyesAQhP"&gt;https://discord.gg/wyesAQhP&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Soroswap.Finance 🪐 is live on Soroban Testnet ✨!</title>
      <dc:creator>esteblock</dc:creator>
      <pubDate>Wed, 15 Nov 2023 20:50:39 +0000</pubDate>
      <link>https://dev.to/soroswap/soroswapfinance-is-live-on-soroban-testnet--5072</link>
      <guid>https://dev.to/soroswap/soroswapfinance-is-live-on-soroban-testnet--5072</guid>
      <description>&lt;p&gt;Soroswap.Finance 🪐 is now live on Soroban Testnet, and we couldn't be more thrilled to share this exciting news with the Stellar and Soroban communities!&lt;/p&gt;

&lt;p&gt;Ten months have passed since Soroswap proudly clinched the 3rd prize in the inaugural &lt;a href="https://hacka-soroban-athon.devpost.com/"&gt;Hacka-Soroban-athon 🖥&lt;/a&gt;, Soroban's first-ever hackathon. Our journey has been filled with dedication, a evoluting team of over 10 talented collaborators, collaboration with an external design agency, and participation in key events like the sub0 Polkadot 🧬 Conference and the Meridian 2023 conference in Madrid 🇪🇸.&lt;/p&gt;

&lt;p&gt;Soroswap is an &lt;strong&gt;open-source&lt;/strong&gt; AMM protocol designed to enhance liquidity provision and asset trading for Stellar assets within the Soroban ecosystem. It comes equipped with an SDK and a user-friendly frontend to make your experience seamless.&lt;br&gt;
&lt;a href="https://soroban.stellar.org/"&gt;Soroban&lt;/a&gt; is the new Smart Contract platform of the Blockchain Stellar, and we are creating DeFi primitives on it!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Experience Soroswap on Testnet now!: &lt;a href="https://soroswap.finance/"&gt;https://soroswap.finance/&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To get started, simply access it with a &lt;strong&gt;Freighter Wallet version 5.6.4 or higher&lt;/strong&gt;. On our Testnet dapp, you can experiment with our test tokens and get a feel for the platform. Mint test tokens, provide liquidity and do swaps"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your Feedback Matters 💭:&lt;/strong&gt; We welcome your valuable feedback! Your input is crucial to us and the entire ecosystem. If you have questions, find bugs, or just want to share your thoughts, please don't hesitate to reach out. We're eager to incorporate your insights into this incredible project. You can do this by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://discord.gg/C7AtGAgU"&gt;Reaching us into our Discord Channel&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/soroswap/frontend/issues"&gt;Open an Issue in our Frontend Repo&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What is next? 🥑✨&lt;/strong&gt;&lt;br&gt;
For the final months and 2024 Q1 Soroswap.Finance Rodamap looks like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Implement Mercury 🌐 Indexer to become a multi AMM Aggregator&lt;/li&gt;
&lt;li&gt;Implement Mercury 🌐 Indexer for a Enhanced Dashboard&lt;/li&gt;
&lt;li&gt;Implement Mercury 🌐 Indexer for a Optimal Routing&lt;/li&gt;
&lt;li&gt;Implement a Bridge (AllBridge in/to Ethereum or Pendulum in/to Polkadot!)&lt;/li&gt;
&lt;li&gt;Community Building&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We still have a lot of things to build!&lt;br&gt;
We hope you give us your support to let this happen!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A Big Thank You 🤗:&lt;/strong&gt; We owe a massive thanks to the &lt;a href="https://communityfund.stellar.org/"&gt;Stellar Community Fund (SCF)&lt;/a&gt; for making this journey possible. You can review all our SCF deliverables in our &lt;a href="https://github.com/soroswap/scf-tracker."&gt;SCF tracker repo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Meet the Team 🧑‍🤝‍🧑:&lt;/strong&gt;&lt;br&gt;
Soroswap.Finance 🪐 is brought to you by &lt;a href="https://paltalabs.io/"&gt;PaltaLabs&lt;/a&gt;🥑, a dynamic Blockchain Development Laboratory with contributors from Santiago, Valdivia and Rancagua (Chile), Rio de Janeiro (Brazil), Berlin (Germany), and Arras (France). Our team is a blend of dedicated full-timers, part-timers, and past collaborators who may rejoin us in the future. We extend our heartfelt gratitude to everyone who's played a role in Soroswap's journey.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://esteban.paltalabs.io/"&gt;Esteban Iglesias (esteblock)&lt;/a&gt;, CEO &amp;amp; Founder, Fullstack Blockchain Developer&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://francisco.paltalabs.io/"&gt;Francisco Catrileo (devmonsterblock)&lt;/a&gt;, Fullstack Blockchain Developer &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://joaquin.paltalabs.io/"&gt;Joaquín Soza (yripper)&lt;/a&gt;, Fullstack Blockchain Developer &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.linkedin.com/in/diego-correa-t/"&gt;Maximiliano Carrasco (abstract#1547)&lt;/a&gt;, Frontend Developer &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.linkedin.com/in/viviana-manriquez-fuenzalida/"&gt;Viviana Manríquez (vivitapatita)&lt;/a&gt;, Brand Coordinator&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.linkedin.com/in/diego-correa-t/"&gt;Diego Correa Tristain (diegotristain)&lt;/a&gt;, Rust Developer &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://benjaminsalon.fr/"&gt;Benjamin Salon(benjaminsalon)&lt;/a&gt; Computer Science  &amp;amp; @soroban-react Supporter&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/jtschuwirth"&gt;Jose Tomas Schuwirth (ealric)&lt;/a&gt;, Frontend Web3 Developer &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/mauroepce"&gt;Mauricio Patiño (.maur0)&lt;/a&gt;, Full-Stack Developer &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://ricardorodriguezreveco.com/"&gt;Ricardo Rodriguez (ricardor4)&lt;/a&gt;, Computer Science &amp;amp; Mathematics Models &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/JoseFredes"&gt;José Fredes (draken1700)&lt;/a&gt;, Frontend Developer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Join us in exploring Soroswap on Testnet and help us make it even better! Your involvement is key to the success of this innovative project. 🚀🌟&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Welcome to Soroswap.Finance</title>
      <dc:creator>esteblock</dc:creator>
      <pubDate>Tue, 31 Oct 2023 12:29:51 +0000</pubDate>
      <link>https://dev.to/soroswap/welcome-to-soroswapfinance-54kb</link>
      <guid>https://dev.to/soroswap/welcome-to-soroswapfinance-54kb</guid>
      <description>&lt;p&gt;This will be our space to share what we are building in the Soroban / Stellar Blockchain!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://soroswap.finance/"&gt;https://soroswap.finance/&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Converting a Soroban Smart Contract into a crate library</title>
      <dc:creator>esteblock</dc:creator>
      <pubDate>Tue, 17 Oct 2023 16:56:12 +0000</pubDate>
      <link>https://dev.to/esteblock/converting-a-soroban-smart-contract-into-a-crate-library-228m</link>
      <guid>https://dev.to/esteblock/converting-a-soroban-smart-contract-into-a-crate-library-228m</guid>
      <description>&lt;p&gt;I am working developing &lt;a href="https://soroswap.finance/"&gt;Soroswap.Finance&lt;/a&gt;, an AMM in Soroban and we write our Smart Contracts based on the &lt;a href="https://docs.uniswap.org/contracts/v2/reference/smart-contracts/factory"&gt;UniswapV2&lt;/a&gt; Smart Contracts written in Solidity.&lt;/p&gt;

&lt;p&gt;In Solidity we can write an smart contract, deploy it and use it as an smart contract and also use the same code as a library, so another smart contract can inherit its logic.&lt;/p&gt;

&lt;p&gt;Common usage is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;contract&lt;/span&gt; &lt;span class="nx"&gt;MyContract&lt;/span&gt; &lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;ContractFather&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another usage is to use a Solidity library like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./libraries/UniswapV2Library.sol&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="c1"&gt;// and then use the library like:&lt;/span&gt;
&lt;span class="nx"&gt;uint&lt;/span&gt; &lt;span class="nx"&gt;amountBOptimal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;UniswapV2Library&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;quote&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amountADesired&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reserveA&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reserveB&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;How can we do something similar with rust and soroban-sdk?&lt;/p&gt;

&lt;h2&gt;
  
  
  The Library Contract
&lt;/h2&gt;

&lt;p&gt;I wrote the SoroswapLibrary Smart Contract and it was working perfectly: Here is the code I had at the moment:&lt;br&gt;
&lt;a href="https://github.com/soroswap/core/tree/c65cebcfe69f05b38567158610dab25a941d4e6a/contracts/library"&gt;https://github.com/soroswap/core/tree/c65cebcfe69f05b38567158610dab25a941d4e6a/contracts/library&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Publishing into crates.io
&lt;/h2&gt;

&lt;p&gt;In order to transform this "pure" Smart Contract into a Library that can be imported by another Smart Contract I did the following:&lt;/p&gt;

&lt;p&gt;1.- Edit the Cargo.toml to add some information necessary to publish into crates.io&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[package]
name = "soroswap-library"
version = "0.1.1"
description = "Library that enables efficient and optimized code execution across different contracts on the Soroswap.Finance protocol"
homepage = "https://github.com/soroswap/core/tree/main/contracts/library"
repository = "https://github.com/soroswap/core/tree/main/contracts/library"
authors = ["esteblock &amp;lt;esteblock@paltalabs.io&amp;gt;"]
readme = "README.md"
license = "GPL-3.0"
edition = "2021"
keywords = ["no_std", "wasm", "soroswap", "amm", "soroban"]
rust-version = "1.73"
publish = true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2.- Create an account in crates.io and login&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cargo login
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3.- Publish:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cargo publish
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If everything goes well, your contract will be published in crates.io and you can use it&lt;/p&gt;

&lt;h2&gt;
  
  
  Importing it into your code:
&lt;/h2&gt;

&lt;p&gt;In my Router contract I can use it as a library, editing &lt;code&gt;Cargo.toml&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[dependencies]
soroban-sdk = { version = "20.0.0-rc2" }
num-integer = { version = "0.1.45", default-features = false, features = ["i128"] }
soroswap-library = "0.1.1"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And I &lt;strong&gt;should&lt;/strong&gt; be able to use it inside my &lt;code&gt;lib.rs&lt;/code&gt; as&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use soroswap_library;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The "no external crate" error
&lt;/h2&gt;

&lt;p&gt;When I complile the &lt;code&gt;Router&lt;/code&gt; contract I had the following error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;error[E0432]: unresolved import `soroswap_library`
 --&amp;gt; src/lib.rs:9:5
  |
9 | use soroswap_library;
  |     ^^^^^^^^^^^^^^^^ no external crate `soroswap_library`

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Very strange... But I found that I could solve it, adding the &lt;code&gt;rlib&lt;/code&gt; crate type in the library contract... So it stays like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
[lib]
crate-type = ["cdylib", "rlib"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Moving out your desired functions.
&lt;/h2&gt;

&lt;p&gt;Also, in order to use a function as a crate library, you'll need to move them out from the contract Trait... and re-export them:&lt;/p&gt;

&lt;p&gt;In my case, the Library's &lt;code&gt;lib.rs&lt;/code&gt; has:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;tokens&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;reserves&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;quotes&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;tokens&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;
    &lt;span class="n"&gt;sort_tokens&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;pair_for&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;reserves&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;
    &lt;span class="n"&gt;get_reserves&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;quotes&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;
    &lt;span class="n"&gt;quote&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;get_amount_out&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;get_amount_in&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;get_amounts_out&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;get_amounts_in&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check the final code here: &lt;a href="https://github.com/soroswap/core/tree/main/contracts/library"&gt;https://github.com/soroswap/core/tree/main/contracts/library&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Using the library
&lt;/h2&gt;

&lt;p&gt;With this change (and of course after publishing a new version of the library in crates.io), I could use in my Router&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="n"&gt;soroswap_library&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// and then&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;amount_b_optimal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;soroswap_library&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;quote&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount_a_desired&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;reserve_a&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;reserve_b&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>The Library Contract: Comparison between Soroswap and UniswapV2</title>
      <dc:creator>esteblock</dc:creator>
      <pubDate>Wed, 04 Oct 2023 12:12:05 +0000</pubDate>
      <link>https://dev.to/esteblock/the-library-contract-comparison-between-soroswap-and-uniswapv2-46d8</link>
      <guid>https://dev.to/esteblock/the-library-contract-comparison-between-soroswap-and-uniswapv2-46d8</guid>
      <description>&lt;p&gt;The &lt;code&gt;UniswapV2Library&lt;/code&gt; contract is a contract that helps the router, or any other Uniswap Client Contract to interact with the &lt;code&gt;Pair&lt;/code&gt; contract. It helps sort tokens (remember that for the pair contract it's not the same token0 than token1), get reserves for an specific pair, and calculates the optimal in/out amount someone needs to send to swap an specific quantity of an specific token.&lt;/p&gt;

&lt;p&gt;In the following we are going to analize each function or characteristic of the &lt;code&gt;UniswapV2Library&lt;/code&gt; contract, originally written in Solidity for EVM's, and we are going to think on how we could implement those functionalities and functions in rust for Soroban:&lt;/p&gt;

&lt;h2&gt;
  
  
  Safe Math:
&lt;/h2&gt;

&lt;p&gt;In Solidity, the SafeMath library is used to validate arithmetic operations and prevent integer overflow/underflow. Should such a situation arise, the library throws an exception, which effectively reverts the transaction.&lt;/p&gt;

&lt;p&gt;In Rust, we can achieve similar functionality by activating the overflow check flag during the compilation process with the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[profile.release]&lt;/span&gt;
&lt;span class="py"&gt;overflow-checks&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Additionally, we use an overflow-safe implementation of functions &lt;code&gt;checked_add&lt;/code&gt;, &lt;code&gt;checked_mul&lt;/code&gt;, &lt;code&gt;checked_div&lt;/code&gt;, and &lt;code&gt;checked_sub&lt;/code&gt;. You can explore these functions and test their functionality in this repository:  &lt;a href="https://github.com/esteblock/overflow-soroban/"&gt;Overflow Soroban Repository&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also, we have overflow-safe functions &lt;code&gt;checked_add&lt;/code&gt;, &lt;code&gt;checked_mul&lt;/code&gt;, &lt;code&gt;checked_div&lt;/code&gt; and &lt;code&gt;checked_sub&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You can check and test these techniques in the following repository: &lt;a href="https://github.com/esteblock/overflow-soroban/"&gt;Overflow Soroban Repository&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In conclusion, Soroswap prevents overflows by leveraging these techniques.&lt;/p&gt;

&lt;h2&gt;
  
  
  The &lt;code&gt;sortTokens&lt;/code&gt; function:
&lt;/h2&gt;

&lt;p&gt;This function returns sorted token addresses, used to handle return values from pairs sorted in this  order.&lt;/p&gt;

&lt;p&gt;In Solidity the code is like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;sortTokens&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt; &lt;span class="nx"&gt;tokenA&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;address&lt;/span&gt; &lt;span class="nx"&gt;tokenB&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;internal&lt;/span&gt; &lt;span class="nx"&gt;pure&lt;/span&gt; &lt;span class="nx"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt; &lt;span class="nx"&gt;token0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;address&lt;/span&gt; &lt;span class="nx"&gt;token1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tokenA&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nx"&gt;tokenB&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;UniswapV2Library: IDENTICAL_ADDRESSES&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;token0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;token1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;tokenA&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;tokenB&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tokenA&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tokenB&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tokenB&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tokenA&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;token0&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;UniswapV2Library: ZERO_ADDRESS&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see on our SoroswapPair contract, we have imposed that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;token_a&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;token_b&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nd"&gt;panic!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"token_a must be less than token_b"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hence, we will implement an order of this type.&lt;/p&gt;

&lt;p&gt;Regarding the zero address, in Soroban there is no such as zero address (&lt;a href="https://discord.com/channels/897514728459468821/1077831317175144528/1077831317175144528"&gt;read this discussion&lt;/a&gt;), so the last &lt;code&gt;require&lt;/code&gt; statement won't be implemented.&lt;/p&gt;

&lt;h2&gt;
  
  
  The &lt;code&gt;pairFor&lt;/code&gt; function
&lt;/h2&gt;

&lt;p&gt;This function calculates the CREATE2 address for a pair without making any external calls. This is because UniswapV2Factory uses the CREATE2 opcode by carefully selecting a unique salt value in order to have a deterministic contract address for each (factory, token0, token1) combination (and of course the same pair contract code)&lt;/p&gt;

&lt;p&gt;The whole idea of this function is to avoid an external call to the Factory contract in order to ask it what the pair address is... In Soroban this external call won't be expensive... and it's not event direct that calculating this address will be cheaper than the external call&lt;/p&gt;

&lt;p&gt;Can we do the same with Soroban? The answer is &lt;strong&gt;yes!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In our SoroswapFactory contract, when we deploy a new Pair contract, we do it like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;e.deployer()
    .with_current_contract(token_pair.salt(&amp;amp;e)) // Use the salt as a unique identifier for the new contract instance
    .deploy(pair_wasm_hash) // Deploy the new contract instance using the given pair_wasm_hash value
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, the &lt;code&gt;salt&lt;/code&gt; is an unique identifier that will be used to calculate the new smart contract address. In fact, the new smart contract address depends only in the combination of &lt;strong&gt;the deployer address and the salt&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In fact, in the &lt;code&gt;salt&lt;/code&gt; in the factory is created by a combination of the &lt;code&gt;token_0&lt;/code&gt; and &lt;code&gt;token_1&lt;/code&gt; address:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;Pair&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;Self&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;Pair&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;Pair&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;salt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;Env&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;BytesN&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;salt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Bytes&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Append the bytes of token_a and token_b to the salt&lt;/span&gt;
        &lt;span class="n"&gt;salt&lt;/span&gt;&lt;span class="nf"&gt;.append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="na"&gt;.0&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.to_xdr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// can be simplified to salt.append(&amp;amp;self.clone().to_xdr(e)); but changes the hash&lt;/span&gt;
        &lt;span class="n"&gt;salt&lt;/span&gt;&lt;span class="nf"&gt;.append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="na"&gt;.1&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.to_xdr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

        &lt;span class="c1"&gt;// Hash the salt using SHA256 to generate a new BytesN&amp;lt;32&amp;gt; value&lt;/span&gt;
        &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="nf"&gt;.crypto&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.sha256&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;salt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;token_a&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;Address&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="na"&gt;.0&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;token_b&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;Address&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="na"&gt;.1&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want to be sure about what we say here, please check this playground repo: &lt;a href="https://github.com/paltalabs/deterministic-address-soroban"&gt;https://github.com/paltalabs/deterministic-address-soroban&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, in Soroban we can also calculate the pair contract address without doing a cross-contract call to the Factory contract, we just need the salt explined above + the Factory address like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;calculate_address&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;deployer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;salt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;BytesN&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Address&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;deployer_with_address&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="nf"&gt;.deployer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.with_address&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;deployer&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;salt&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Calculate deterministic address:&lt;/span&gt;
    &lt;span class="c1"&gt;// This function can be called at anytime, before or after the contract is deployed, because contract addresses are deterministic.&lt;/span&gt;
    &lt;span class="c1"&gt;// https://docs.rs/soroban-sdk/20.0.0-rc2/soroban_sdk/deploy/struct.DeployerWithAddress.html#method.deployed_address&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;deterministic_address&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;deployer_with_address&lt;/span&gt;&lt;span class="nf"&gt;.deployed_address&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;deterministic_address&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The &lt;code&gt;getReserves&lt;/code&gt; function
&lt;/h2&gt;

&lt;p&gt;This function fetches and sorts the reserves for a pair. &lt;/p&gt;

&lt;p&gt;It's code in Solidity is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getReserves&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt; &lt;span class="nx"&gt;factory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;address&lt;/span&gt; &lt;span class="nx"&gt;tokenA&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;address&lt;/span&gt; &lt;span class="nx"&gt;tokenB&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;internal&lt;/span&gt; &lt;span class="nx"&gt;view&lt;/span&gt; &lt;span class="nx"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;uint&lt;/span&gt; &lt;span class="nx"&gt;reserveA&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;uint&lt;/span&gt; &lt;span class="nx"&gt;reserveB&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt; &lt;span class="nx"&gt;token0&lt;/span&gt;&lt;span class="p"&gt;,)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sortTokens&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tokenA&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tokenB&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;uint&lt;/span&gt; &lt;span class="nx"&gt;reserve0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;uint&lt;/span&gt; &lt;span class="nx"&gt;reserve1&lt;/span&gt;&lt;span class="p"&gt;,)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;IUniswapV2Pair&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pairFor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;factory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tokenA&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tokenB&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;getReserves&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;reserveA&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reserveB&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;tokenA&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nx"&gt;token0&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;reserve0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reserve1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;reserve1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reserve0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is a set of simple external and internal function calls, so it will be easy to implement in Soroban&lt;/p&gt;

&lt;h2&gt;
  
  
  The &lt;code&gt;quote&lt;/code&gt; function
&lt;/h2&gt;

&lt;p&gt;This function given some amount of an asset and pair reserves, returns an equivalent amount of the &lt;br&gt;
other asset&lt;/p&gt;

&lt;p&gt;It's code in Solidity is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;quote&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;uint&lt;/span&gt; &lt;span class="nx"&gt;amountA&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;uint&lt;/span&gt; &lt;span class="nx"&gt;reserveA&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;uint&lt;/span&gt; &lt;span class="nx"&gt;reserveB&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;internal&lt;/span&gt; &lt;span class="nx"&gt;pure&lt;/span&gt; &lt;span class="nx"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;uint&lt;/span&gt; &lt;span class="nx"&gt;amountB&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amountA&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;UniswapV2Library: INSUFFICIENT_AMOUNT&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;reserveA&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;reserveB&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;UniswapV2Library: INSUFFICIENT_LIQUIDITY&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;amountB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;amountA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mul&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;reserveB&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;reserveA&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's a set of restrictions and arithmetics operations, so it will be implemented in Soroban without any problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  The &lt;code&gt;getAmount...&lt;/code&gt; functions
&lt;/h2&gt;

&lt;p&gt;There are four important functions in Uniswap's code: &lt;code&gt;getAmountOut&lt;/code&gt;, &lt;code&gt;getAmountIn&lt;/code&gt;, &lt;code&gt;getAmountsOut&lt;/code&gt; and &lt;code&gt;getAmountsIn&lt;/code&gt; that are similar. These functions are used for making trades and managing liquidity in Uniswap.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;getAmountOut&lt;/code&gt;` calculates how much of one token you can get when you put in another token, considering fees and available reserves.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;getAmountIn&lt;/code&gt; does the opposite, determining how much you need to put in to get a specific amount of another token.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;getAmountsOut&lt;/code&gt; and &lt;code&gt;getAmountsIn&lt;/code&gt;` help with more complex trades that involve multiple steps, like going from Token A to Token B to Token C. They make sure you get the right amount at each step.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These operations involve  math and checks. These same operations can be easily recreated in Rust and Soroban.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Deterministic Address in Soroban</title>
      <dc:creator>esteblock</dc:creator>
      <pubDate>Wed, 04 Oct 2023 11:46:19 +0000</pubDate>
      <link>https://dev.to/esteblock/deterministic-address-in-soroban-4eck</link>
      <guid>https://dev.to/esteblock/deterministic-address-in-soroban-4eck</guid>
      <description>&lt;p&gt;with Soroban, the Smart Contract Platform on Stellar we can know what the address of an smart contract will be, when we deploy the contract using a Deployer contract or Factory contract.&lt;/p&gt;

&lt;p&gt;In fact, from after &lt;strong&gt;soroban-sdk version 20.0.0-rc2&lt;/strong&gt; we can use the &lt;code&gt;deployed_address&lt;/code&gt; method for a &lt;code&gt;DeployerWithAddress&lt;/code&gt; struct. For more information please check the documentation here: &lt;a href="https://docs.rs/soroban-sdk/20.0.0-rc2/soroban_sdk/deploy/struct.DeployerWithAddress.html#method.deployed_address"&gt;https://docs.rs/soroban-sdk/20.0.0-rc2/soroban_sdk/deploy/struct.DeployerWithAddress.html#method.deployed_address&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can calculate the contract address like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pub fn calculate_address(
    env: Env, 
    deployer: Address,
    salt: BytesN&amp;lt;32&amp;gt;,
) -&amp;gt; Address {

    let deployer_with_address = env.deployer().with_address(deployer.clone(), salt);

    // Calculate deterministic address:
    // This function can be called at anytime, before or after the contract is deployed, because contract addresses are deterministic.
    // https://docs.rs/soroban-sdk/20.0.0-rc2/soroban_sdk/deploy/struct.DeployerWithAddress.html#method.deployed_address
    let deterministic_address = deployer_with_address.deployed_address();
    deterministic_address
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;I wrote a playground repo available here: &lt;a href="https://github.com/paltalabs/deterministic-address-soroban"&gt;https://github.com/paltalabs/deterministic-address-soroban&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Where we answer the following questions:&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Same WASM, different salt ✅
&lt;/h2&gt;

&lt;p&gt;Can a deployer deploy 2 contracts with same WASM and different salt?&lt;/p&gt;

&lt;p&gt;Answer: &lt;strong&gt;✅ Yes!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Check &lt;code&gt;test_deploy_from_contract_twice_same_wasm_different_salt&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Same WASM, same salt ❌
&lt;/h2&gt;

&lt;p&gt;Can a deployer deploys 2 contracts with same WASM and same salt?&lt;/p&gt;

&lt;p&gt;Answer: &lt;strong&gt;❌ No!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Check &lt;code&gt;test_deploy_from_contract_twice_same_wasm_same_salt_should_panic&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Different WASM, same salt ❌
&lt;/h2&gt;

&lt;p&gt;Can a deployer deploys 2 different contracts (different WASM) with same salt?&lt;/p&gt;

&lt;p&gt;Answer: &lt;strong&gt;❌ No!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Check &lt;code&gt;test_deploy_from_contract_different_wasm_same_salt_should_panic&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This proves that in fact &lt;strong&gt;the contract addresses does not depend on the WASM, but on the combination of address &amp;amp; salt&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Two deployers, same WASM, same salt ✅
&lt;/h2&gt;

&lt;p&gt;Can one deployer deploys a (wasm/salt) and another deployer deploys the same (wasm/salt)?&lt;/p&gt;

&lt;p&gt;Answer: &lt;strong&gt;✅ Yes!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Check &lt;code&gt;test_deploy_from_two_contract_deployers_same_wasm_same_salt&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;They have indeed different contract addreess, because, again, the contract address depends on the combination of address&amp;amp;salt.!!&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Calculate a deterministic address
&lt;/h2&gt;

&lt;p&gt;Can we calculate the address of a contract only knowing the address of the factory that will (or that already did) deploy the contract and the salt used (or to be used)?&lt;/p&gt;

&lt;p&gt;Answer: &lt;strong&gt;✅ Yes!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Check &lt;code&gt;test_calculate_address&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;After &lt;code&gt;soroban-sdk = { version = "20.0.0-rc2" }&lt;/code&gt;, we can use the &lt;code&gt;deployed_address&lt;/code&gt; method for a &lt;code&gt;DeployerWithAddress&lt;/code&gt; struct. For more information please check the documentation here: &lt;a href="https://docs.rs/soroban-sdk/20.0.0-rc2/soroban_sdk/deploy/struct.DeployerWithAddress.html#method.deployed_address"&gt;https://docs.rs/soroban-sdk/20.0.0-rc2/soroban_sdk/deploy/struct.DeployerWithAddress.html#method.deployed_address&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>The Router Contract: Comparison between Soroswap and UniswapV2</title>
      <dc:creator>esteblock</dc:creator>
      <pubDate>Tue, 12 Sep 2023 15:45:50 +0000</pubDate>
      <link>https://dev.to/esteblock/the-router-contract-comparison-between-soroswap-and-uniswapv2-2dmn</link>
      <guid>https://dev.to/esteblock/the-router-contract-comparison-between-soroswap-and-uniswapv2-2dmn</guid>
      <description>&lt;p&gt;Check this and more in docs.soroswap.finance&lt;/p&gt;

&lt;p&gt;Until now, we have developed the Factory and the Pair contract. The factory knows how many pairs it has created and can give us their contract addresses. Also, if we want to trade between token A and token B, and if that pair exists, the Factory will also give us the corresponding pair contract address.&lt;/p&gt;

&lt;p&gt;But what happens if there are two pairs, A-B and B-C, and a user wants to make a trade between A and C? We could first trade A to B and then B to C! This is why we have the Router Contract.&lt;/p&gt;

&lt;p&gt;The Router Contract allows swapping of tokens when a direct pair does not exist. It also handles liquidity provision and manages deposit and withdrawal functions for liquidity providers within the Soroswap ecosystem.&lt;/p&gt;

&lt;h1&gt;
  
  
  The native token: ETH, WETH, and XLM.
&lt;/h1&gt;

&lt;p&gt;In the &lt;code&gt;UniswapV2Router02&lt;/code&gt;, there is a very important distinction between any ERC20 tokens and the native token ETH (and its wrapped version WETH). In particular, in the contract we find:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;address&lt;/span&gt; &lt;span class="kr"&gt;public&lt;/span&gt; &lt;span class="nx"&gt;immutable&lt;/span&gt; &lt;span class="nx"&gt;override&lt;/span&gt; &lt;span class="nx"&gt;WETH&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With UniswapV2Router02, if you are using ETH, you'll need to use special functions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;addLiquidityETH&lt;/code&gt; instead of &lt;code&gt;addLiquidity&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;removeLiquidityETH&lt;/code&gt; instead of &lt;code&gt;removeLiquidity&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;removeLiquidityETHWithPermit&lt;/code&gt; instead of &lt;code&gt;removeLiquidityWithPermit&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Instead of just having &lt;code&gt;swapExactTokensForTokens&lt;/code&gt; and &lt;code&gt;swapTokensForExactTokens&lt;/code&gt;; Uniswap Router needs to add 4 extra functions: &lt;code&gt;swapExactETHForTokens&lt;/code&gt;, &lt;code&gt;swapTokensForExactETH&lt;/code&gt;, 
&lt;code&gt;swapExactTokensForETH&lt;/code&gt;, &lt;code&gt;swapETHForExactTokens&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Instead of just having &lt;code&gt;swapExactTokensForTokensSupportingFeeOnTransferTokens&lt;/code&gt;, Uniswap Router needs to add 2 extra functions: &lt;code&gt;swapExactETHForTokensSupportingFeeOnTransferTokens&lt;/code&gt; and &lt;code&gt;swapExactTokensForETHSupportingFeeOnTransferTokens&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is because it's very common that in Blockchains, the native token (in this case ETH in Ethereum) is treated differently, so the smart contract needs to trigger different functions when transferring the native token.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What about in Soroban?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Well, in Soroban, we won't need to have all these extra functions! This is because the native XML token has its own token contract address and can be treated as any other token complying with the token interface.&lt;/p&gt;

&lt;p&gt;You can find more information about this in the Soroban Token Playground Chapter 8, 9, 10, and 11.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion:&lt;/strong&gt;&lt;br&gt;
Only the following functions will be written:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;addLiquidity&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;removeLiquidityWithPermit&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;swapExactTokensForTokens&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;swapTokensForExactTokens&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;swapExactTokensForTokensSupportingFeeOnTransferTokens&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The following functions won't be written:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;addLiquidityETH&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;removeLiquidityETH&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;removeLiquidityETHWithPermit&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;swapExactETHForTokens&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;swapTokensForExactETH&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;swapExactTokensForETH&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;swapETHForExactTokens&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;swapExactETHForTokensSupportingFeeOnTransferTokens&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;swapExactTokensForETHSupportingFeeOnTransferTokens&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also, because we will treat XML as any other token, we won't need to define its address. We won't need to write something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;address&lt;/span&gt; &lt;span class="kr"&gt;public&lt;/span&gt; &lt;span class="nx"&gt;immutable&lt;/span&gt; &lt;span class="nx"&gt;override&lt;/span&gt; &lt;span class="nx"&gt;WETH&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, there is also no need for this function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;receive&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="nx"&gt;external&lt;/span&gt; &lt;span class="nx"&gt;payable&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sender&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nx"&gt;WETH&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// only accept ETH via fallback from the WETH contract&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;as XML can only be sent using the native contract.&lt;/p&gt;

&lt;h1&gt;
  
  
  SafeMath
&lt;/h1&gt;

&lt;p&gt;In Solidity, the SafeMath library is used to validate arithmetic operations and prevent integer overflow/underflow. Should such a situation arise, the library throws an exception, which effectively reverts the transaction.&lt;/p&gt;

&lt;p&gt;In Rust, we can achieve similar functionality by activating the overflow check flag during the compilation process with the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[profile.release]&lt;/span&gt;
&lt;span class="py"&gt;overflow-checks&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Additionally, we use an overflow-safe implementation of functions &lt;code&gt;checked_add&lt;/code&gt;, &lt;code&gt;checked_mul&lt;/code&gt;, &lt;code&gt;checked_div&lt;/code&gt;, and &lt;code&gt;checked_sub&lt;/code&gt;. You can explore these functions and test their functionality in this repository:  &lt;a href="https://github.com/esteblock/overflow-soroban/"&gt;Overflow Soroban Repository&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also, we have overflow-safe functions &lt;code&gt;checked_add&lt;/code&gt;, &lt;code&gt;checked_mul&lt;/code&gt;, &lt;code&gt;checked_div&lt;/code&gt; and &lt;code&gt;checked_sub&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You can check and test these techniques in the following repository: &lt;a href="https://github.com/esteblock/overflow-soroban/"&gt;Overflow Soroban Repository&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In conclusion, Soroswap prevents overflows by leveraging these techniques.&lt;/p&gt;

&lt;h1&gt;
  
  
  Deadlines
&lt;/h1&gt;

&lt;p&gt;In Ethereum we can send a transaction with low gas price, and that transaction could be accepted 5, 10 or more minutes later. In order to avoid unwanted transactions after a period of time, Uniswap introduces the &lt;code&gt;deadline&lt;/code&gt; parameter and the &lt;code&gt;ensure(deadline)&lt;/code&gt; modifier:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;modifier&lt;/span&gt; &lt;span class="nx"&gt;ensure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;uint&lt;/span&gt; &lt;span class="nx"&gt;deadline&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;deadline&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nx"&gt;block&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;UniswapV2Router: EXPIRED&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In Soroban, we can think that having a transaction waiting for minutes is something that can never happen. But because we don't want to say &lt;strong&gt;never&lt;/strong&gt;, Soroswap will include this "deadline modifier."&lt;/p&gt;

&lt;p&gt;Modifiers do not currently exist in the &lt;code&gt;soroban-sdk&lt;/code&gt;. So we'll need to build a special function using the &lt;code&gt;env.ledger().timestamp()&lt;/code&gt; object.&lt;/p&gt;

&lt;h1&gt;
  
  
  Permit
&lt;/h1&gt;

&lt;p&gt;In &lt;code&gt;UniswapV2Router02&lt;/code&gt; we use the &lt;code&gt;permit&lt;/code&gt; method of the &lt;code&gt;UniswapV2ERC20.sol&lt;/code&gt; contracts that is defined &lt;a href="https://github.com/Uniswap/v2-core/blob/master/contracts/UniswapV2ERC20.sol"&gt;here&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;permit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt; &lt;span class="nx"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;address&lt;/span&gt; &lt;span class="nx"&gt;spender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;uint&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;uint&lt;/span&gt; &lt;span class="nx"&gt;deadline&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;uint8&lt;/span&gt; &lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;bytes32&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;bytes32&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;external&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;deadline&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nx"&gt;block&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;UniswapV2: EXPIRED&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;bytes32&lt;/span&gt; &lt;span class="nx"&gt;digest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;keccak256&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nx"&gt;abi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;encodePacked&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s1"&gt;x19&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s1"&gt;x01&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="nx"&gt;DOMAIN_SEPARATOR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="nx"&gt;keccak256&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;abi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PERMIT_TYPEHASH&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;spender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;nonces&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;deadline&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="p"&gt;)&lt;/span&gt; 
        &lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;address&lt;/span&gt; &lt;span class="nx"&gt;recoveredAddress&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ecrecover&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;digest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;recoveredAddress&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;recoveredAddress&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nx"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;UniswapV2: INVALID_SIGNATURE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;_approve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;spender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function implements &lt;a href="https://eips.ethereum.org/EIPS/eip-2612"&gt;EIP-2612&lt;/a&gt;. This avoids the user to use 2 transactions &lt;code&gt;approve&lt;/code&gt; and `transfer, which allows users to modify the allowance mapping using a signed message. this function allows a token holder to grant permission for a specific address (spender) to spend their tokens up to a certain amount (value) with a specified expiration time (deadline). The signature ensures the authenticity of the permit, and the function enforces that the permit hasn't expired and that it was signed by the legitimate token owner.&lt;/p&gt;

&lt;p&gt;In Soroban we don't need to implement something like this, as we use the &lt;code&gt;require.auth()&lt;/code&gt; method when sending tokens from the user into the smart contract.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion:&lt;/strong&gt; We don't need to impement the &lt;code&gt;removeLiquidityWithPermit&lt;/code&gt;, neither the &lt;code&gt;removeLiquidityETHWithPermit&lt;/code&gt; functions (neither &lt;code&gt;removeLiquidityETHWithPermitSupportingFeeOnTransferTokens&lt;/code&gt;)&lt;/p&gt;

&lt;h1&gt;
  
  
  Fees on Transfer
&lt;/h1&gt;

&lt;p&gt;In UniswapV2, there is a special function that allows the user to swap tokens that charge a fee when doing a transfer. This tokens are popular in the &lt;strong&gt;deflactionist community&lt;/strong&gt;, and indeed it made Uniswap upgrade their original &lt;a href="https://github.com/Uniswap/v2-periphery/blob/master/contracts/UniswapV2Router01.sol"&gt;UniswapV2Router&lt;/a&gt; (latter called UniswapV2Router01) contract to a &lt;a href="https://github.com/Uniswap/v2-periphery/blob/master/contracts/UniswapV2Router02.sol"&gt;UniswapV2Router02&lt;/a&gt; version!&lt;/p&gt;

&lt;p&gt;You can read all the discussion of the Uniswap design in &lt;a href="https://github.com/Uniswap/interface/issues/835"&gt;this issue&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the code we see many functions that have the word &lt;code&gt;SupportingFeeOnTransferTokens&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;_swapSupportingFeeOnTransferTokens&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;swapExactTokensForTokensSupportingFeeOnTransferTokens&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;swapExactETHForTokensSupportingFeeOnTransferTokens&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;swapExactTokensForETHSupportingFeeOnTransferTokens&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;removeLiquidityETHSupportingFeeOnTransferTokens&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But in fact there is only two functions that do all the work: &lt;code&gt;_swapSupportingFeeOnTransferTokens&lt;/code&gt; and &lt;code&gt;removeLiquidityETHSupportingFeeOnTransferTokens&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;These functions work equal to &lt;code&gt;_swap&lt;/code&gt; and &lt;code&gt;removeLiquidityETH&lt;/code&gt; but succeeds for tokens that take a fee on transfer.&lt;/p&gt;

&lt;p&gt;Because in Soroswap we want to support all types of tokens, we will implement these logics in the SoroswapRouter contract!&lt;/p&gt;

&lt;h1&gt;
  
  
  library UniswapV2Library
&lt;/h1&gt;

&lt;p&gt;UniswapV2Router uses the UniswapV2Library. This is something that Soroswap will also develop&lt;/p&gt;

&lt;h1&gt;
  
  
  What's next?
&lt;/h1&gt;

&lt;p&gt;Write rust!&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
