<?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: Mark Santiago</title>
    <description>The latest articles on DEV Community by Mark Santiago (@marksantiago290).</description>
    <link>https://dev.to/marksantiago290</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%2F2461201%2Fdd1f553e-b5a4-4dd9-85cc-67d9e9744014.png</url>
      <title>DEV Community: Mark Santiago</title>
      <link>https://dev.to/marksantiago290</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/marksantiago290"/>
    <language>en</language>
    <item>
      <title>Agile Project Management in Software Development Teams</title>
      <dc:creator>Mark Santiago</dc:creator>
      <pubDate>Thu, 23 Oct 2025 07:26:49 +0000</pubDate>
      <link>https://dev.to/marksantiago290/agile-project-management-in-software-development-teams-20bl</link>
      <guid>https://dev.to/marksantiago290/agile-project-management-in-software-development-teams-20bl</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In today’s rapidly evolving software development landscape, traditional project management models often struggle to keep pace with shifting priorities, emerging technologies, and increasingly dynamic stakeholder expectations. Agile project management has emerged as a powerful alternative—offering flexibility, collaboration, and continuous improvement as core values.&lt;/p&gt;

&lt;p&gt;Agile’s strength lies in its adaptability. In a world where market conditions, technologies, and customer needs can pivot overnight, Agile allows development teams to respond effectively without losing momentum. By emphasizing iterative progress, stakeholder engagement, and team collaboration, Agile ensures that software is not only built faster but is also more aligned with user needs and business goals.&lt;/p&gt;

&lt;p&gt;This article explores how Agile project management enhances performance within medium-sized software development teams. We will examine its methodologies, practical applications, and the specific advantages it offers teams that must remain adaptive, efficient, and forward-thinking in an increasingly complex software environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding Agile in Software Development Project Management
&lt;/h2&gt;

&lt;p&gt;Agile project management originated in the software engineering domain as a response to rigid, documentation-heavy processes that often hindered innovation. Instead of large, inflexible project plans, Agile focuses on developing software in small, manageable increments—each iteration producing a functional version of the product.&lt;/p&gt;

&lt;p&gt;At its core, Agile promotes continuous improvement, transparency, and collaboration between all stakeholders. It encourages teams to embrace change as a natural and beneficial part of the development process. For medium-sized teams, this approach is particularly valuable: it creates an operational rhythm that balances flexibility with control, allowing teams to pivot quickly while maintaining a clear direction.&lt;/p&gt;

&lt;p&gt;Whether the goal is to build a new application, upgrade existing infrastructure, or sustain legacy systems, Agile provides a framework that helps teams manage complexity and uncertainty with confidence.&lt;/p&gt;

&lt;p&gt;Agile Methodologies in Practice&lt;br&gt;
Agile is a philosophy supported by several methodologies, each offering unique benefits. The two most prevalent in software development are &lt;strong&gt;Scrum&lt;/strong&gt; and &lt;strong&gt;Kanban&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scrum&lt;/strong&gt; structures work into fixed-length iterations known as sprints, typically lasting one to four weeks. During each sprint, the team commits to completing specific deliverables. Regular touchpoints—such as daily stand-ups, sprint planning meetings, and retrospectives—ensure alignment, continuous learning, and accountability. Scrum is an excellent choice for teams that prefer a well-defined process and predictable delivery cycles.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Kanban&lt;/strong&gt;, by contrast, emphasizes flexibility and visual workflow management. Through a Kanban board that displays each stage of work (e.g., to-do, in progress, done), teams gain immediate insight into task status, enabling them to identify bottlenecks and optimize throughput. Kanban suits environments that require constant prioritization and a balanced flow of new and ongoing work.&lt;/p&gt;

&lt;p&gt;Both methodologies share core Agile principles: visibility, communication, and adaptability. When applied effectively, they empower medium-sized teams to balance multiple deliverables, adjust swiftly to evolving requirements, and maintain project stability.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Benefits of Agile Project Management for Medium-Sized Teams
&lt;/h2&gt;

&lt;p&gt;Medium-sized software development teams—often managing several concurrent projects—stand to benefit greatly from Agile’s iterative, feedback-driven approach. Its practical advantages are numerous:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Enhanced Software Quality&lt;br&gt;
Agile promotes continuous testing, integration, and review, enabling teams to identify and fix issues early. Regular quality assurance efforts throughout the development cycle ensure that the final product meets usability, security, and performance standards before release. This proactive focus on quality not only prevents costly rework but strengthens user confidence in the final product.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Greater Flexibility and Responsiveness&lt;br&gt;
Because Agile welcomes change, teams can adjust priorities and scope even late in development. This responsiveness is critical for medium-sized teams working in dynamic industries, where client feedback and emerging technologies frequently reshape project goals. Agile provides a structured way to adapt—without derailing timelines or outcomes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Improved Team Collaboration&lt;br&gt;
Agile fosters open communication and shared accountability. Through daily interactions, sprint reviews, and retrospectives, developers, designers, testers, and stakeholders remain connected to a common vision. This transparency strengthens team cohesion, promotes diversity of thought, and accelerates problem-solving.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Predictable Delivery and Transparency&lt;br&gt;
Agile’s time-boxed sprints and clear backlog prioritization make progress measurable and predictable. Teams and stakeholders gain visibility into what is being developed, when it will be delivered, and how changes affect overall timelines. This consistency builds trust and makes long-term planning more reliable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Effective Risk Mitigation&lt;br&gt;
By delivering in small increments, Agile greatly reduces project risk. Early feedback reveals potential flaws before they scale, and regular retrospectives allow continuous process improvements. For medium-sized teams with limited resources, this adaptive risk control is essential for maintaining stability and ensuring successful project outcomes.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Agile’s Role in Medium-Sized Teams: Bridging Strategy and Execution
&lt;/h2&gt;

&lt;p&gt;Medium-sized teams often fall between the high agility of small startups and the structural complexity of large organizations. They face significant challenges—balancing innovation with governance, and adaptability with coordination. Agile provides the connective tissue between strategic vision and technical execution.&lt;/p&gt;

&lt;p&gt;To maximize its impact, Agile must be tailored to team dynamics. Scaled frameworks such as SAFe (Scaled Agile Framework) or LeSS (Large-Scale Scrum) can help align multiple teams working toward shared objectives. Meanwhile, clear role definitions—Product Owner, Scrum Master, and Development Team—ensure accountability and prevent overlaps.&lt;/p&gt;

&lt;p&gt;In practice, this alignment allows medium-sized teams to maintain the speed and flexibility of smaller units while operating with the structure and discipline needed to handle complex, multi-stakeholder projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In the modern software landscape, agility is not a luxury but a necessity. For medium-sized development teams, Agile project management provides a practical, human-centered framework that harmonizes innovation, quality, and adaptability. It empowers teams to collaborate effectively, respond to change with confidence, and deliver solutions that meet both customer needs and business goals.&lt;/p&gt;

&lt;p&gt;Whether building new products or enhancing existing ones, Agile transforms the way teams approach software development—replacing rigidity with responsiveness, and uncertainty with continuous improvement. By embracing Agile principles, medium-sized software teams can cultivate a sustainable culture of excellence, where productivity, collaboration, and customer value thrive together.&lt;/p&gt;

</description>
      <category>agile</category>
      <category>webdev</category>
      <category>startup</category>
      <category>programming</category>
    </item>
    <item>
      <title>Automated Server Provisioning: A DevOps Framework for Enterprise Scale</title>
      <dc:creator>Mark Santiago</dc:creator>
      <pubDate>Wed, 08 Oct 2025 18:28:29 +0000</pubDate>
      <link>https://dev.to/marksantiago290/automated-server-provisioning-a-devops-framework-for-enterprise-scale-peb</link>
      <guid>https://dev.to/marksantiago290/automated-server-provisioning-a-devops-framework-for-enterprise-scale-peb</guid>
      <description>&lt;h2&gt;
  
  
  🧭 Business Goal
&lt;/h2&gt;

&lt;p&gt;Reduce &lt;strong&gt;server provisioning time and configuration errors by 75%&lt;/strong&gt; for enterprise IT teams — enabling rapid scaling of cloud infrastructure while maintaining &lt;strong&gt;compliance, consistency, and reliability&lt;/strong&gt; across more than &lt;strong&gt;10,000 nodes&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔍 Problem Identification &amp;amp; Scope
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Pain Points
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Manual provisioning&lt;/strong&gt; required over &lt;strong&gt;2 hours per machine&lt;/strong&gt; (OS install, package setup, security configuration).
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Configuration drift&lt;/strong&gt; led to production outages (e.g., mismatched firewall rules).
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Audit failures&lt;/strong&gt; occurred due to undocumented or manual changes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Objective
&lt;/h3&gt;

&lt;p&gt;Automate server provisioning and enforce standardized configurations using &lt;strong&gt;version-controlled YAML playbooks&lt;/strong&gt;, ensuring repeatable, compliant infrastructure across all environments.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚙️ Technical Implementation Phases
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Phase 1: Configuration Standardization&lt;/strong&gt;
&lt;/h3&gt;

&lt;h4&gt;
  
  
  YAML Template Design
&lt;/h4&gt;

&lt;p&gt;Configurations were modularized into reusable roles for maintainability.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# web-server.yml&lt;/span&gt;
&lt;span class="na"&gt;roles&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;common&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;  
      &lt;span class="na"&gt;packages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;nginx&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;nodejs&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;  
      &lt;span class="na"&gt;firewall&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;  
        &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;80&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;443&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;security&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;  
      &lt;span class="na"&gt;users&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;admin&lt;/span&gt;  
          &lt;span class="na"&gt;sudo&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  ✅ Validation
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Schema checks&lt;/strong&gt; via &lt;code&gt;yamllint&lt;/code&gt; and custom &lt;strong&gt;Python scripts&lt;/strong&gt; ensured structural integrity of YAML playbooks.&lt;/p&gt;




&lt;h2&gt;
  
  
  🗂️ Version Control
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;infra-configs:&lt;/strong&gt; Main repository for YAML playbooks.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;env-specific branches:&lt;/strong&gt; Separate branches for &lt;code&gt;dev&lt;/code&gt;, &lt;code&gt;stage&lt;/code&gt;, and &lt;code&gt;prod&lt;/code&gt; environments.

&lt;ul&gt;
&lt;li&gt;Example: The &lt;code&gt;dev&lt;/code&gt; branch allows SSH access from a wider range of IPs for testing.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  ⚙️ Phase 2: Ansible Automation Development
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Playbook Design
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Idempotent Tasks:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Ensured repeatable and predictable execution for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Installing packages
&lt;/li&gt;
&lt;li&gt;Managing users
&lt;/li&gt;
&lt;li&gt;Deploying TLS certificates
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Modular Roles:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Example: A logging role deployed &lt;strong&gt;Fluentd&lt;/strong&gt; and integrated with &lt;strong&gt;AWS CloudWatch&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Error Handling:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Retries for transient failures (e.g., package repository timeouts).
&lt;/li&gt;
&lt;li&gt;Slack notifications for critical task failures.&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;
  
  
  Dynamic Inventory
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AWS EC2 Integration:&lt;/strong&gt; Automatically discovered instances via tags (e.g., &lt;code&gt;env:prod&lt;/code&gt;).
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custom On-Prem Mapping:&lt;/strong&gt; Python scripts mapped YAML configurations to local IP ranges.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  🚀 Phase 3: CI/CD Pipeline Integration
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Jenkins Workflow
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Triggers:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Git webhooks on &lt;code&gt;main&lt;/code&gt; branch commits
&lt;/li&gt;
&lt;li&gt;Scheduled daily compliance runs
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pipeline Stages:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Lint YAML files
&lt;/li&gt;
&lt;li&gt;Dry-run Ansible playbooks
&lt;/li&gt;
&lt;li&gt;Deploy to &lt;code&gt;dev&lt;/code&gt; and &lt;code&gt;stage&lt;/code&gt; servers
&lt;/li&gt;
&lt;li&gt;Manual approval gate for &lt;code&gt;prod&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Rollback Mechanism:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
If a production deployment fails, &lt;strong&gt;Jenkins automatically triggers a Git revert&lt;/strong&gt; and reapplies the last stable configuration.&lt;/p&gt;


&lt;h2&gt;
  
  
  🧩 Phase 4: Deployment &amp;amp; Validation
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Target Environments
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cloud (AWS/GCP):&lt;/strong&gt; Auto-scaling groups execute Ansible during instance launch.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;On-Prem:&lt;/strong&gt; PXE boot + Kickstart files trigger Ansible post-OS installation.&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;
  
  
  Compliance Checks
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;InSpec&lt;/strong&gt; was used to validate post-deployment configurations.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;  
  &lt;span class="n"&gt;its&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'addresses'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;should&lt;/span&gt; &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="s1"&gt;'10.0.0.0/8'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;  
&lt;span class="k"&gt;end&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This ensured that all deployed servers adhered to defined &lt;strong&gt;security and compliance policies&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  📈 Phase 5: Monitoring &amp;amp; Reporting
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Dashboards
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Grafana:&lt;/strong&gt; Visualized server setup time and playbook success rates.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Splunk:&lt;/strong&gt; Audited Ansible logs to detect unauthorized or manual changes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Alerting
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Prometheus:&lt;/strong&gt; Triggered alerts when configuration drift was detected (e.g., unexpected package versions).&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧰 Tech Stack
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Category&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Tools&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Automation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Ansible, Python&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;CI/CD&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Jenkins, Git&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Monitoring&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Prometheus, Grafana, InSpec&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cloud&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;AWS EC2, CloudWatch&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  📊 Results &amp;amp; Impact
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Metric&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Manual Process&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Automated Tool&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Setup Time/Server&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;2.3 hours&lt;/td&gt;
&lt;td&gt;0.5 hours (&lt;strong&gt;-78%&lt;/strong&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Configuration Errors&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;12% of servers&lt;/td&gt;
&lt;td&gt;0.8%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Audit Pass Rate&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;65%&lt;/td&gt;
&lt;td&gt;98%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cost Savings:&lt;/strong&gt; $420K/year in reduced labor for a 5,000-server fleet.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability:&lt;/strong&gt; Deployed &lt;strong&gt;1,000+ identical development servers&lt;/strong&gt; in 8 hours during a cloud migration.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  💡 Lessons Learned
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Idempotency Matters&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Every Ansible task must be repeatable without unintended side effects (e.g., appending to files multiple times).&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Git Hygiene&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Enforced pull request reviews for all YAML changes to protect production stability.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Cultural Adoption&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Empowering teams to own playbooks fostered accountability and faster iteration cycles.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>automation</category>
      <category>ai</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How to Use ChatGPT to Build AI Voice Agents Effectively</title>
      <dc:creator>Mark Santiago</dc:creator>
      <pubDate>Wed, 08 Oct 2025 16:58:02 +0000</pubDate>
      <link>https://dev.to/marksantiago290/how-to-use-chatgpt-to-build-ai-voice-agents-effectively-jd9</link>
      <guid>https://dev.to/marksantiago290/how-to-use-chatgpt-to-build-ai-voice-agents-effectively-jd9</guid>
      <description>&lt;p&gt;AI voice agent platforms are evolving at lightning speed. While &lt;strong&gt;ChatGPT&lt;/strong&gt; can be an incredibly powerful assistant during development, relying solely on it can sometimes lead to outdated or incorrect implementations.&lt;br&gt;&lt;br&gt;
Following inaccurate or stale information can be frustrating and time-consuming.&lt;/p&gt;

&lt;p&gt;This guide provides &lt;strong&gt;practical tips and best practices&lt;/strong&gt; for using ChatGPT to &lt;strong&gt;build reliable AI voice agents&lt;/strong&gt;, ensuring accuracy, efficiency, and alignment with the latest documentation.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;Scope&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;AI voice agent development is a fast-moving field. ChatGPT can serve as a &lt;strong&gt;co-developer&lt;/strong&gt; that helps design conversation logic, debug integrations, and optimize prompts — but it’s not a replacement for official documentation.&lt;/p&gt;

&lt;p&gt;This article outlines &lt;strong&gt;how to strategically use ChatGPT&lt;/strong&gt; to assist with each phase of the voice agent lifecycle while avoiding pitfalls caused by outdated information.&lt;/p&gt;


&lt;h2&gt;
  
  
  &lt;strong&gt;Background&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;A typical &lt;strong&gt;AI voice agent lifecycle&lt;/strong&gt; includes three main stages:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Create&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Deploy&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Among these, the &lt;strong&gt;Create&lt;/strong&gt; phase is where ChatGPT is most useful — helping design the agent’s behavior, conversation flow, and integrations with backend systems.&lt;/p&gt;


&lt;h2&gt;
  
  
  &lt;strong&gt;Core Components of AI Voice Agents&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Building a successful AI voice agent involves several interconnected parts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Conversation Flow&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Prompt Writing&lt;/em&gt; (supported by all platforms)&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Conversational Pathways&lt;/em&gt; (natively supported by tools like &lt;strong&gt;Bland&lt;/strong&gt; and &lt;strong&gt;Retell&lt;/strong&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Function Calling&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;In-call Behavior&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Post-call Analysis&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Call Transfer&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Settings Configuration&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
(e.g., backchannel setup, fallback responses, or environment settings)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  &lt;strong&gt;Key Challenges&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Developers often face a few recurring issues when building AI voice agents:&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;1. Fragmented Workflows&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Integrating multiple systems — prompts, flows, and automation — into a cohesive pipeline can be tricky, especially when AI outputs aren’t deterministic.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;2. Testing Frustrations&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;AI models may produce slightly different responses each time, making it hard to debug or replicate issues consistently.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;3. Keeping Up With Platform Changes&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;AI voice platforms like Bland and Retell evolve quickly. The most common frustration is when ChatGPT references &lt;strong&gt;outdated API docs or schema formats&lt;/strong&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  &lt;strong&gt;Important Tips for Using ChatGPT Effectively&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;ChatGPT can be your best assistant for &lt;strong&gt;idea generation, flow design, and debugging&lt;/strong&gt;, but you must pair it with &lt;strong&gt;official platform documentation&lt;/strong&gt; for accuracy.&lt;/p&gt;


&lt;h3&gt;
  
  
  &lt;strong&gt;1. Conversation Flow Design&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;There are two main approaches to designing AI voice agent conversations:&lt;/p&gt;
&lt;h4&gt;
  
  
  &lt;strong&gt;(1) Prompt Writing&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;ChatGPT is excellent at helping you &lt;strong&gt;draft and refine prompts&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
Start by outlining the main conversation goals or call structure. Then, paste that into ChatGPT and ask it to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rewrite the prompt naturally and clearly
&lt;/li&gt;
&lt;li&gt;Add context awareness and user intent handling
&lt;/li&gt;
&lt;li&gt;Include fallback or escalation phrases
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once finalized, copy the prompt directly into your AI voice platform.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;✅ &lt;em&gt;Tip:&lt;/em&gt; This method works best for single-prompt or light-flow agents.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;
  
  
  &lt;strong&gt;(2) Conversation Flow Mapping&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;For more complex, multi-turn conversations, platforms like &lt;strong&gt;Bland&lt;/strong&gt; and &lt;strong&gt;Retell&lt;/strong&gt; allow you to define structured conversation flows.&lt;/p&gt;

&lt;p&gt;Since these formats change often, always provide ChatGPT with the &lt;strong&gt;latest documentation URL&lt;/strong&gt; and say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Follow the latest Bland/Retell conversation flow format to build or fix this section.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This ensures ChatGPT references the most recent syntax and conventions.&lt;/p&gt;


&lt;h3&gt;
  
  
  &lt;strong&gt;2. Function Calling and Integrations&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Function calling connects your agent to external systems or automations (e.g., &lt;strong&gt;N8N&lt;/strong&gt;, &lt;strong&gt;Make&lt;/strong&gt;, or custom webhooks).&lt;/p&gt;

&lt;p&gt;There are two layers here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Voice Agent Setup&lt;/strong&gt; (trigger functions during calls)
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automation Platform Setup&lt;/strong&gt; (handle webhooks or API responses)&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  &lt;strong&gt;Best Practice: Test with cURL&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Before connecting automations, test your webhook manually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://your-automation-url.com/webhook &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"message": "test"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can ask ChatGPT to generate the correct &lt;code&gt;curl&lt;/code&gt; command for your use case.&lt;br&gt;
This helps you &lt;strong&gt;debug integration errors&lt;/strong&gt; more precisely before embedding the function inside your voice agent.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;3. Call Transfer&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Call transfer logic is usually configured via the platform’s dashboard.&lt;br&gt;
ChatGPT can still assist by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Explaining the transfer setup process&lt;/li&gt;
&lt;li&gt;Writing user-facing transition prompts&lt;/li&gt;
&lt;li&gt;Troubleshooting SIP or API call routing issues&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By referencing documentation directly, ChatGPT can walk you through the steps for your specific platform.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;4. Settings Configuration&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;For advanced configurations such as &lt;strong&gt;backchanneling&lt;/strong&gt;, &lt;strong&gt;fallbacks&lt;/strong&gt;, or &lt;strong&gt;environment tuning&lt;/strong&gt;, ChatGPT can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Generate configuration templates&lt;/li&gt;
&lt;li&gt;Suggest error-handling patterns&lt;/li&gt;
&lt;li&gt;Validate setup instructions from documentation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When asking for help, specify your platform and say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Please reference the latest documentation for [platform name] to configure [feature].”&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;ChatGPT is a powerful &lt;strong&gt;co-developer&lt;/strong&gt; in building AI voice agents, particularly during the &lt;strong&gt;design&lt;/strong&gt; and &lt;strong&gt;setup&lt;/strong&gt; phases.&lt;br&gt;
However, its value depends on how strategically it’s used.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Takeaways&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Combine ChatGPT’s reasoning skills with official documentation.&lt;/li&gt;
&lt;li&gt;Use it for prompt design, conversation flow planning, and integration testing.&lt;/li&gt;
&lt;li&gt;Validate all configurations (e.g., webhooks, APIs) manually before deployment.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By following these principles, you can leverage ChatGPT not just as a chatbot — but as a creative, technical accelerator that helps you build smarter, more human-like AI voice agents faster.&lt;/p&gt;

</description>
      <category>chatgpt</category>
      <category>aivoiceagent</category>
      <category>voiceai</category>
    </item>
    <item>
      <title>Required Skills to Master as a Project Manager</title>
      <dc:creator>Mark Santiago</dc:creator>
      <pubDate>Tue, 16 Sep 2025 18:00:30 +0000</pubDate>
      <link>https://dev.to/marksantiago290/required-skills-to-master-as-a-project-manager-5211</link>
      <guid>https://dev.to/marksantiago290/required-skills-to-master-as-a-project-manager-5211</guid>
      <description>&lt;p&gt;After years of managing projects across different industries and team sizes, I've learned that successful project management isn't just about following a methodology or using the right tools. It's about developing a comprehensive skill set that combines technical expertise, leadership capabilities, and emotional intelligence. Based on extensive research and real-world experience, here are the essential skills every project manager needs to master.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Foundation: Core Leadership Skills
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Strategic Leadership
&lt;/h3&gt;

&lt;p&gt;The most effective project managers I've worked with don't just execute plans—they think strategically. They understand how their project fits into the bigger business picture and can communicate that vision to their teams. This means being able to translate high-level business objectives into actionable project goals and ensuring everyone understands the "why" behind their work.&lt;/p&gt;

&lt;h3&gt;
  
  
  Communication Excellence
&lt;/h3&gt;

&lt;p&gt;Let's be honest—project managers spend about 90% of their time communicating. Whether it's running stakeholder meetings, writing status updates, or having difficult conversations about scope creep, your ability to communicate clearly and effectively can make or break a project. I've seen too many technically brilliant projects fail because of poor communication.&lt;/p&gt;

&lt;p&gt;The key is learning to speak the language of different stakeholders. When talking to executives, focus on business impact and ROI. With technical teams, dive into the details and constraints. With clients, emphasize value and outcomes. It's not about dumbing things down—it's about meeting people where they are.&lt;/p&gt;

&lt;h3&gt;
  
  
  Team Leadership and Mentoring
&lt;/h3&gt;

&lt;p&gt;Great project managers don't just manage tasks; they develop people. I've found that teams perform better when they feel supported, challenged, and valued. This means taking time to understand each team member's strengths, providing constructive feedback, and creating opportunities for growth.&lt;/p&gt;

&lt;p&gt;The best project managers I know act as mentors, sharing their knowledge and experience while helping team members develop their own project management skills. This investment in people pays dividends in project success and team morale.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Technical Core: Project Management Fundamentals
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Project Planning and Scoping
&lt;/h3&gt;

&lt;p&gt;This is where many projects go wrong from the start. Effective project planning isn't just about creating a timeline—it's about understanding the full scope, identifying dependencies, and setting realistic expectations. I've learned that spending extra time upfront on planning saves countless hours of rework later.&lt;/p&gt;

&lt;p&gt;A solid project plan should include clear objectives, success metrics, stakeholder roles, budget constraints, key milestones, and a communication strategy. But here's the thing—your plan is a living document. The ability to adapt and adjust while maintaining project integrity is crucial.&lt;/p&gt;

&lt;h3&gt;
  
  
  Risk Management
&lt;/h3&gt;

&lt;p&gt;Every project has risks, and the best project managers are those who can anticipate and mitigate them before they become problems. This isn't about being pessimistic—it's about being prepared. I've developed a habit of asking "What could go wrong?" early and often, and then creating contingency plans.&lt;/p&gt;

&lt;p&gt;The most common risks I've encountered include scope creep, resource constraints, timeline delays, and stakeholder misalignment. Having mitigation strategies ready for these scenarios can mean the difference between project success and failure.&lt;/p&gt;

&lt;h3&gt;
  
  
  Agile and Hybrid Methodologies
&lt;/h3&gt;

&lt;p&gt;The project management landscape has evolved significantly. While traditional waterfall approaches still have their place, most organizations now require project managers who can work with Agile methodologies and hybrid approaches. This flexibility allows teams to respond quickly to changes while maintaining structure and accountability.&lt;/p&gt;

&lt;p&gt;I've found that the most successful project managers understand when to apply different methodologies based on project type, team dynamics, and organizational culture. It's not about being dogmatic about one approach—it's about choosing the right tool for the job.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Human Element: Soft Skills That Matter
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Stakeholder Engagement
&lt;/h3&gt;

&lt;p&gt;Managing stakeholders is an art form. You're dealing with people who have different priorities, communication styles, and levels of project involvement. The key is understanding what each stakeholder needs and how to keep them engaged throughout the project lifecycle.&lt;/p&gt;

&lt;p&gt;I've learned that stakeholder management isn't just about keeping people informed—it's about building relationships, managing expectations, and sometimes having difficult conversations about trade-offs. The ability to navigate these relationships while keeping the project on track is invaluable.&lt;/p&gt;

&lt;h3&gt;
  
  
  Problem Solving and Critical Thinking
&lt;/h3&gt;

&lt;p&gt;Projects rarely go exactly as planned, and the ability to think critically and solve problems quickly is essential. This means analyzing situations objectively, considering multiple solutions, and making decisions based on data rather than emotions.&lt;/p&gt;

&lt;p&gt;I've found that the best problem solvers are those who can step back from the immediate issue and see the bigger picture. They ask the right questions, gather relevant information, and consider the long-term implications of their decisions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adaptability and Change Management
&lt;/h3&gt;

&lt;p&gt;Change is constant in project management. Requirements shift, priorities change, and unexpected challenges arise. The most successful project managers are those who can adapt quickly while maintaining project momentum.&lt;/p&gt;

&lt;p&gt;This also includes managing organizational change. When implementing new processes or tools, project managers need to help their teams transition smoothly. This requires patience, clear communication, and a focus on the benefits of change.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Technical Toolkit: Tools and Technologies
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Project Management Software Proficiency
&lt;/h3&gt;

&lt;p&gt;Modern project management tools have evolved significantly from the complex systems of the past. Today's tools are designed to be intuitive and flexible, but they still require time to master. Whether you're using Asana, Microsoft Project, Jira, or another platform, understanding how to leverage these tools effectively can significantly improve your project outcomes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Data Analysis and Reporting
&lt;/h3&gt;

&lt;p&gt;Project managers need to be comfortable with data. This includes tracking project metrics, analyzing trends, and creating meaningful reports for stakeholders. The ability to translate raw data into actionable insights is crucial for project success and continuous improvement.&lt;/p&gt;

&lt;h3&gt;
  
  
  Budget and Cost Management
&lt;/h3&gt;

&lt;p&gt;Financial acumen is often overlooked in project management, but it's essential. Understanding how to create realistic budgets, track expenses, and manage costs throughout the project lifecycle can mean the difference between project success and failure.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Integration: Bringing It All Together
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Time Management and Organization
&lt;/h3&gt;

&lt;p&gt;With multiple projects, stakeholders, and deadlines to manage, organization is critical. This isn't just about keeping your own tasks organized—it's about creating systems that help your entire team stay focused and productive.&lt;/p&gt;

&lt;p&gt;I've found that the most effective project managers are those who can prioritize effectively, delegate appropriately, and maintain visibility into all aspects of their projects. This requires both personal discipline and the right tools and processes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Customer Service Orientation
&lt;/h3&gt;

&lt;p&gt;Even if you're not working directly with external customers, every project has stakeholders who need to be satisfied. This means approaching each project from the perspective of meeting stakeholder needs and delivering value.&lt;/p&gt;

&lt;p&gt;The best project managers I know are those who can balance competing demands while keeping the end user or customer in mind. They understand that project success isn't just about meeting technical requirements—it's about delivering something that truly serves its intended purpose.&lt;/p&gt;

&lt;h2&gt;
  
  
  Continuous Development: The Path Forward
&lt;/h2&gt;

&lt;p&gt;Mastering these skills isn't a one-time achievement—it's an ongoing process. The project management field continues to evolve, with new methodologies, tools, and best practices emerging regularly. The most successful project managers are those who commit to continuous learning and improvement.&lt;/p&gt;

&lt;p&gt;This might mean attending industry conferences, pursuing certifications, joining professional associations, or simply seeking out new challenges and experiences. The key is maintaining a growth mindset and being open to new approaches and ideas.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Project management is a complex discipline that requires a diverse skill set. While technical knowledge and tool proficiency are important, the most successful project managers are those who can combine these capabilities with strong leadership, communication, and interpersonal skills.&lt;/p&gt;

&lt;p&gt;The good news is that these skills can be developed over time. Start by focusing on the areas where you feel least confident, seek out opportunities for hands-on experience, and don't be afraid to learn from both successes and failures. Remember, every project is an opportunity to grow and improve your skills.&lt;/p&gt;

&lt;p&gt;The demand for skilled project managers continues to grow, and organizations are looking for professionals who can bring both technical expertise and leadership capabilities to their projects. By developing these essential skills, you'll not only improve your project outcomes but also advance your career in this dynamic and rewarding field.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>management</category>
    </item>
    <item>
      <title>Revenue Sharing Model: A Powerful Marketing Strategy for Token Presales</title>
      <dc:creator>Mark Santiago</dc:creator>
      <pubDate>Sat, 26 Jul 2025 16:16:11 +0000</pubDate>
      <link>https://dev.to/marksantiago290/revenue-sharing-model-a-powerful-marketing-strategy-for-token-presales-3k48</link>
      <guid>https://dev.to/marksantiago290/revenue-sharing-model-a-powerful-marketing-strategy-for-token-presales-3k48</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Launching a successful token presale is not just about having a great product or tokenomics—it’s also about building momentum, trust, and community engagement. One of the most effective ways to achieve this is by leveraging a &lt;strong&gt;revenue sharing model&lt;/strong&gt; as part of your presale marketing strategy. This approach incentivizes community members, influencers, and promoters to actively participate in and promote your presale, creating a win-win scenario for all parties involved.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a Revenue Sharing Model in Presales?
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;revenue sharing model&lt;/strong&gt; in the context of a token presale is a system where a portion of the funds raised (or tokens sold) is distributed as rewards to promoters or referrers who help bring in new investors. This model transforms your community into an active marketing force, aligning their interests with the success of your presale.&lt;/p&gt;

&lt;h3&gt;
  
  
  How It Works
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Promoter Registration:&lt;/strong&gt; Community members or influencers register as promoters and receive unique referral codes or links.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Referral Tracking:&lt;/strong&gt; When new investors participate in the presale using a promoter’s code, the system tracks these referrals.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reward Distribution:&lt;/strong&gt; After the presale round ends, a predefined percentage of the raised funds (in stablecoins or tokens) is distributed to promoters based on the contributions of their referred users.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transparency:&lt;/strong&gt; All transactions and reward calculations are handled by smart contracts, ensuring fairness and transparency.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why Use Revenue Sharing for Presale Marketing?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. &lt;strong&gt;Incentivized Word-of-Mouth&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;People are more likely to promote your project if they have a direct financial incentive. Revenue sharing turns every promoter into a stakeholder, motivating them to reach out to their networks and communities.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. &lt;strong&gt;Network Effects&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;As more promoters join and share your presale, your reach grows exponentially. This organic growth is often more effective and authentic than paid advertising.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. &lt;strong&gt;Community Engagement&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Rewarding promoters fosters a sense of ownership and loyalty. Engaged community members are more likely to support your project long-term, not just during the presale.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. &lt;strong&gt;Cost-Effective Marketing&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Instead of spending large sums on traditional marketing, you only pay for actual results—i.e., successful referrals that lead to investments.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. &lt;strong&gt;Transparency and Trust&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Smart contract-based revenue sharing ensures that rewards are distributed fairly and automatically, building trust among participants.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Components of a Revenue Sharing Presale
&lt;/h2&gt;

&lt;p&gt;While implementations may vary, a typical revenue sharing presale includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Promoter Registration:&lt;/strong&gt; A process for users to sign up as promoters and receive unique codes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Referral Tracking:&lt;/strong&gt; Mechanisms to track which investors used which promoter’s code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reward Calculation:&lt;/strong&gt; Logic to determine the share of revenue each promoter earns, often as a percentage of the referred investment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reward Claiming:&lt;/strong&gt; A transparent, on-chain process for promoters to claim their rewards after the presale round ends.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bonus for Referred Users:&lt;/strong&gt; Optionally, referred users may also receive a bonus, further incentivizing participation.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Example Workflow
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;+-------------------------+
| 1. Project Launches     |
|    Presale              |
+-----------+-------------+
            |
            v
+-------------------------+
| 2. Promoters Register   |
|    &amp;amp; Get Referral Codes |
+-----------+-------------+
            |
            v
+-------------------------+
| 3. Promoters Share      |
|    Codes with Community |
+-----------+-------------+
            |
            v
+-------------------------+
| 4. Investors Join       |
|    Presale Using Codes  |
+-----------+-------------+
            |
            v
+-------------------------+
| 5. Smart Contract       |
|    Tracks Referrals     |
+-----------+-------------+
            |
            v
+-------------------------+
| 6. Presale Ends         |
+-----------+-------------+
            |
            v
+-------------------------+
| 7. Promoters Claim      |
|    Revenue Share        |
+-----------+-------------+
            |
            v
+-------------------------+
| 8. Referred Users       |
|    Claim Bonuses        |
|    (Optional)           |
+-------------------------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Best Practices
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Set Clear Rules:&lt;/strong&gt; Define the percentage of revenue shared, eligibility, and claiming process upfront.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prevent Abuse:&lt;/strong&gt; Implement checks to prevent self-referrals or circular referrals.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Promote Transparency:&lt;/strong&gt; Make referral and reward data publicly viewable (e.g., via a dashboard).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Engage Promoters:&lt;/strong&gt; Provide marketing materials and support to help promoters succeed.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;A revenue sharing model is a powerful, community-driven marketing strategy for token presales. By aligning the interests of your project and its supporters, you can amplify your reach, build trust, and drive greater participation in your presale. As the blockchain space becomes more competitive, leveraging such innovative strategies can make the difference between a good presale and a great one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Note.
&lt;/h2&gt;

&lt;p&gt;If you wanna implement this revenue sharing model in your token presale, please contact to &lt;a href="https://t.me/marksantiago02" rel="noopener noreferrer"&gt;Mark Santiago&lt;/a&gt; and check the &lt;a href="https://github.com/marksantiago02/ERC20-Token-Presale-Smart-Contract" rel="noopener noreferrer"&gt;github repos&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thanks.&lt;br&gt;
Happy Coding.&lt;/p&gt;

</description>
      <category>presale</category>
      <category>erc20</category>
      <category>revenuesharing</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How to write solana wallet tracking telegram bot</title>
      <dc:creator>Mark Santiago</dc:creator>
      <pubDate>Sat, 01 Mar 2025 14:11:03 +0000</pubDate>
      <link>https://dev.to/marksantiago290/how-to-write-solana-wallet-tracking-telegram-bot-3m9h</link>
      <guid>https://dev.to/marksantiago290/how-to-write-solana-wallet-tracking-telegram-bot-3m9h</guid>
      <description>&lt;p&gt;A comprehensive guide to building a professional Solana wallet tracking system that monitors transactions and delivers real-time notifications through Telegram.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In the fast-moving world of Solana trading, staying informed about wallet activities is crucial. This guide will walk you through creating a sophisticated wallet tracking bot that monitors transactions and sends detailed notifications via Telegram.&lt;/p&gt;

&lt;h2&gt;
  
  
  System Architecture
&lt;/h2&gt;

&lt;p&gt;The system consists of three main components:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Helius RPC for transaction monitoring&lt;/li&gt;
&lt;li&gt;MongoDB for data storage&lt;/li&gt;
&lt;li&gt;Telegram Bot for notifications&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Step-by-Step Guide
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Setting Up Your Telegram Bot
&lt;/h3&gt;

&lt;p&gt;First, we'll create and configure your Telegram bot for notifications.&lt;/p&gt;

&lt;h4&gt;
  
  
  Creating your own Telegram bot
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Open Telegram and search for the &lt;a class="mentioned-user" href="https://dev.to/botfather"&gt;@botfather&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Send &lt;code&gt;/newbot&lt;/code&gt; command&lt;/li&gt;
&lt;li&gt;Name your bot (Example: "super_wallet_tracking_bot")&lt;/li&gt;
&lt;li&gt;Save your bot token&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Configuring Chat IDs
&lt;/h4&gt;

&lt;p&gt;Now we named our bot and get bot token, we need to get our chat ID.&lt;/p&gt;

&lt;p&gt;To get your chat ID:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add your bot to your channel&lt;/li&gt;
&lt;li&gt;Send a message&lt;/li&gt;
&lt;li&gt;Access: &lt;a href="https://api.telegram.org/bot" rel="noopener noreferrer"&gt;https://api.telegram.org/bot&lt;/a&gt;/getUpdates&lt;/li&gt;
&lt;li&gt;Extract the chat_id from the response&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Or you can use this script to get your chat ID:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;import TelegramBot from &lt;span class="s2"&gt;"node-telegram-bot-api"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
import dotenv from &lt;span class="s2"&gt;"dotenv"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

dotenv.config&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

const TELEGRAM_BOT_TOKEN &lt;span class="o"&gt;=&lt;/span&gt; process.env.TELEGRAM_BOT_TOKEN!&lt;span class="p"&gt;;&lt;/span&gt;

const bot &lt;span class="o"&gt;=&lt;/span&gt; new TelegramBot&lt;span class="o"&gt;(&lt;/span&gt;TELEGRAM_BOT_TOKEN, &lt;span class="o"&gt;{&lt;/span&gt; polling: &lt;span class="nb"&gt;true&lt;/span&gt; &lt;span class="o"&gt;})&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

bot.on&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"message"&lt;/span&gt;, &lt;span class="o"&gt;(&lt;/span&gt;msg&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  console.log&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"New chat ID:"&lt;/span&gt;, msg.chat.id&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  TELEGRAM_CHAT_ID &lt;span class="o"&gt;=&lt;/span&gt; msg.chat.id.toString&lt;span class="o"&gt;()&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Environment Configuration
&lt;/h4&gt;

&lt;p&gt;Add these to your .env file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;TELEGRAM_BOT_NAME &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"super_wallet_tracking_bot"&lt;/span&gt;
TELEGRAM_BOT_TOKEN &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"YOUR_BOT_TOKEN"&lt;/span&gt;
TELEGRAM_CHAT_ID &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"YOUR_CHAT_ID"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once we set environment variables, create a &lt;code&gt;telegram.ts&lt;/code&gt; file and write the following code to send messsages to Telegram:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;import TelegramBot from &lt;span class="s2"&gt;"node-telegram-bot-api"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
import dotenv from &lt;span class="s2"&gt;"dotenv"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

dotenv.config&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

const TELEGRAM_CHAT_ID &lt;span class="o"&gt;=&lt;/span&gt; process.env.TELEGRAM_CHAT_ID!&lt;span class="p"&gt;;&lt;/span&gt;

const bot &lt;span class="o"&gt;=&lt;/span&gt; new TelegramBot&lt;span class="o"&gt;(&lt;/span&gt;TELEGRAM_BOT_TOKEN, &lt;span class="o"&gt;{&lt;/span&gt; polling: &lt;span class="nb"&gt;false&lt;/span&gt; &lt;span class="o"&gt;})&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nb"&gt;export &lt;/span&gt;const sendTelegramMessage &lt;span class="o"&gt;=&lt;/span&gt; async &lt;span class="o"&gt;(&lt;/span&gt;message: string&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  try &lt;span class="o"&gt;{&lt;/span&gt;
    await bot.sendMessage&lt;span class="o"&gt;(&lt;/span&gt;TELEGRAM_CHAT_ID, message, &lt;span class="o"&gt;{&lt;/span&gt;
      parse_mode: &lt;span class="s2"&gt;"HTML"&lt;/span&gt;,
      disable_web_page_preview: &lt;span class="nb"&gt;true&lt;/span&gt;,
    &lt;span class="o"&gt;})&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt; catch &lt;span class="o"&gt;(&lt;/span&gt;error&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    console.error&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Failed to send Telegram message:"&lt;/span&gt;, error&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2.Integrating Helius RPC
&lt;/h3&gt;

&lt;p&gt;Helius provides reliable RPC endpoints for Solana transaction monitoring.&lt;/p&gt;

&lt;p&gt;Setup Steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Get your Helius API key from &lt;a href="https://dashboard.helius.dev/" rel="noopener noreferrer"&gt;Helius Dashboard&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Configure RPC endpoints in .env:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;RPC_URL &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"https://mainnet.helius-rpc.com/?api-key=YOUR_API_KEY"&lt;/span&gt;
WSS_URL &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"wss://mainnet.helius-rpc.com/?api-key=YOUR_API_KEY"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Database Configuration and connection to MongoDB
&lt;/h3&gt;

&lt;p&gt;We use  MongoDB for storing transaction history and analysis.&lt;/p&gt;

&lt;p&gt;Configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;MONGODB_URI &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"mongodb://localhost:27017/solana_wallet_tracking"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create &lt;code&gt;db.ts&lt;/code&gt; file, and write the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;import mongoose from &lt;span class="s2"&gt;"mongoose"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nb"&gt;export &lt;/span&gt;const connectDB &lt;span class="o"&gt;=&lt;/span&gt; async &lt;span class="o"&gt;(&lt;/span&gt;mongodb_url: string&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  await mongoose.connect&lt;span class="o"&gt;(&lt;/span&gt;mongodb_url&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  console.log&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"📦 MongoDB Connected"&lt;/span&gt;&lt;span class="o"&gt;)&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Wallet Monitoring
&lt;/h3&gt;

&lt;p&gt;Configure the wallet address you want to monitor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;WALLET_ADDRESS &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"YOUR_WALLET_ADDRESS"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. Solana Connection Setup with Helius RPC
&lt;/h3&gt;

&lt;p&gt;We need to establish communication with the Solana blockchain through Helius RPC endpoints.&lt;/p&gt;

&lt;p&gt;Create &lt;code&gt;connection.ts&lt;/code&gt; file, and write the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;import &lt;span class="o"&gt;{&lt;/span&gt; Connection &lt;span class="o"&gt;}&lt;/span&gt; from &lt;span class="s2"&gt;"@solana/web3.js"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
import dotenv from &lt;span class="s2"&gt;"dotenv"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

dotenv.config&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

const RPC_URL &lt;span class="o"&gt;=&lt;/span&gt; process.env.RPC_URL!&lt;span class="p"&gt;;&lt;/span&gt;
const WSS_URL &lt;span class="o"&gt;=&lt;/span&gt; process.env.WSS_URL!&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(!&lt;/span&gt;RPC_URL &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;WSS_URL&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  throw new Error&lt;span class="o"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;"RPC_URL and WSS_URL must be defined in environment variables"&lt;/span&gt;
  &lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="nb"&gt;export &lt;/span&gt;const connection &lt;span class="o"&gt;=&lt;/span&gt; new Connection&lt;span class="o"&gt;(&lt;/span&gt;RPC_URL, &lt;span class="o"&gt;{&lt;/span&gt; wsEndpoint: WSS_URL &lt;span class="o"&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 creates a Connection instance that provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HTTP-based RPC calls for transaction queries&lt;/li&gt;
&lt;li&gt;WebSocket connection for real-time transaction monitoring&lt;/li&gt;
&lt;li&gt;Automatic reconnection handling&lt;/li&gt;
&lt;li&gt;Connection state management&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  6. Transaction Analysis
&lt;/h3&gt;

&lt;p&gt;The system monitors:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Transaction signatures&lt;/li&gt;
&lt;li&gt;Token transfers&lt;/li&gt;
&lt;li&gt;Buy/Sell operations&lt;/li&gt;
&lt;li&gt;Amount changes&lt;/li&gt;
&lt;li&gt;Timestamps&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We need to get transaction data from Helius RPC and processes this data and analyze signature in detail :&lt;/p&gt;

&lt;p&gt;Create &lt;code&gt;trading.ts&lt;/code&gt; file, and write the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;import &lt;span class="o"&gt;{&lt;/span&gt; NATIVE_MINT &lt;span class="o"&gt;}&lt;/span&gt; from &lt;span class="s2"&gt;"@solana/spl-token"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
import &lt;span class="o"&gt;{&lt;/span&gt; LAMPORTS_PER_SOL, PublicKey &lt;span class="o"&gt;}&lt;/span&gt; from &lt;span class="s2"&gt;"@solana/web3.js"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

import &lt;span class="o"&gt;{&lt;/span&gt; sendTelegramMessage &lt;span class="o"&gt;}&lt;/span&gt; from &lt;span class="s2"&gt;"./telegram.js"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
import &lt;span class="o"&gt;{&lt;/span&gt; Trading &lt;span class="o"&gt;}&lt;/span&gt; from &lt;span class="s2"&gt;"./models/Trading.js"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
import &lt;span class="o"&gt;{&lt;/span&gt; formatCryptoAddress &lt;span class="o"&gt;}&lt;/span&gt; from &lt;span class="s2"&gt;"./lib/format.js"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

import &lt;span class="o"&gt;{&lt;/span&gt; connection &lt;span class="o"&gt;}&lt;/span&gt; from &lt;span class="s2"&gt;"./config.js"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

const explorerUrl &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"https://solscan.io/tx/"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
const walletUrl &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sb"&gt;`&lt;/span&gt;https://solscan.io/account/&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nb"&gt;export &lt;/span&gt;const subscribeTrading &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;key: string&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    const anaylzeSignature &lt;span class="o"&gt;=&lt;/span&gt; async &lt;span class="o"&gt;(&lt;/span&gt;log: any&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      txn &lt;span class="o"&gt;=&lt;/span&gt; await connection.getParsedTransaction&lt;span class="o"&gt;(&lt;/span&gt;signature, &lt;span class="o"&gt;{&lt;/span&gt;
             maxSupportedTransactionVersion: 0,
            commitment: &lt;span class="s2"&gt;"confirmed"&lt;/span&gt;,
          &lt;span class="o"&gt;})&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(!&lt;/span&gt;txn&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        console.log&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;Failed to fetch transaction after &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;attempt&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; attempts&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt;

      // process transaction to get relevant information

      console.log&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"preTokenBalances"&lt;/span&gt;, preTokenBalances&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      console.log&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"postTokenBalances"&lt;/span&gt;, postTokenBalances&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      console.log&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"loaced addresses"&lt;/span&gt;, innerInstructions&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      const message &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sb"&gt;`&lt;/span&gt;
        🔔 &amp;lt;b&amp;gt;New Transaction Detected!&amp;lt;/b&amp;gt;

        👛 &amp;lt;b&amp;gt;Wallet:&amp;lt;/b&amp;gt; &amp;lt;a &lt;span class="nv"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;walletUrl&lt;/span&gt;&lt;span class="p"&gt; + signer&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;formatCryptoAddress&lt;/span&gt;&lt;span class="p"&gt;(signer)&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&amp;lt;/a&amp;gt;

        💰 &amp;lt;b&amp;gt;Sol Amount:&amp;lt;/b&amp;gt; &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;solAmount&lt;/span&gt;&lt;span class="p"&gt; &amp;gt; 0 ? &lt;/span&gt;&lt;span class="s2"&gt;"📥 SELL"&lt;/span&gt;&lt;span class="p"&gt; &lt;/span&gt;:&lt;span class="p"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"📤 BUY"&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.abs(solAmount).(3)&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; SOL

        💸 &amp;lt;b&amp;gt;PNL &lt;span class="k"&gt;for &lt;/span&gt;this Token:&amp;lt;/b&amp;gt; &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;totalPNL&lt;/span&gt;&lt;span class="p"&gt;.toFixed(3)&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; SOL

        🚀 &amp;lt;b&amp;gt;Token:&amp;lt;/b&amp;gt; &amp;lt;a &lt;span class="nv"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;walletUrl&lt;/span&gt;&lt;span class="p"&gt; + tokenAddress&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;tokenInfo&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&amp;lt;/a&amp;gt;

        🔗 &amp;lt;a &lt;span class="nv"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;explorerUrl&lt;/span&gt;&lt;span class="p"&gt; + signature&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;View Transaction&amp;lt;/a&amp;gt;

        ⏰ &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;new&lt;/span&gt;&lt;span class="p"&gt; Date().toLocaleString()&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;
        &lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      await sendTelegramMessage&lt;span class="o"&gt;(&lt;/span&gt;message&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
    &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;connection.onLogs&lt;span class="o"&gt;(&lt;/span&gt;new PublicKey&lt;span class="o"&gt;(&lt;/span&gt;key&lt;span class="o"&gt;)&lt;/span&gt;, anaylzeSignature, &lt;span class="s2"&gt;"processed"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This Solana wallet tracking bot provides a robust solution for monitoring wallet activities with real-time Telegram notifications. By following this guide and implementing the provided configurations, you can create a powerful tool for tracking Solana transactions and maintaining awareness of your wallet activities.&lt;/p&gt;

&lt;p&gt;The system's modular architecture allows for easy maintenance and future enhancements while providing reliable transaction monitoring and notification delivery.&lt;/p&gt;

&lt;p&gt;Remember to regularly monitor your API usage and maintain your database to ensure optimal performance of your tracking system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Contact Information
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Gmail: &lt;a href="mailto:marksantiago0929@gmail.com"&gt;marksantiago0929@gmail.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/BTC415" rel="noopener noreferrer"&gt;MARK&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;LinkedIn: &lt;a href="https://www.linkedin.com/in/mark-santiago-373172339/" rel="noopener noreferrer"&gt;Mark Santiago&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Telegram: &lt;a href="https://t.me/marksantiago02" rel="noopener noreferrer"&gt;@marksantiago02&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Twitter: &lt;a href="https://twitter.com/MarkSantiago02" rel="noopener noreferrer"&gt;@MarkSantiago02&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>bot</category>
      <category>solana</category>
      <category>helius</category>
    </item>
    <item>
      <title>How to write dynamic staking smart contract step by step in practice</title>
      <dc:creator>Mark Santiago</dc:creator>
      <pubDate>Sat, 14 Dec 2024 13:53:53 +0000</pubDate>
      <link>https://dev.to/marksantiago290/how-to-write-dynamic-staking-smart-contract-step-by-step-in-practice-2bg4</link>
      <guid>https://dev.to/marksantiago290/how-to-write-dynamic-staking-smart-contract-step-by-step-in-practice-2bg4</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In the ever-expanding landscape of decentralized finance (DeFi), &lt;strong&gt;staking&lt;/strong&gt; has emerged as a popular mechanism for users to earn rewards by participating in network security and governance. Unlike traditional financial systems, staking allows cryptocurrency holders to lock up their assets to support blockchain operations, all while earning passive income. However, the conventional staking model often comes with restrictions, such as lock-in periods and fixed reward structures that can limit user flexibility and engagement.&lt;/p&gt;

&lt;p&gt;This article provides a detailed, hands-on guide to implementing dynamic staking smart contracts on Ethereum. We'll walk through building a production-ready staking system that enables real-time reward calculations and flexible withdrawals. &lt;br&gt;
This article is the implementation of the &lt;a href="https://dev.to/marksantiago02/basic-understanding-of-dynamic-staking-2e9l"&gt;Basic understanding of Dynamic Staking&lt;/a&gt;.&lt;br&gt;
By following this step-by-step tutorial, you'll learn how to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create an upgradeable staking contract with role-based access control&lt;/li&gt;
&lt;li&gt;Implement share-based reward calculations for precise token distribution&lt;/li&gt;
&lt;li&gt;Build flexible deposit and withdrawal mechanisms without lock-in periods&lt;/li&gt;
&lt;li&gt;Add essential security features and administrative controls&lt;/li&gt;
&lt;li&gt;Handle real-time reward tracking and distribution&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Whether you're building a DeFi protocol or enhancing an existing platform, this practical guide will equip you with the technical knowledge to implement a robust dynamic staking system. The code examples and implementation patterns shown here are battle-tested and ready for production use, helping you create staking mechanisms that truly serve the needs of modern DeFi users.&lt;/p&gt;

&lt;p&gt;Let's dive into the technical implementation and understand how each component works together to create a flexible and secure dynamic staking system.&lt;/p&gt;
&lt;h4&gt;
  
  
  Implementation Details
&lt;/h4&gt;

&lt;p&gt;Let's break down the key components of the dynamic staking contract:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Contract Structure and Inheritance&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;contract Staking is
    Initializable,
    UUPSUpgradeable,
    AccessControlUpgradeable,
    PausableUpgradeable
{
    using EnumerableSet for EnumerableSet.AddressSet;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The contract inherits from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Initializable: For upgradeable contract initialization&lt;/li&gt;
&lt;li&gt;UUPSUpgradeable: For upgrade functionality&lt;/li&gt;
&lt;li&gt;AccessControlUpgradeable: For role-based access control&lt;/li&gt;
&lt;li&gt;PausableUpgradeable: For emergency pause functionality&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. State Variables and Data Structures&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;struct Stake {
    uint256 stakedMRKST;
    uint256 shares;
}

IERC20 private MRKST;
EnumerableSet.AddressSet private stakeholders;
uint256 private totalStakes;
uint256 private totalShares;
mapping(address =&amp;gt; Stake) private stakeholderToStake;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Key Functions&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Initialization&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function initialize(
    address admin1,
    address admin2,
    address _MRKST
) public initializer {
    AccessControlUpgradeable.__AccessControl_init();
    PausableUpgradeable.__Pausable_init();
    ADMIN_ROLE = keccak256("ADMIN_ROLE");
    _setupRole(ADMIN_ROLE, admin1);
    _setupRole(ADMIN_ROLE, admin2);
    MRKST = IERC20(_MRKST);
    base = 10**18;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function initializes the contracts. It&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sets up the initial contract state&lt;/li&gt;
&lt;li&gt;Assigns two administrators for enhanced security&lt;/li&gt;
&lt;li&gt;Links the staking token contract&lt;/li&gt;
&lt;li&gt;Establishes the base unit (10^18) for precise calculations&lt;/li&gt;
&lt;li&gt;Initializes access control and pause functionality&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Staking Implementation&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function createStake(uint256 stakeAmount) public whenNotPaused isInitialRatioSet {
    uint256 shares = (stakeAmount * totalShares) / MRKST.balanceOf(address(this));

    require(MRKST.transferFrom(msg.sender, address(this), stakeAmount), "MRKST transfer failed");

    stakeholders.add(msg.sender);
    stakeholderToStake[msg.sender].stakedMRKST += stakeAmount;
    stakeholderToStake[msg.sender].shares += shares;
    totalStakes += stakeAmount;
    totalShares += shares;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Accepts user deposits&lt;/li&gt;
&lt;li&gt;Calculates shares based on current token/share ratio&lt;/li&gt;
&lt;li&gt;Transfers tokens from user to contract&lt;/li&gt;
&lt;li&gt;Records stake details in storage&lt;/li&gt;
&lt;li&gt;Updates global totals&lt;/li&gt;
&lt;li&gt;Adds user to stakeholder list&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Withdrawal Implementation&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function removeStake(uint256 stakeAmount) public whenNotPaused {
    uint256 stakeholderStake = stakeholderToStake[msg.sender].stakedMRKST;
    uint256 stakeholderShares = stakeholderToStake[msg.sender].shares;

    require(stakeholderStake &amp;gt;= stakeAmount, "Not enough staked!");

    uint256 sharesToWithdraw = (stakeAmount * stakeholderShares) / stakeholderStake;
    uint256 rewards = calculateRewards(stakeAmount, stakeholderStake, stakeholderShares);

    updateStakeAndShares(msg.sender, stakeAmount, sharesToWithdraw);
    transferRewards(msg.sender, stakeAmount, rewards);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Processes withdrawal requests&lt;/li&gt;
&lt;li&gt;Calculates earned rewards&lt;/li&gt;
&lt;li&gt;Determines shares to burn&lt;/li&gt;
&lt;li&gt;Updates user's stake balance&lt;/li&gt;
&lt;li&gt;Transfers principal plus rewards&lt;/li&gt;
&lt;li&gt;Removes user from stakeholder list if fully withdrawn&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Reward Calculation&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function rewardOf(address stakeholder) public view returns (uint256) {
    uint256 stakeholderStake = stakeholderToStake[stakeholder].stakedMRKST;
    uint256 stakeholderShares = stakeholderToStake[stakeholder].shares;

    if (stakeholderShares == 0) {
      return 0;
    }

    uint256 stakedRatio = (stakeholderStake * base) / stakeholderShares;
    uint256 currentRatio = (MRKST.balanceOf(address(this)) * base) /
      totalShares;

    if (currentRatio &amp;lt;= stakedRatio) {
      return 0;
    }

    uint256 rewards = (stakeholderShares * (currentRatio - stakedRatio)) / base;

    return rewards;
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Calculates total pending rewards for a stakeholder&lt;/li&gt;
&lt;li&gt;Uses ratio comparison between initial stake and current value&lt;/li&gt;
&lt;li&gt;Accounts for all accumulated rewards&lt;/li&gt;
&lt;li&gt;Returns total claimable reward amount&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Reward Distribution&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function rewardForStake(address stakeholder, uint256 stakeAmount)
    public
    view
    returns (uint256)
  {
    uint256 stakeholderStake = stakeholderToStake[stakeholder].stakedMRKST;
    uint256 stakeholderShares = stakeholderToStake[stakeholder].shares;

    require(stakeholderStake &amp;gt;= stakeAmount, "Not enough staked!");

    uint256 stakedRatio = (stakeholderStake * base) / stakeholderShares;
    uint256 currentRatio = (MRKST.balanceOf(address(this)) * base) /
      totalShares;
    uint256 sharesToWithdraw = (stakeAmount * stakeholderShares) /
      stakeholderStake;

    if (currentRatio &amp;lt;= stakedRatio) {
      return 0;
    }

    uint256 rewards = (sharesToWithdraw * (currentRatio - stakedRatio)) / base;

    return rewards;
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Calculates rewards for partial withdrawal&lt;/li&gt;
&lt;li&gt;Determines proportional share of rewards&lt;/li&gt;
&lt;li&gt;Validates withdrawal amount&lt;/li&gt;
&lt;li&gt;Returns specific reward amount for requested withdrawal&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Refund Locking Implementation&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  function refundLockedStake(uint256 from, uint256 to) public hasAdminRole {
    require(to &amp;lt;= stakeholders.length(), "Invalid `to` param");
    uint256 s;

    for (s = from; s &amp;lt; to; s += 1) {
      totalStakes -= stakeholderToStake[stakeholders.at(s)].stakedMRKST;

      require(
        MRKST.transfer(
          stakeholders.at(s),
          stakeholderToStake[stakeholders.at(s)].stakedMRKST
        ),
        "MRKST transfer failed"
      );

      stakeholderToStake[stakeholders.at(s)].stakedMRKST = 0;
    }
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Emergency withdrawal mechanism&lt;/li&gt;
&lt;li&gt;Processes refunds in batches&lt;/li&gt;
&lt;li&gt;Returns original stake amounts&lt;/li&gt;
&lt;li&gt;Clears stake records&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This dynamic staking implementation provides a flexible and secure way to manage token staking with real-time reward calculations. The share-based system ensures fair distribution of rewards while maintaining precision in calculations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Future Possibilities
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Multiple token support&lt;/li&gt;
&lt;li&gt;Tiered reward systems&lt;/li&gt;
&lt;li&gt;Governance integration&lt;/li&gt;
&lt;li&gt;Advanced reward strategies&lt;/li&gt;
&lt;li&gt;Enhanced analytics and reporting&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This implementation serves as a robust foundation for building more sophisticated staking mechanisms in DeFi applications.&lt;/p&gt;

&lt;p&gt;For more detailed information, please refer to the &lt;a href="https://github.com/BTC415/Dynamic-Staking" rel="noopener noreferrer"&gt;source code&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thank you! Happy coding! 😍&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>smartcontract</category>
      <category>solidity</category>
      <category>ethereum</category>
    </item>
    <item>
      <title>Basic understanding of Dynamic Staking</title>
      <dc:creator>Mark Santiago</dc:creator>
      <pubDate>Sat, 07 Dec 2024 17:27:32 +0000</pubDate>
      <link>https://dev.to/marksantiago290/basic-understanding-of-dynamic-staking-2e9l</link>
      <guid>https://dev.to/marksantiago290/basic-understanding-of-dynamic-staking-2e9l</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In the ever-expanding landscape of decentralized finance (DeFi), &lt;strong&gt;staking&lt;/strong&gt; has emerged as a popular mechanism for users to earn rewards by participating in network security and governance. Unlike traditional financial systems, staking allows cryptocurrency holders to lock up their assets to support blockchain operations, all while earning passive income. However, the conventional staking model often comes with restrictions, such as lock-in periods and fixed reward structures that can limit user flexibility and engagement.&lt;/p&gt;

&lt;p&gt;This article explores the concept of staking and delves into the mechanism and example workflow of innovative &lt;strong&gt;dynamic staking&lt;/strong&gt;. I will guide you basic knowledge of dynamic staking that offers stakeholders the freedom to withdraw their assets at any time while earning rewards calculated in real-time based on their contributions. By understanding the mechanics of dynamic staking, you can create more flexible and user-friendly DeFi applications that cater to the evolving needs of the crypto community.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Staking?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Staking&lt;/strong&gt; is a process used in various blockchain networks, particularly those that operate on a proof-of-stake (PoS) consensus mechanism. In simple terms, staking allows users to lock up a certain amount of cryptocurrency in a wallet to support the operations of a blockchain network. In return for their contribution, stakeholders earn rewards, typically in the form of additional tokens.&lt;/p&gt;

&lt;p&gt;The primary purpose of staking is to enhance network security and efficiency. By staking their tokens, participants help validate transactions and maintain the integrity of the blockchain. The more tokens a user stakes, the higher their chances of being selected to validate a block and earn rewards.&lt;/p&gt;

&lt;h3&gt;
  
  
  General Staking Mechanism
&lt;/h3&gt;

&lt;p&gt;In traditional staking models, users commit their tokens for a predetermined period, often referred to as a "lock-in" period. During this time, they cannot access or withdraw their staked tokens. The rewards are usually calculated based on the amount of tokens staked and the duration of the staking period.&lt;/p&gt;

&lt;p&gt;Here’s a simplified workflow of how traditional staking works:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;User Participation:&lt;/strong&gt; A user decides to stake a certain amount of cryptocurrency.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Locking Tokens:&lt;/strong&gt; The user locks their tokens in a staking contract for a fixed period.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Earning Rewards:&lt;/strong&gt; Throughout the staking period, the user earns rewards based on their staked amount.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Withdrawal:&lt;/strong&gt; At the end of the staking period, the user can withdraw their original tokens along with any earned rewards.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While this approach provides predictable rewards, it also comes with drawbacks, such as the inability to access funds during the lock-in period and the potential for missed opportunities if market conditions change.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dynamic Staking: A New Approach
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Dynamic staking&lt;/strong&gt; introduces a more flexible and responsive model for staking that addresses some of the limitations of traditional staking. Instead of requiring users to lock their tokens for a specific period, dynamic staking allows stakeholders to withdraw their tokens at any time while still earning rewards based on their contributions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Features of Dynamic Staking&lt;/strong&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No Lock-in Period:&lt;/strong&gt; Stakeholders can remove their staked tokens whenever they want, providing liquidity and flexibility.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dynamic APY Calculation:&lt;/strong&gt; The Annual Percentage Yield (APY) is calculated based on real-time data, including the number of stakeholders, their staked amounts, and the total rewards accumulated in the staking contract.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Share-Based Rewards:&lt;/strong&gt; Instead of a fixed reward per staked token, rewards are distributed based on the number of shares each stakeholder holds, which reflects their proportional contribution to the staking pool.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example workflow of Dynamic Staking&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before diving into the code, let's understand the key concepts of the dynamic staking mechanism:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MRK&lt;/strong&gt; is the token used in the staking system. It represents the currency that stakeholders can stake to earn rewards.&lt;br&gt;
&lt;strong&gt;Shares&lt;/strong&gt; represent each stakeholder's claim to the total pool of STK in the staking contract. Shares are proportional to the amount of STK staked.&lt;br&gt;
&lt;strong&gt;Rewards&lt;/strong&gt; are additional STK tokens deposited into the staking contract, typically as a form of incentive for stakeholders to participate. &lt;br&gt;
&lt;strong&gt;Alice&lt;/strong&gt;, &lt;strong&gt;Bob&lt;/strong&gt;, &lt;strong&gt;Charlie&lt;/strong&gt;, and &lt;strong&gt;Dave&lt;/strong&gt; are  stakeholders who participate in the dynamic staking system in this example scenario.&lt;br&gt;
They can stake, claim, unstake MRK tokens&lt;br&gt;
The &lt;strong&gt;MRK/share ratio&lt;/strong&gt; is a proportional ratio that represents the amount of MRK available in the contract per share owned by the stakeholders.  This ratio determines how much MRK a stakeholder receives when they withdraw their shares. It changes as stakeholders deposit more MRK or as rewards are added to the contract, affecting each stakeholder's payout.&lt;/p&gt;

&lt;p&gt;Now, let's walk through a simplified example of how dynamic staking works:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Initial State:&lt;/strong&gt; The MRK/share ratio begins at 1:1.&lt;br&gt;
Alice, Bob and Charlie stakes 500, 1000, 500 MRK tokens. In return, they receive 500, 1000, 500 shares respectively.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Action 1:&lt;/strong&gt; 100 MRK Token is deposited into the staking contract as rewards.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Updated State:&lt;/strong&gt; The MRK/share ratio increases to 1.05, calculated as follows:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    Total MRK = 500 (Alice) + 1000 (Bob) + 500 (Charlie) + 100 (reward) = 2100 MRK
    MRK/Share Ratio = 2100 MRK / 2000 shares = 1.05
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Action 2:&lt;/strong&gt; Alice and Bob claims rewards, so they will receive 25, 50 MRK tokens respectively.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    Alice's Claim Amount = (500 MRK * 0.05) = 25 MRK
    Alice's remaining shares = 500 - 25 / 1.05 = 476.19 shares
    Bob's Claim Amount = (1000 MRK * 0.05) = 50 MRK
    Bob's remaining shares = 1000 - 50 / 1.05 = 952.38 shares
    Charlie's remaining shares = 500 shares

    Remaining Total MRK tokens  = 2100 - (25 + 50) = 2025 MRK
    Remaining Shares = 476.19 + 952.38 + 500 = 1928.57 shares
    MRK/Share Ratio = 2025 MRK / 1928.57 shares = 1.05
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, MRK/Share Ratio remains constant at 1.05 because no new rewards are added to the contract.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Action 3:&lt;/strong&gt; Dave stakes 500 MRK tokens and his shares will be 500 / 1.05 = 476.19 shares.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So remaining total MRK tokens  = 2025 + 500 = 2525 MRK, and remaining shares = 1928.57 + 476.19 = 2404.76 shares&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Action 4:&lt;/strong&gt; Charlie claims 250 MRK tokens. He receives 12.5 MRKs.
Charlie's remaining shares = 500 - 12.5 / 1.05 = 488.10 shares
Remaining MRK tokens = 2525 - 12.5 = 2512.5 MRK, remaining shares = 2404.76 - 12.5 / 1.05 = 2392.86 shares&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Still MRK/Share Ratio remains constant at 1.05 because no new rewards are added to the contract.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Action 5:&lt;/strong&gt; Dave stakes another 500 MRK tokens, so his shares will be 476.19 + 500 / 1.05 = 952.38 shares and total MRK tokens are 2512.5 + 500 = 3012.5 MRK, and total shares are 2392.86 + 500 / 1.05 = 2869.05 shares&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Action 6:&lt;/strong&gt; Another reward of 100 MRK is deposited into the staking contract.&lt;br&gt;
Then the MRK/share ratio is updated to 1.08485, calculated as follows:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; MRK/Share Ratio = (3012.5 + 100) MRK / 2869.05 shares = 1.08485
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And they now have 476.19, 952.38, 488.10, 952.38 shares respectively.&lt;br&gt;
So they will receive approx. 516, 1038, 528, 1038 MRK tokens respectively when they withdraw their whole staked MRK tokens and their rewards will be 16.5, 33, 17.5, 33 MRK tokens respectively.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Dynamic staking represents a significant evolution in the staking landscape, providing users with the flexibility to manage their investments while still benefiting from rewards. By calculating rewards based on real-time data and allowing for immediate withdrawals, this model enhances user experience and engagement.&lt;/p&gt;

&lt;p&gt;Thanks.&lt;br&gt;
Happy coding.&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>smartcontract</category>
      <category>ethereum</category>
      <category>solidity</category>
    </item>
    <item>
      <title>How to Write a Token Price Oracle Smart Contract</title>
      <dc:creator>Mark Santiago</dc:creator>
      <pubDate>Sun, 01 Dec 2024 07:14:12 +0000</pubDate>
      <link>https://dev.to/marksantiago290/how-to-write-a-token-price-oracle-smart-contract-1oj</link>
      <guid>https://dev.to/marksantiago290/how-to-write-a-token-price-oracle-smart-contract-1oj</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In the rapidly evolving DeFi ecosystem, accurate and reliable token price data is fundamental for various applications like lending protocols, automated trading systems, and yield farming strategies. Token price oracles serve as the critical infrastructure that enables these protocols to access real-time price information directly from the blockchain.&lt;/p&gt;

&lt;p&gt;This article shows you how to build a robust token price oracle smart contract that leverages Uniswap V2's liquidity pools to derive token prices. By understanding and implementing this oracle system, developers can create DeFi applications that make informed decisions based on current market conditions.&lt;/p&gt;

&lt;h4&gt;
  
  
  Key benefits of building a token price oracle:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Real-time price discovery from decentralized exchanges&lt;/li&gt;
&lt;li&gt;On-chain price verification&lt;/li&gt;
&lt;li&gt;Integration capability with any DeFi protocol&lt;/li&gt;
&lt;li&gt;Support for multiple tokens through batch queries&lt;/li&gt;
&lt;li&gt;Cost-effective price fetching through view functions&lt;/li&gt;
&lt;li&gt;Throughout this guide, we'll explore a practical implementation that showcases:&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  How to interact with Uniswap V2 contracts
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Methods for accurate price calculations&lt;/li&gt;
&lt;li&gt;Handling different token decimals&lt;/li&gt;
&lt;li&gt;Batch processing for multiple tokens&lt;/li&gt;
&lt;li&gt;Event emission for price tracking&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Okay, now let's dive into the technical implementation and understand how each component works together to create a reliable price oracle system.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Implement Price Oracle Smart Contract Step by Step
&lt;/h2&gt;

&lt;p&gt;We are going to use Uniswap V2's liquidity pools to fetch token prices. &lt;/p&gt;

&lt;p&gt;This approach offers several advantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Decentralization&lt;/strong&gt;: Uniswap V2 is a decentralized exchange, ensuring that price data is not controlled by a single entity.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Liquidity&lt;/strong&gt;: Uniswap V2 pools provide liquidity for various tokens, allowing for a wide range of price data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexibility&lt;/strong&gt;: Uniswap V2 supports multiple tokens, enabling the oracle to fetch prices for multiple tokens simultaneously.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We need to import required interfaces like &lt;code&gt;IUniswapV2Pair&lt;/code&gt;, &lt;code&gt;IUniswapV2Factory&lt;/code&gt;, and &lt;code&gt;IERC20&lt;/code&gt;.&lt;br&gt;
And define the contract's state variables, events.&lt;/p&gt;
&lt;h3&gt;
  
  
  Key functions
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Getting Pair Address&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function getPairAddress(address tokenA, address tokenB) public view returns (address) {
    return IUniswapV2Factory(UNISWAP_V2_FACTORY_ADDRESS).getPair(tokenA, tokenB);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function retrieves the liquidity pair address for any token pair from Uniswap V2.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Token Price Calculation&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    function getTokenPrice(address token) public returns (uint256 tokenPrice, uint256 ethPrice, string memory symbol) {
        address pairAddress = getPairAddress(token, WETH);
        require(pairAddress != address(0), "Pair not found");

        IUniswapV2Pair pairContract = IUniswapV2Pair(pairAddress);

        (uint112 reserve0, uint112 reserve1, ) = pairContract.getReserves();
        address token0 = pairContract.token0();

        uint8 tokenDecimals = IERC20(token).decimals();
        symbol = IERC20(token).symbol();

        if (token0 == WETH) {
            ethPrice = (reserve0 * (10 ** tokenDecimals)) / reserve1;
            tokenPrice = (reserve1 * (10 ** 18)) / reserve0;
        } else {
            ethPrice = (reserve1 * (10 ** tokenDecimals)) / reserve0;
            tokenPrice = (reserve0 * (10 ** 18)) / reserve1;
        }

        emit PriceUpdated(token, tokenPrice, ethPrice, symbol);
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First we get the pair address for the token pair. &lt;br&gt;
And if the pair is not found, it throws an error.&lt;/p&gt;

&lt;p&gt;The price calculation logic handles two scenarios:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If WETH is token0:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (token0 == WETH) {
    ethPrice = (reserve0 * (10 ** tokenDecimals)) / reserve1;
    tokenPrice = (reserve1 * (10 ** 18)) / reserve0;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;If WETH is token1:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;else {
    ethPrice = (reserve1 * (10 ** tokenDecimals)) / reserve0;
    tokenPrice = (reserve0 * (10 ** 18)) / reserve1;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;3. Batch Price Fetching&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function getMultipleTokenPrices(address[] calldata tokens) external returns (
    uint256[] memory tokenPrices,
    uint256[] memory ethPrices,
    string[] memory symbols
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function efficiently fetches prices for multiple tokens in a single transaction.&lt;/p&gt;

&lt;h2&gt;
  
  
  Usage Example
&lt;/h2&gt;

&lt;p&gt;We can use this price oracle contract in other smart contract and also frontend for getting real time token price.&lt;/p&gt;

&lt;h3&gt;
  
  
  Usage in other solidity Smart contract
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// SPDX-License-Identifier: MIT
pragma solidity ^0.8.27;

import "./UniswapV2PriceOracle.sol";

contract PriceConsumer {
    UniswapV2PriceOracle public oracle;

    constructor(address _oracle) {
        oracle = UniswapV2PriceOracle(_oracle);
    }

    function getTokenPriceInETH(address token, uint256 amount) external view returns (uint256) {
        return oracle.getTokenValueInETH(token, amount);
    }

    function checkPriceImpact(address token, uint256 amount) external view returns (uint256) {
        return oracle.getPriceImpact(token, amount);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Frontend Implementation with ethers.js
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { ethers } from 'ethers';
import { useState, useEffect } from 'react';

const PriceTracker = () =&amp;gt; {
    const [price, setPrice] = useState&amp;lt;string&amp;gt;('0');
    const [priceImpact, setPriceImpact] = useState&amp;lt;string&amp;gt;('0');

    const ORACLE_ADDRESS = "YOUR_ORACLE_ADDRESS";
    const TOKEN_ADDRESS = "YOUR_TOKEN_ADDRESS";

    useEffect(() =&amp;gt; {
        const provider = new ethers.providers.Web3Provider(window.ethereum);
        const oracle = new ethers.Contract(ORACLE_ADDRESS, oracleABI, provider);

        const fetchPrices = async () =&amp;gt; {
            const amount = ethers.utils.parseEther("1");

            // Get token price
            const tokenPrice = await oracle.getTokenValueInETH(
                TOKEN_ADDRESS, 
                amount
            );
            setPrice(ethers.utils.formatEther(tokenPrice));

            // Get price impact
            const impact = await oracle.getPriceImpact(
                TOKEN_ADDRESS,
                amount
            );
            setPriceImpact(ethers.utils.formatUnits(impact, 2));
        };

        fetchPrices();

        // Listen for price updates
oracle.on("PriceUpdated", (token, ethPrice, tokenPrice, symbol) =&amp;gt; {
    if(token === TOKEN_ADDRESS) {
        setPrice(ethers.utils.formatEther(ethPrice));
        setTokenPrice(ethers.utils.formatEther(tokenPrice));
        setSymbol(symbol);
    } else {
        // Track other token updates
        setOtherTokenPrices(prev =&amp;gt; ({
            ...prev,
            [token]: {
                ethPrice: ethers.utils.formatEther(ethPrice),
                tokenPrice: ethers.utils.formatEther(tokenPrice),
                symbol
            }
        }));

        // Optionally notify about other token updates
        console.log(`Price updated for ${symbol}: ${ethers.utils.formatEther(ethPrice)} ETH`);
    }
});

        return () =&amp;gt; {
            oracle.removeAllListeners();
        };
    }, []);

    return (
        &amp;lt;div&amp;gt;
            &amp;lt;h2&amp;gt;Token Price: {price} ETH&amp;lt;/h2&amp;gt;
            &amp;lt;h3&amp;gt;Price Impact: {priceImpact}%&amp;lt;/h3&amp;gt;
        &amp;lt;/div&amp;gt;
    );
};

export default PriceTracker;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This implementation provides a reliable way to fetch token prices directly from Uniswap V2 liquidity pools, making it suitable for various DeFi applications requiring on-chain price data&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The implementation of a token price oracle smart contract demonstrates the power and flexibility of on-chain price discovery through Uniswap V2 liquidity pools.&lt;/p&gt;

&lt;h3&gt;
  
  
  Future Possibilities
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Integration with additional DEX protocols&lt;/li&gt;
&lt;li&gt;Implementation of time-weighted average prices (TWAP)&lt;/li&gt;
&lt;li&gt;Price feed aggregation from multiple sources&lt;/li&gt;
&lt;li&gt;Enhanced security features and price manipulation protection&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This oracle implementation serves as a robust starting point for developers building DeFi applications that require reliable, on-chain price data. By understanding and implementing these concepts, developers can create more sophisticated and reliable DeFi protocols.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>smartcontract</category>
      <category>oracle</category>
      <category>solidity</category>
    </item>
    <item>
      <title>How to write smart contract for NFT marketplace</title>
      <dc:creator>Mark Santiago</dc:creator>
      <pubDate>Sat, 23 Nov 2024 18:27:01 +0000</pubDate>
      <link>https://dev.to/marksantiago290/how-to-write-smart-contract-for-nft-marketplace-5mg</link>
      <guid>https://dev.to/marksantiago290/how-to-write-smart-contract-for-nft-marketplace-5mg</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;This technical guide will give you a comprehensive guide to building a complete NFT marketplace ecosystem using Solidity and Openzeppelin. &lt;br&gt;
Our marketplace features a native token, NFT creation with customizable royalties, and secure trading mechanisms.&lt;/p&gt;
&lt;h3&gt;
  
  
  Technical Stack
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Solidity ^0.8.27&lt;/li&gt;
&lt;li&gt;OpenZeppelin Contracts&lt;/li&gt;
&lt;li&gt;Hardhat Development Environment&lt;/li&gt;
&lt;li&gt;TypeScript&lt;/li&gt;
&lt;li&gt;Ethers.js&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Contract Structure
&lt;/h3&gt;

&lt;p&gt;The project is structured into three main contracts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Platform Token (NYWToken.sol)&lt;/li&gt;
&lt;li&gt;NFT Contract (NYWNFT.sol)&lt;/li&gt;
&lt;li&gt;Marketplace Contract (NYWMarketplace.sol)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;1. Platform Token Implementation (NYWToken.sol)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The foundation of our marketplace starts with implementing the platform's native token.&lt;/p&gt;

&lt;p&gt;This NYWToken contract is a simple ERC20 token implementation. &lt;br&gt;
It inherits from the OpenZeppelin ERC20 contract and initializes the token with a supply of 1 billion tokens.&lt;/p&gt;

&lt;p&gt;Key Features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Token Supply: 1 billion tokens&lt;/li&gt;
&lt;li&gt;Token Standard: ERC20 compliance&lt;/li&gt;
&lt;li&gt;Decimals: 18 decimal places for maximum divisibility&lt;/li&gt;
&lt;li&gt;Initial Distribution: All tokens minted to contract deployer
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//SPDX-License-Identifier: MIT
pragma solidity ^0.8.27;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract NYWToken is ERC20 {
    uint256 initialSupply = 10 ** 9;

    constructor() ERC20("NYWToken", "NYW") {
        _mint(msg.sender, initialSupply * 10 ** decimals());
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;2. NFT Contract Implementation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The NYWNFT contract handles creating and burning NYW NFT token, and royalty management.&lt;br&gt;
This contract inherits from the OpenZeppelin ERC721 contract, which provides the necessary functionality for creating and managing NFTs.&lt;/p&gt;

&lt;p&gt;Key Functions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;createNYW()&lt;/code&gt;: Creates new NFTs with customizable royalties&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;burnNYW()&lt;/code&gt;: Removes NFTs from circulation&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;getCreator()&lt;/code&gt;: Updates metadata URI&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;getRoyalty()&lt;/code&gt;: Returns royalty configuration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is a detailed implementation of the NYWNFT contract:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//SPDX-License-Identifier: MIT
pragma solidity ^0.8.27;

import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract NYWNFT is ERC721URIStorage, Ownable {
    uint256 private _tokenId;

    mapping(uint256 =&amp;gt; address) public creators;
    mapping(uint256 =&amp;gt; uint256) public royalties;

    event NYWTokenCreated(
        address indexed creator,
        uint256 tokenId,
        uint256 royalty,
        string tokenURI
    );
    event NYWTokenBurned(address indexed burner, uint256 tokenId);

    constructor() ERC721("NYW NFT", "NYW") Ownable(msg.sender) {}

    function createNYW(
        string memory tokenURI,
        uint256 royalty
    ) external returns (uint256) {
        require(
            royalty &amp;gt;= 0 &amp;amp;&amp;amp; royalty &amp;lt;= 30,
            "Royalty must be between 0 and 30"
        );
        _tokenId += 1;

        creators[_tokenId] = msg.sender;
        royalties[_tokenId] = royalty;
        _safeMint(msg.sender, _tokenId);
        _setTokenURI(_tokenId, tokenURI);
        _setApprovalForAll(msg.sender, address(this), true);

        emit NYWTokenCreated(msg.sender, _tokenId, royalty, tokenURI);

        return _tokenId;
    }

    function burnNYW(uint256 tokenId) external {
        require(
            msg.sender == ownerOf(tokenId),
            "Only the owner can burn the token"
        );

        _burn(tokenId);
        delete creators[tokenId];
        delete royalties[tokenId];

        emit NYWTokenBurned(msg.sender, tokenId);
    }

    function getCreator(uint256 tokenId) external view returns (address) {
        return creators[tokenId];
    }

    function getRoyalty(uint256 tokenId) external view returns (uint256) {
        return royalties[tokenId];
    }

    function supportsInterface(bytes4 interfaceId)
        public
        view
        virtual
        override(ERC721URIStorage)
        returns (bool)
    {
        return super.supportsInterface(interfaceId);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Marketplace Contract Implementation (NYWMarketplace.sol)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The NYWMarketplace contract manages listings, delisting and buying NFTs and withdrawing funds:&lt;/p&gt;

&lt;p&gt;Key Functions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;listNFT(uint256 tokenId_, uint256 price_)&lt;/code&gt;: Lists new NFT to  marketplace for sale&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;delistNFT(uint256 tokenId_)&lt;/code&gt;: Removes NFT from marketplace&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;buyNFT(uint256 tokenId_)&lt;/code&gt;: Purchases NFT from marketplace&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;withdraw()&lt;/code&gt;:  Withdraws funds from marketplace
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    function listNFT(uint256 tokenId_, uint256 price_) external {
        // Check if the NFT is already listed
        require(!isExisting[tokenId_], "NFT is already listed");
        // Check if the NFT is owned by the caller
        require(
            nftContract.ownerOf(tokenId_) == msg.sender,
            "You are not the owner of the NFT"
        );

        //Define new NFTMarketItem
        NFTMarketItem memory newNFTMarketItem = NFTMarketItem(
            tokenId_,
            price_,
            nywContract.getRoyalty(tokenId_),
            payable(msg.sender),
            nywContract.getCreator(tokenId_),
            true
        );

        isExisting[tokenId_] = true;
        listedNFTs.push(newNFTMarketItem);
        tokenIdToNFTMarketItemId[tokenId_] = totalListedNFTs;
        totalListedNFTs++;

        emit NYWNFTListed(
            tokenId_,
            price_,
            nywContract.getRoyalty(tokenId_),
            nywContract.getCreator(tokenId_),
            msg.sender
        );
    }

    function delistNFT(uint256 tokenId_) external {
        require(isExisting[tokenId_], "NFT is not listed");
        uint256 nftMarketItemId = tokenIdToNFTMarketItemId[tokenId_];
        require(
            listedNFTs[nftMarketItemId].seller == msg.sender,
            "Only the seller can delist the NFT"
        );

        deleteNFTfromArray(tokenId_);
        emit NYWNFTDelisted(tokenId_);
    }

    function deleteNFTfromArray(uint256 tokenId_) public {
        uint256 nftMarketItemId = tokenIdToNFTMarketItemId[tokenId_];
        uint256 lastIndex = listedNFTs.length - 1;
        listedNFTs[nftMarketItemId] = listedNFTs[lastIndex];
        tokenIdToNFTMarketItemId[
            listedNFTs[lastIndex].tokenId
        ] = nftMarketItemId;
        listedNFTs.pop();
        totalListedNFTs--;
        delete tokenIdToNFTMarketItemId[tokenId_];
        isExisting[tokenId_] = false;
    }

    function buyNFT(uint256 tokenId_) public payable {
        require(isExisting[tokenId_], "NFT is not listed");
        uint256 _nftMarketItemId = tokenIdToNFTMarketItemId[tokenId_];
        NFTMarketItem memory _nftMarketItem = listedNFTs[_nftMarketItemId];
        require(!_nftMarketItem.isSold, "NFT is already sold");
        require(msg.value == _nftMarketItem.price, "Incorrect payment amount");

        // Calculate royalty amount
        uint256 _royaltyAmount = (_nftMarketItem.price *
            _nftMarketItem.royalty) / deno;
        // Calculate platform fee
        uint256 _platformFeeAmount = (_nftMarketItem.price * platformFee) /
            deno;
        // Calculate seller amount
        uint256 _sellerAmount = _nftMarketItem.price -
            _royaltyAmount -
            _platformFeeAmount;
        // Transfer funds to the seller
        payable(_nftMarketItem.seller).transfer(_sellerAmount);
        // Transfer royalty amount to the creator
        payable(_nftMarketItem.creator).transfer(_royaltyAmount);
        // Transfer platform fee amount to the platform
        payable(owner()).transfer(_platformFeeAmount);
        //Transfer NFT to the buyer
        nftContract.safeTransferFrom(
            _nftMarketItem.seller,
            msg.sender,
            _nftMarketItem.tokenId
        );

        _nftMarketItem.isSold = true;
        deleteNFTfromArray(tokenId_);
        emit NYWNFTBought(
            _nftMarketItem.tokenId,
            msg.sender,
            _nftMarketItem.seller,
            _nftMarketItem.price
        );
    }

    function withdraw() external onlyOwner {
        uint256 balance = address(this).balance;
        require(balance &amp;gt; 0, "No funds to withdraw");
        payable(owner()).transfer(balance);
        emit NYWNFTWithdrawn(balance);
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Building a secure and efficient NFT marketplace requires careful implementation of multiple smart contracts working together. This guide covered the essential components: platform token, NFT contract, and marketplace functionality.&lt;/p&gt;

</description>
      <category>nft</category>
      <category>smartcontract</category>
      <category>marketplace</category>
      <category>erc721</category>
    </item>
    <item>
      <title>Understanding smart contracts for NFT marketplace</title>
      <dc:creator>Mark Santiago</dc:creator>
      <pubDate>Sat, 23 Nov 2024 16:51:47 +0000</pubDate>
      <link>https://dev.to/marksantiago290/understanding-smart-contracts-for-nft-marketplace-22e6</link>
      <guid>https://dev.to/marksantiago290/understanding-smart-contracts-for-nft-marketplace-22e6</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;Non-fungible tokens are making headlines in recent days. This hype started with the advent of blockchain networks that has been adopted by most industries. For quite a long time, we have discussed developing an NFT marketplace; now, it's time to focus on the legal things that surround the launch of NFT marketplaces. This article will give you a knowledge of NFT and smart contracts for developing a comprehensive NFT marketplace like Opensea. &lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://www.investopedia.com/non-fungible-tokens-nft-5115211" rel="noopener noreferrer"&gt;What is a Non-Fungible Token(NFT)?&lt;/a&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;NFTs (non-fungible tokens) are unique cryptographic tokens that exist on a blockchain and cannot be replicated.&lt;/li&gt;
&lt;li&gt;NFTs can represent digital or real-world items like artwork and real estate.&lt;/li&gt;
&lt;li&gt;"Tokenizing" these real-world tangible assets makes buying, selling, and trading them more efficient while reducing the probability of fraud.&lt;/li&gt;
&lt;li&gt;NFTs can represent individuals' identities, property rights, and more.
Collectors and investors initially sought NFTs after the public became more aware of them, but their popularity has since waned.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What is an NFT Marketplace?
&lt;/h3&gt;

&lt;p&gt;NFT marketplace is a digital platform where users can buy, sell, and trade non-fungible tokens (NFTs). It acts as intermediaries between creators and collectors, providing a space for these digital assets to be traded and exchanged.&lt;/p&gt;

&lt;h3&gt;
  
  
  Different Standards of NFT Smart Contract
&lt;/h3&gt;

&lt;p&gt;Okay, now that you've got a general understanding of NFT and marketplace, its time to navigate to the different standards of NFT smart contracts. These are called Ethereum standards that are popular globally due to their provided benefits such as secure transactions, verify authentication, and more.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. ERC 721 Standard&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;ERC-721 is known as an open standard found on Ethereum Blockchain and makes the NFTs work like one-of-its-kind while being perpetual on the Blockchain. It is the reason behind making NFTs difficult to replicate unique digital holding on the Ethereum Blockchain. It specifies the Smart Contract is working. Each ERC 721 can handle multiple tokens efficiently. The time token is transferred, you will require 2 important things including a Token ID, and a Smart Contract address. It defines the legitimacy of digital ownership and protects the NFT token from fraudulent activities.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. ERC 1155 Standard&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The solidity of the Smart Contract for NFTs will be bolstered further with the help of the ERC 1155 standard. It is considered a multi-token able to do multi-transactions. At a time, it has the capability to manage different tokens. With this token, a token ID will include its type, metadata, and supply. It will be useful for Smart Contracts to be semi-fungible, non-fungible as well as fungible. Hence, multiple tokens can be transferred in a single transaction.    &lt;/p&gt;

&lt;p&gt;Other than Ethereum, there are many Smart Contract Blockchains with NFT tools EOS, TRON, TEZOS, and Solarium. This NFTs standardization will be helpful to ensure the tokens’ interoperability. Here, these tokens will operate entirely different according to the Blockchain platforms they are implemented in.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Functions for NFT Smart Contract
&lt;/h3&gt;

&lt;p&gt;An NFT smart contract, usually adhering to standards like ERC-721 or ERC-1155, contains functions related to the creation and management of NFTs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Minting Functions:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;mint(address to, uint256 tokenId)&lt;/code&gt;: Creates a new NFT and assigns it to the specified address.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;safeMint(address to, uint256 tokenId)&lt;/code&gt;: Similar to mint, but checks that the recipient can receive NFTs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Metadata Functions:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;setBaseURI(string memory baseURI)&lt;/code&gt;: Sets the base URI for metadata, allowing dynamic linking to metadata using token IDs.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tokenURI(uint256 tokenId)&lt;/code&gt;: Returns the URI for a specific token, which points to its metadata (e.g., JSON file describing the NFT).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. Ownership Functions:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ownerOf(uint256 tokenId)&lt;/code&gt;: Returns the owner of a specific NFT.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;balanceOf(address owner)&lt;/code&gt;: Returns the number of NFTs owned by a specific address.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;4. Transfer Functions:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;transferFrom(address from, address to, uint256 tokenId)&lt;/code&gt;: Transfers ownership of a specific NFT from one address to another.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;safeTransferFrom(address from, address to, uint256 tokenId)&lt;/code&gt;: Transfers an NFT and checks that the receiving address can handle it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;5. Approval Functions:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;approve(address to, uint256 tokenId)&lt;/code&gt;: Grants permission to another address to transfer the specified NFT.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;setApprovalForAll(address operator, bool approved)&lt;/code&gt;: Approves or revokes approval for an operator to transfer all of a user’s NFTs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;6. Several helper functions:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;supportsInterface(bytes4 interfaceId)&lt;/code&gt;: Checks if a contract implements a specific interface.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;getCreator(uint256 tokenId)&lt;/code&gt;: Returns the creator of a specific NFT.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;getApproved(uint256 tokenId)&lt;/code&gt;: Returns the address approved to transfer a specific NFT.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;isApprovedForAll(address owner, address operator)&lt;/code&gt;: Checks if an operator is approved to manage all of an owner’s NFTs.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;function getRoyalty(uint256 tokenId)&lt;/code&gt;: Returns the royalty fee for a specific NFT.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;...&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Functions for NFT Marketplace Smart Contract
&lt;/h3&gt;

&lt;p&gt;An NFT marketplace smart contract facilitates buying, selling, and trading of NFTs. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Listing Functions:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;listNFT(uint256 tokenId, uint256 price)&lt;/code&gt;: Allows the owner of an NFT to list it for sale at a specified price.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;cancelListing(uint256 tokenId)&lt;/code&gt;: Allows the owner to cancel a listing before it is sold.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Buying Functions:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;buyNFT(uint256 tokenId)&lt;/code&gt;: Allows a user to purchase a listed NFT, transferring ownership and handling the payment.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;getNFTPrice(uint256 tokenId)&lt;/code&gt;: Returns the listing price for a specific NFT.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. Bid Functions for auction-style selling of NFTs:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;placeBid(uint256 tokenId, uint256 bidAmount)&lt;/code&gt;: Allows users to place bids on NFTs.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;acceptBid(uint256 tokenId, address bidder)&lt;/code&gt;: Allows the owner to accept a bid, completing the sale.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;4. Royalties and Payment Handling:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;setRoyaltyPercentage(uint256 tokenId, uint256 percentage)&lt;/code&gt;: Allows setting a royalty percentage for future sales of the NFT.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;withdrawFunds()&lt;/code&gt;: Allows the contract owner to withdraw funds collected from sales.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;5. Ownership Verification:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;isOwner(uint256 tokenId)&lt;/code&gt;: Returns whether the caller is the owner of the specified NFT.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;The development of NFT marketplaces represents a significant advancement in digital asset trading, combining blockchain technology with unique digital ownership. Through the implementation of standardized smart contracts like ERC-721 and ERC-1155, these platforms provide secure, transparent, and efficient ways to create, buy, sell, and trade NFTs.&lt;/p&gt;

&lt;p&gt;Key takeaways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;NFT smart contracts provide essential functions for minting, managing ownership, handling metadata, and facilitating transfers&lt;/li&gt;
&lt;li&gt;Marketplace smart contracts enable crucial features like listing, buying, bidding, and royalty management&lt;/li&gt;
&lt;li&gt;The combination of both contract types creates a robust ecosystem for NFT trading&lt;/li&gt;
&lt;li&gt;Standardization through ERC protocols ensures interoperability and security&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As the NFT space continues to evolve, understanding these fundamental components is crucial for developers looking to build secure and functional NFT marketplaces. The proper implementation of these smart contract functions creates a foundation for successful NFT platforms that can serve creators, collectors, and traders effectively.&lt;/p&gt;

&lt;p&gt;I will provide you with the code for the NFT marketplace smart contract step by step in the next article.&lt;/p&gt;

</description>
      <category>nft</category>
      <category>smartcontract</category>
      <category>marketplace</category>
      <category>erc721</category>
    </item>
    <item>
      <title>How to write ERC20 Token Presale smart contract using Solidity and Hardhat</title>
      <dc:creator>Mark Santiago</dc:creator>
      <pubDate>Thu, 21 Nov 2024 14:40:13 +0000</pubDate>
      <link>https://dev.to/marksantiago290/how-to-write-ico-smart-contract-using-solidity-and-hardhat-4pmg</link>
      <guid>https://dev.to/marksantiago290/how-to-write-ico-smart-contract-using-solidity-and-hardhat-4pmg</guid>
      <description>&lt;h2&gt;
  
  
  &lt;h3&gt;Introduction&lt;/h3&gt;
&lt;/h2&gt;

&lt;p&gt;This article will give you a knowledge of ERC20 token and how to write ERC20 Token Presale smart contract using Solidity and Hardhat.&lt;/p&gt;

&lt;h3&gt; Theory &lt;/h3&gt;

&lt;h4&gt; What is an ERC20 Token? &lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;ERC-20 is a technical standard; it is used for all smart contracts on the Ethereum blockchain for token implementation and provides a list of rules that all Ethereum-based tokens must follow.&lt;/li&gt;
&lt;li&gt;You can check all the ERC20 &lt;a href="https://docs.openzeppelin.com/contracts/2.x/api/token/erc20" rel="noopener noreferrer"&gt;functions&lt;/a&gt; before moving ahead.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt; What is an Initial Coin Offering (ICO)? &lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;An &lt;a href="https://www.coinbase.com/learn/tips-and-tutorials/what-are-initial-coin-offerings-and-how-do-they-work" rel="noopener noreferrer"&gt;Initial Coin Offering (ICO)&lt;/a&gt; is a fundraising mechanism in the cryptocurrency industry, akin to an Initial Public Offering (IPO) in the traditional financial sector.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Development of Smart Contracts&lt;/h3&gt;

&lt;h4&gt; ERC20 token contract &lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Token Specification

&lt;ul&gt;
&lt;li&gt;Token Name : MARK Token&lt;/li&gt;
&lt;li&gt;Token Symbol : MRK&lt;/li&gt;
&lt;li&gt;Token Decimal : 18&lt;/li&gt;
&lt;li&gt;Total Supply : 100,000,000,000&lt;/li&gt;
&lt;li&gt;Token Type : ERC20&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Token Contract&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;We will use OpenZeppelin ERC20 contract to create our token and mint 100 billion tokens to the owner of the contract.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//SPDX-License-Identifier: MIT
pragma solidity ^0.8.27;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract MKT is ERC20 {
    uint256 private _totalSupply = 100_000_000_000;

    constructor() ERC20("MARK Token", "MKT") {
        _mint(msg.sender, _totalSupply * 10 ** decimals());
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt; Token presale contract &lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Presale Specification&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Presale Supply : 10 billion (10%)&lt;/li&gt;
&lt;li&gt;Presale Period : 30 days&lt;/li&gt;
&lt;li&gt;Softcap : 300000 USDT&lt;/li&gt;
&lt;li&gt;Hardcap : 1000000 USDT&lt;/li&gt;
&lt;li&gt;Buy Token with ETH and USDT&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Key functions&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Buy&lt;/li&gt;
&lt;li&gt;Round management &lt;/li&gt;
&lt;li&gt;Claim&lt;/li&gt;
&lt;li&gt;Withdraw&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Implementation&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;We are going to use Chainlink Oracle to get the latest price of USDT and ETH. Alternatively you can use Uniswap or PancakeSwap to get the price of USDT and ETH.&lt;/p&gt;

&lt;h5&gt;
  
  
  &lt;em&gt;Buy MARK Token with ETH&lt;/em&gt;
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  function buy_with_eth()
        external
        payable
        nonReentrant
        whenNotPaused
        canPurchase(_msgSender(), msg.value)
        returns (bool)
    {

        uint256 amount_in_usdt = (msg.value * get_eth_in_usdt()) / 1e30;
        require(
            round_list[current_round_index].usdt_round_raised + amount_in_usdt &amp;lt;
                round_list[current_round_index].usdt_round_cap,
            "BUY ERROR : Too much money already deposited."
        );

        uint256 amount_in_tokens = (amount_in_usdt *
            round_list[current_round_index].usdt_to_token_rate) * 1e3;

        users_list[_msgSender()].usdt_deposited += amount_in_usdt;
        users_list[_msgSender()].tokens_amount += amount_in_tokens;

        round_list[current_round_index].usdt_round_raised += amount_in_usdt;

        (bool sent,) = round_list[current_round_index].wallet.call{value: msg.value}("");
        require(sent, "Failed to send Ether");

        emit Deposit(_msgSender(), 1, amount_in_usdt, amount_in_tokens);

        return true;
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;First&lt;/strong&gt;, the function has several checks through modifiers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;nonReentrant prevents reentrancy attacks&lt;/li&gt;
&lt;li&gt;whenNotPaused ensures the contract isn't paused&lt;/li&gt;
&lt;li&gt;canPurchase verifies the presale is active and valid purchase amount&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Next&lt;/strong&gt;, it calculates the USDT equivalent of sent ETH using Chainlink oracle price feeds&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  function get_eth_in_usdt() internal view returns (uint256) {
        (, int256 price, , , ) = price_feed.latestRoundData();
        price = price * 1e10;
        return uint256(price);
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And checks if the purchase amount is within the round cap.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Next&lt;/strong&gt;, it calculates token amount based on the USDT equivalent using the current round's exchange rate:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Next&lt;/strong&gt;, it updates the states of the user and the round:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Records user's USDT deposit and token allocation&lt;/li&gt;
&lt;li&gt;Updates the total USDT raised in current round&lt;/li&gt;
&lt;li&gt;Transfers the ETH to the round's wallet address&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Finally&lt;/strong&gt;, it emits a Deposit event with purchase details and returns true for successful transaction.&lt;/p&gt;

&lt;h5&gt;
  
  
  &lt;em&gt;Buy MARK token with USDT&lt;/em&gt;
&lt;/h5&gt;

&lt;p&gt;Similar to the ETH purchase, we can define the buy function with USDT as follows. The only difference is that this handles direct USDT transfers instead of using price oracles for conversion.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; function buy_with_usdt(uint256 amount_)
        external
        nonReentrant
        whenNotPaused
        canPurchase(_msgSender(), amount_)
        returns (bool)
    {
        uint256 amount_in_usdt = amount_;
        require(
            round_list[current_round_index].usdt_round_raised + amount_in_usdt &amp;lt;
                round_list[current_round_index].usdt_round_cap,
            "BUY ERROR : Too much money already deposited."
        );

        uint256 allowance = usdt_interface.allowance(msg.sender, address(this));

        require(amount_ &amp;lt;= allowance, "BUY ERROR: Allowance is too small!");

        (bool success_receive, ) = address(usdt_interface).call(
            abi.encodeWithSignature(
                "transferFrom(address,address,uint256)",
                msg.sender,
                round_list[current_round_index].wallet,
                amount_in_usdt
            )
        );

        require(success_receive, "BUY ERROR: Transaction has failed!");

        uint256 amount_in_tokens = (amount_in_usdt *
            round_list[current_round_index].usdt_to_token_rate) * 1e3;

        users_list[_msgSender()].usdt_deposited += amount_in_usdt;
        users_list[_msgSender()].tokens_amount += amount_in_tokens;

        round_list[current_round_index].usdt_round_raised += amount_in_usdt;

        emit Deposit(_msgSender(), 3, amount_in_usdt, amount_in_tokens);

        return true;
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  &lt;em&gt;Claim Token&lt;/em&gt;
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function claim_tokens() external returns (bool) {
        require(presale_ended, "CLAIM ERROR : Presale has not ended!");
        require(
            users_list[_msgSender()].tokens_amount != 0,
            "CLAIM ERROR : User already claimed tokens!"
        );
        require(
            !users_list[_msgSender()].has_claimed,
            "CLAIM ERROR : User already claimed tokens"
        );

        uint256 tokens_to_claim = users_list[_msgSender()].tokens_amount;
        users_list[_msgSender()].tokens_amount = 0;
        users_list[_msgSender()].has_claimed = true;

        (bool success, ) = address(token_interface).call(
            abi.encodeWithSignature(
                "transfer(address,uint256)",
                msg.sender,
                tokens_to_claim
            )
        );
        require(success, "CLAIM ERROR : Couldn't transfer tokens to client!");

        return true;
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Checks if presale has ended&lt;/li&gt;
&lt;li&gt;Verifies user has tokens to claim and hasn't claimed before&lt;/li&gt;
&lt;li&gt;Retrieves and stores user's claimable token amount&lt;/li&gt;
&lt;li&gt;Resets user's token balance to 0 and marks as claimed&lt;/li&gt;
&lt;li&gt;Transfers tokens to user using the token contract interface&lt;/li&gt;
&lt;li&gt;Returns true on successful claim&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  &lt;em&gt;Withdraw Token&lt;/em&gt;
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; function withdrawToken(address tokenContract, uint256 amount) external onlyOwner {
        IERC20(tokenContract).transfer(_msgSender(), amount);
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is restricted to contract owner only through onlyOwner modifier&lt;/li&gt;
&lt;li&gt;Allows owner to withdraw any ERC20 token from the contract&lt;/li&gt;
&lt;li&gt;Takes token contract address and amount as parameters&lt;/li&gt;
&lt;li&gt;Transfers specified amount to the owner's address&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  &lt;em&gt;Round Management&lt;/em&gt;
&lt;/h5&gt;

&lt;p&gt;We also need to define functions to manage the rounds:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  function start_next_round(
        address payable wallet_,
        uint256 usdt_to_token_rate_,
        uint256 usdt_round_cap_
    ) external onlyOwner {
        current_round_index = current_round_index + 1;

        round_list.push(
            Round(wallet_, usdt_to_token_rate_, 0, usdt_round_cap_ * (10**6))
        );
    }

  function set_current_round(
        address payable wallet_,
        uint256 usdt_to_token_rate_,
        uint256 usdt_round_cap_
    ) external onlyOwner {
        round_list[current_round_index].wallet = wallet_;
        round_list[current_round_index]
            .usdt_to_token_rate = usdt_to_token_rate_;
        round_list[current_round_index].usdt_round_cap = usdt_round_cap_ * (10**6);
    }

  function get_current_round()
        external
        view
        returns (
            address,
            uint256,
            uint256,
            uint256
        )
    {
        return (
            round_list[current_round_index].wallet,
            round_list[current_round_index].usdt_to_token_rate,
            round_list[current_round_index].usdt_round_raised,
            round_list[current_round_index].usdt_round_cap
        );
    }

  function get_current_raised() external view returns (uint256) {
        return round_list[current_round_index].usdt_round_raised;
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;This ERC20 token contract and Presale contract is a comprehensive and secure solution for conducting token presales. It provides features for managing presale rounds, depositing USDT, claiming tokens, withdrawing tokens, and managing rounds. The contract is designed to be flexible and customizable for different presale scenarios.&lt;/p&gt;

</description>
      <category>erc20</category>
      <category>smartcontract</category>
      <category>solidity</category>
      <category>presale</category>
    </item>
  </channel>
</rss>
