# Home

> ***UPDATE: In light of recent events with Terra Classic, Pylon Protocol is continuing to explore all possible options moving forward. We are committed to our vision of platforms built around yield redirection and deposit contracts.***&#x20;
>
> ***Please check our Twitter or Telegram for more updates and information on next steps.***

Welcome!&#x20;

This is where you will find all the essential information about Pylon Protocol, including documentation for the functional and technical aspects of Pylon Protocol's core products.

You can access Pylon Protocol through the[ landing page](https://www.pylon.money/), trade and stake Pylon's native governance tokens (MINE) on the [Pylon WebApp](https://app.pylon.money/), and deposit to invest in early stage projects, NFTs, and DAO Funds on [Pylon Gateway](https://gateway.pylonprotocol.com/), Terra's leading project launchpad.

This is a live document that will be updated as the protocol evolves over time via governance.

## What is Pylon Protocol? 💎

**Pylon Protocol** consists of a suite of savings and payments products in decentralized finance (DeFi) that builds on low-volatile yield-bearing protocols, notably Anchor, to provide services powered by user deposits. Pylon enables sustainable exchanges between long-term value providers and their consumers through customizable deposit contracts and yield redirection.

As a promising future standard of programmable payments, Pylon introduces a new paradigm of incentive alignment between payers and payees, consumers and creators, patrons and artists, investors and entrepreneurs, borrowers and lenders, and many more groups and relationships.&#x20;

The protocol is maintained by various independent platforms and is governed by holders of Pylon's native governance token also known as **$MINE.**

## **What problem is Pylon trying to solve?**

In a conventional value transfer model, a seller offers some good or service and a buyer pays with money or barter. While this model works well for immediate and one-off transactions, it fails to effectively capture value for transactions over a sustained period of time involving recurring services and consumption. Consider the following cases:

1. **Sellers of future value or unascertained goods** (early-stage startups, crowdfunding, initial coin offerings, etc.) may not be incentivized to deliver value over time if they receive all the funds upfront.
2. **Sellers of intangible value** (artists, musicians, livestreamers, content creators, etc.) may struggle to monetize their niche creative content offerings and receive steady payouts that reflect fanbase growth over time.
3. **Sellers of recurring value** (content IP, SaaS software, subscription-based services, etc.) may need to rely on discounts to fair value to reduce churn.
4. **Lenders of illiquid assets** (real estate, cars, luxury items, etc.) may lack a venue to securely lease their assets over time and be provided with proper recourse for contract violations.

Pylon provides each of these parties with the technical toolkit necessary to readjust their payments options and accommodate long-term services that garner value with the growth of an active customer base. Pylon aspires to build a wide array of consumer-friendly payments and savings platforms that integrate complex DeFi payments infrastructure via simple user deposits.

## Deposit with Pylon

Pylon unlocks a new suite of options for payments, patronage, investments, rentals, and savings. When realized as a payments gateway, Pylon is a **principal-protected payment product** where users can finance recurring services (i.e. subscriptions, memberships, content offerings) via "key money" deposits and consistent interest payouts.

Most simply put, users can **deposit Terra native assets and spend accrued yields** on platform services and content offerings. Upon subscription expiry, users can **withdraw their principal in full**. Platforms can easily integrate the "Deposit with Pylon" widget in 10 lines of code.

By making a simple retrievable deposit, users essentially receive **"no-fee" subscription services;** contribute to charity and academic research in perpetuity; support their admired artists and gain access to gated content and NFT airdrops; rent cars and condos with their principal as collateral; enter raffles and mystery box giveaways with prize savings accounts; and make "lossless" investments in startup blockchain projects with all the upsides of being an early investor.

By "principal-protected" and "lossless," this means a guarantee of minimum return equal to the investor's amount, not value, of initial investment. For instance, if a user deposits 10 LUNA and yields from the token are redirected to a third-party beneficiary for a certain period of time, a user can later retrieve the underlying 10 LUNA, although the value of the token may fluctuate.

**Reimagining the future of recurring payments** and providing convenient platform integrations for the mainstream adoption of crypto, Pylon aims to become a must-have feature of the DeFi future. Forthcoming Pylon innovations plan to stretch the design space for programmable payments and represent an exciting paradigm shift for real-world DeFi applications.

## Core Products

Rather than limiting itself to a single platform, Pylon intertwines a series of decentralized, modular payments and savings gateways. Pylon's core products include a project launchpad, yield-integration widget, and a dashboard for staking rewards. Pylon's products are configured in a way that allows for the entire platform to maintain decentralized governance by MINE token holders, while continuing to innovate with platform integrations.

**Pylon Gateway**

[Pylon Gateway](https://gateway.pylonprotocol.com/) is a user-friendly token launchpad for forthcoming projects in the Terra ecosystem, and Pylon Protocol’s first fully integrated use case and flagship platform.

**Pylon Protocol WebApp**

The [Pylon WebApp](https://app.pylon.money/) allows users to easily trade and stake MINE, vote on community governance proposals, engage with the Pylon community, and propose ideas for future platform growth.

"**Deposit with Pylon" Widget**

Pylon will soon be launching a widget and SDK which new and existing platforms can simply integrate into their payment options. This would allow users on any crypto-friendly site to pay for services via user deposits and automatically redirect yield to creators and platforms.

**"You Must Build Additional Pylons..."**

Forthcoming platforms building on Pylon Protocol span the range of applications in philanthropy, arts and entertainment, hospitality and tourism, real estate, savings accounts, sweepstakes, as well as other recurring subscriptions and membership programs.&#x20;

Terraform Labs and Pylon's core team is currently developing a second flagship product which aims for mainstream adoption, planning to launch in Q3.

## Sections

Further documentation of Pylon Protocol is provided in the following pages.

* Read up on the specifications and descriptions of Pylon's main offerings
* Check out Pylon's core smart contracts and the mechanics of deposit provider contracts
* Find out how to invest in Pylon's native governance token MINE via Pylon Gateway
* Engage in governance and Pylon's forum through governance proposals
* Learn about the mechanics behind the yield-generating protocols that support Pylon
* Discover forthcoming service provider platforms powered by Pylon's payments-via-deposits

## Communication Channels

Telegram: <https://t.me/pylon_protocol>

Twitter: <https://twitter.com/pylon_protocol>

Medium: <https://medium.com/pylon-protocol>

## Pylon Protocol Links

Pylon Website: <https://www.pylon.money/>

Pylon WebApp: <https://app.pylon.money/>

Pylon Gateway: <https://gateway.pylon.money/>


# Security

The security of Pylon Protocol is our highest priority; our development team, alongside third-party auditors and consultants, has invested considerable effort to create a protocol that we believe is safe and dependable. All contract code and balances are publicly verifiable, and security researchers are eligible for a bug bounty for reporting undiscovered vulnerabilities.

Built on open-source software, Pylon's site and all our Smart Contracts are publicly visible for maximum transparency. We believe that size, visibility, and time are the true test for the security of a smart contract; please exercise caution, and make your own determination of security and suitability.

## **Audits**

* [**Independent audit report**](https://drive.google.com/file/d/1aki0EznHBNcNeUyQ2wr0sx5pjMtt4R_P/view?usp=sharing)
* Forthcoming second audit by Cryptonics

## Pylon **Bug Bounty Program**

Security is core to our values, and we value the input of hackers acting in good faith to help us maintain the highest standard for the security and safety of the Pylon ecosystem. Pylon Protocol depends on new technology that may contain undiscovered vulnerabilities.

Pylon encourages the community to audit our contracts and security; we also encourage the responsible disclosure of any issues. This program is intended to recognize the value of working with the community of independent security researchers, and sets out our definition of good faith in the context of finding and reporting vulnerabilities, as well as what you can expect from us in return.

### **Rewards**

Pylon offers substantial rewards for discoveries that can prevent the loss of assets, the freezing of assets, or harm to a user, commensurate with the severity and exploitability of the vulnerability. Pylon will pay a reward of $500 to $150,000 for eligible discoveries according to the terms and conditions provided below.

### **Scope**

The primary scope of the bug bounty program is for vulnerabilities affecting the on-chain Pylon Protocol, deployed to the Terra Columbus 0.4.1 Mainnet, for contract addresses listed in this developer documentation.

This list may change as new contracts are deployed, or as existing contracts are removed from usage. Vulnerabilities in contracts built on top of the Protocol by third-party developers (such as smart contract wallets) are not in-scope, nor are vulnerabilities that require ownership of an admin key.

The secondary scope of the bug bounty program is for vulnerabilities affecting the Pylon Protocol Interface hosted at [app.pylonprotocol.com](http://app.pylonprotocol.com/) that could conceivably result in exploitation of user accounts.

Finally, test contracts (Tequila and other testnets) and staging servers are out of scope, unless the discovered vulnerability also affects Pylon Protocol or Interface, or could otherwise be exploited in a way that risks user funds.

### **Disclosure**

Submit all bug bounty disclosures to **<contact@pylon.money>**. The disclosure must include clear and concise steps to reproduce the discovered vulnerability in either written or video format. Pylon will follow up promptly with acknowledgement of the disclosure.

### **Terms and Conditions**

To be eligible for bug bounty reward consideration, you must:

* Identify an original, previously unreported, non-public vulnerability within the scope of the Pylon bug bounty program as described above.
* Include sufficient detail in your disclosure to enable our engineers to quickly reproduce, understand, and fix the vulnerability.
* Be at least 18 years of age.
* Be reporting in an individual capacity, or if employed by a company, reporting with the company’s written approval to submit a disclosure to Pylon.
* Not be subject to US sanctions or reside in a US-embargoed country.
* Not be a current or former Pylon employee, vendor, contractor, or employee of an Pylon vendor or contractor.

To encourage vulnerability research and to avoid any confusion between good-faith hacking and malicious attack, we require that you:

* Play by the rules, including following the terms and conditions of this program and any other relevant agreements. If there is any inconsistency between this program and any other relevant agreements, the terms of this program will prevail.
* Report any vulnerability you’ve discovered promptly.
* Avoid violating the privacy of others, disrupting our systems, destroying data, or harming user experience.
* Use only **<contact@pylon.money>** to discuss vulnerabilities with us.
* Keep the details of any discovered vulnerabilities confidential until they are fixed.
* Perform testing only on in-scope systems, and respect systems and activities which are out-of-scope.
* Only interact with accounts you own or with explicit permission from the account holder.
* Not engage in blackmail, extortion, or any other unlawful conduct.

When working with us according to this program, you can expect us to:

* Pay generous rewards for eligible discoveries based on the severity and exploitability of the discovery, at Pylon's sole discretion
* Extend Safe Harbor for your vulnerability research that is related to this program, meaning we will not threaten or bring any legal action against anyone who makes a good faith effort to comply with our bug bounty program.
* Work with you to understand and validate your report, including a timely initial response to the submission.
* Work to remediate discovered vulnerabilities in a timely manner.
* Recognize your contribution to improving our security if you are the first to report a unique vulnerability, and your report triggers a code or configuration change.

**All reward determinations, including eligibility and payment amount, are made at Pylon's sole discretion. Pylon reserves the right to reject submissions and alter the terms and conditions of this program.**


# Overview

## Deposit with Pylon

Pylon builds on Anchor's fully decentralized fixed income standard to open up a new design space for payments for services via retrievable key stablecoin deposits and yield redirection.

1. **Users deposit Terra stablecoins and access platform-specific services.**

   e.g. 1 > Investor Zerg deposits $100K UST into Pylon Gateway in return for $MINE token rewards over a vesting period of 12 months.\
   e.g. 2 > Collector Mirror deposits $500 UST via the "Deposit with Pylon" widget to support the artwork of Artist Anchor
2. **Creators receive stable yield payouts for providing recurring services.**

   e.g. 1> Project team Protoss receives funding via payouts-in-yield generated by Zerg's deposit over the vesting period of 12 months.\
   e.g. 2 > Artist Anchor receives consistent yield stipends to support their creative artwork without having to worry about financing their work.
3. **Upon subscription expiry, users withdraw their principal in full.**

   e.g. 1 > Investor Zerg is issued a full refund of $100K UST after 12 months in addition to $MINE token rewards, which Zerg can claim beginning 6 months into the vesting period.\
   e.g. 2 > Collector Mirror receives back the $500 UST deposit (or may decide to donate it to Artist Anchor to provide patronage in perpetuity) while also claiming NFT airdrops, exclusive tickets to virtual tours, meet-and-greets, and perhaps even physical merch.

## Protocol Participants

The main participants that exist in the Pylon ecosystem include **users** (payers), **creators** (value providers), **platforms**, **MINE investors**, **MINE stakers**, and **MINE liquidity providers**.

#### Users

Users are the payers who deposit stablecoins in return for a particular service, content offering, exclusive membership, or other staking rewards. Depending on specific platform integrations, users can be interchangeably referred to as customers, investors, patrons, fandoms, donors, consumers, or borrowers.

#### **Creators**

Creators are the value providers of a service who receive regular interest payouts via Anchor. Depending on specific platform integrations, creators can be interchangeably referred to as suppliers, project teams, artists, popular influencers, beneficiaries, producers, or lenders.

#### **Platforms**

Platforms are the forums of exchange that facilitate long-term transactions between users and creators. Platforms can integrate Pylon's deposit-to-pay mechanism to pay creators via user deposits. Pylon's open source Payments-as-a-Service SDK can be integrated in 10 lines of code.

#### Users

Early users of Pylon Gateway can stake UST for a designated vesting period in return for various project token rewards.

**Stakers**

MINE stakers are holders of Pylon's native token MINE who are eligible to participate in governance, and receive voting power weighted by the amount of their total staked MINE. MINE stakers also earn staking rewards which grow linearly as more deposits are made into Pylon. MINE can be staked through the Pylon WebApp.

Regarding Pylon Gateway in particular, MINE stakers may gain access to exclusive pools for selected projects and may receive airdrops for project tokens launching on Pylon Gateway.

#### Li**quidity Providers**

MINE Liquidity Providers provide liquidity to the MINE-UST Terraswap Pair. They manage the initial bootstrapping of the exchange liquidity between MINE tokens and UST. MINE exchange liquidity is critical as MINE tokens are distributed as depositor and platform incentives.

## Mechanism

Pylon Protocol builds on Terra's native savings standard via Anchor Protocol to provide a medium for sustainable payments.

Later versions of Pylon Protocol will accommodate yield diversification by partnering with a number of different yield-bearing protocols within and beyond the Terra ecosystem.

#### **Anchor Protocol**

[Anchor](https://docs.anchorprotocol.com/) is a principal-protected low-volatility savings product that accepts Terra deposits and stabilizes the deposit interest rate. To generate yield, Anchor lends out deposits to borrowers who put down liquid-staked assets from diversified Proof-of-Stake blockchains as collateral and passes on a variable fraction of block rewards from collateral assets to depositors.

## Tokens

| Name               | Type         | Description                                            |
| ------------------ | ------------ | ------------------------------------------------------ |
| TerraUSD (UST)     | Native Terra | Terra Stablecoin pegged to the US Dollar               |
| Pylon Token (MINE) | CW20 Token   | Governance token for Pylon Protocol                    |
| PylonDP Token      | CW20 Token   | Deposit receipt for Pylon Protocol (Liquid Pylon Pool) |


# Pylon Token ($MINE)

![](/files/-MdWHdYLGBvS57h32Jw2)

**MINE** is the native governance token for Pylon Protocol. As with Pylon's namesake, MINE is inspired by "minerals" in StarCraft.

A portion of all yields generated across all forthcoming platforms and projects launching on Pylon Protocol and its suite of products, including Pylon Gateway, are captured by the Pylon Treasury. MINE stakers are able to govern in a decentralized fashion the initial distribution parameters and further use cases of the Pylon Treasury.

### Token Utility

The most prominent functionality of MINE is to allow holders to govern the underlying protocol via the **Pylon WebApp**. Users can deposit MINE to create governance polls, while MINE stakers can vote on community fund grants, protocol updates, launchpad projects, parameter changes, new features development, treasury distribution, and other ecosystem expansion initiatives.

Via the Pylon Treasury, MINE is designed to capture a portion of yields and transactions generated across all Pylon platforms and project launches on **Pylon Gateway,** such that MINE holders directly benefit from the growth of Pylon Protocol's total value locked (TVL).

Currently, as per [Governance Poll #8](https://app.pylon.money/gov/poll/8) to lay out an initial distribution of the Pylon Treasury, the accrued yield reserve is distributed as follows:

1. 25% for weekly MINE token buybacks at market prices to be linearly distributed to stakers
2. 25% for providing additional liquidity to the MINE-UST pair, with LP rewards being linearly distributed to stakers
3. 50% being stored as aUST in Anchor Protocol, with further storage and use cases for the UST being governed by stakers

MINE buybacks and rewards generated from the MINE-UST LP pair are linearly distributed as staking rewards to MINE stakers in proportion to each staker's percentage of total stake in the governance pool. This process creates buying pressure against the generation of new MINE tokens, supports long-term price stability and value growth, and allows Pylon to share transaction fee revenues with ecosystem participants.

MINE provides incentives to active community members on **Pylon Gateway,** that is, users and project teams, as well as for secondary platforms that are building service offerings integrating Pylon via proposals submitted to the community fund. Liquidity providers to the MINE-UST LP pair also receive MINE as passive income.

### Value Accrual

Pylon captures a portion of total protocol assets under management (AUM) with the MINE token. A percentage of interests and revenues generated across all Pylon projects and platforms will be captured in the Pylon Treasury, governed by MINE stakers. For Pylon Gateway, the platform fee will be 20% of all yields generated.

Yields collected in TerraUSD are used in various cases to generate value for MINE stakers, including buybacks and protocol-owned liquidity.

The parameters of the yield accrual mechanism can be changed in the future through the governance process. Holders of MINE are incentivized to propose, discuss, and vote for proposals that further merit the protocol.

MINE doubles as an incentives mechanism to bootstrap depositor demand and project launch incentives for platforms and projects that build on Pylon. Active ecosystem participants are awarded with MINE for their participation. These activities may include:

* users making deposits into selected projects on Pylon Gateway and other Pylon platforms
* projects launching tokens on Pylon Gateway
* platforms building service offerings that integrate with Pylon's "Deposit with Pylon" widget
* liquidity providers of the MINE-UST pair on various decentralized exchanges on Terra

On top of MINE rewards, MINE stakers may receive additional real-time project token airdrops, NFT airdrops, and additional token rewards and early access perks on **Pylon Gateway**.

The latest proposal for [Pylon Funds](https://medium.com/pylon-protocol/roadmap-and-monthly-update-december-2021-3e5ff25831c3) on Pylon Gateway, will introduce a deflationary mechanics by requiring user-depositors to burn MINE in order to deposit into particular pools.

### Governance

MINE stakers can exercise voting rights over protocol upgrades, parameter changes, community grants, and text proposals on Pylon's decentralized governance platform. Voting power for users is proportional to the amount of MINE staked.

Any proposal implementation or community fund use will be implemented only if it is clearly by the will of the community, that is, a passing vote by quorum.

MINE token deposits for Pylon governance polls that have failed to reach the required quorum will be sent back to MINE stakers as staking rewards.

### Token Supply

The hard cap of circulating MINE token supply will be fixed at **10,000,000,000 MINE**, which is scheduled for distribution over a period of at least 4 years. Beyond that, there will be no more MINE tokens introduced to the supply.

Annual inflation rate of MINE tokens is designed to gradually decrease every year, until MINE eventually reaches a maximum capped supply of **10B**.

### Genesis Token Distribution

![](/files/-Md2OjO7uzTpwCXWuF6M)

A total of **2,500,000,000 MINE** tokens are released at the genesis of Pylon Protocol. The initial distribution of MINE will be as follows:

* **Pylon Launchpad**: 400M (16%) tokens will be distributed in early "deposit to earn" farming pools for community investors on Pylon Gateway, Terra's premier project launchpad.
* **LUNA Staking Airdrop**: 500M (20%) tokens will be airdropped to LUNA stakers, with the snapshot taken on the date of launch.
* **Community Fund**: 1,600M (64%) will be allocated to the community pool, governed by MINE stakers. At least 100M tokens will be reserved for bootstrapping initial project pipeline on Pylon Gateway, early user onboarding, or growth round fundraising as needed.

### Final Token Distribution

![](/files/-Md2PHozWdMNgZWs_Uw1)

Further MINE tokens are set to be released over a period of at least 4 years, increasing total supply until it reaches **10B**. The final distribution structure will be:

* **Pylon Launchpad**: 400M (4%) tokens will be distributed to early MINE investors over vesting periods of 6 months, 12 months, and 18 months.
* **Genesis Airdrop for LUNA Stakers**: 500M (5%) tokens are airdropped to LUNA stakers on launch.
* **Weekly Airdrops for LUNA Stakers**: 1,000M (10%) tokens are linearly distributed to LUNA stakers over a period of 2 years. Tokens will be distributed every 100,000 blocks (approximately every week). Snapshots are taken every 100,000 blocks to determine distribution eligibility.&#x20;
  * \[**Update**] As with [Governance Poll #4](https://app.pylon.money/gov/poll/4), weekly MINE airdrops for LUNA stakers are no longer active. The remainder of the MINE allocation reserved for airdrops for LUNA stakers have been redirected to the Pylon Treasury.
* **Depositor Incentives**: 4,000M (40%) tokens are reserved for rewarding ecosystem participation, encouraging user deposits, project partnerships, and third-party SDK integrations to bring about more TVL to Pylon's ecosystem.
* **Community Fund**: 1,600M (16%) tokens will be reserved for the Pylon Community Fund, governed by MINE stakers.
* **Team Reserve:** 1,000M (10%) tokens will be vested over 3 years to the core Pylon team, following a 1 year lockup period.
* **MINE LP Staking Rewards:** 1,500M (15%) tokens are distributed to the MINE-UST pair liquidity providers over a period of 4 years.

#### Distribution to Ecosystem Participants

MINE tokens allocated for depositor incentives are gradually distributed to depositors (users), creators, and platforms, including projects teams and investors on Pylon Launchpad, as well as other ecosystem participants on forthcoming Pylon-powered platforms.

MINE aims to fuel a reinforcing adoption cycle, incentivizing more projects to integrate the Pylon SDK and more depositors to stake UST.

#### **Distribution to MINE Liquidity Providers**

High exchange liquidity for MINE is crucial for maintaining a constant incentive flow across all platforms. To incentivize initial exchange liquidity of MINE, newly minted MINE is distributed to liquidity providers, specifically via the fMINE-UST pair. MINE tokens are distributed as part of staking rewards for LP token holders of the MINE-UST pair.


# Pylon Governance

{% hint style="info" %}
**NOTE**: Governance poll features will be enabled with a future update. MINE Governance stakers **may receive MINE buybacks** from all Pylon Core pools (10% of redirected interest) in the meantime. Only MINE Governance stakers may vote in polls once Governance features are fully enabled.
{% endhint %}

The Pylon Governance framework aims to build a solid and sustainable protocol for development and usage. Governance is the decentralized process through which proposals for change in Pylon Protocol are introduced and accepted by the community through voting.

There are no admin keys with privileged access. After the initial bootstrapping of contracts, the Governance contract is set to be the owner of the Pylon Protocol contracts and all changes must be made through the governance with the procedure defined in this section. All major structural changes to Pylon Protocol must be voted on by the community and passed with a quorum to be considered binding.

Users can deposit MINE to create governance polls, and MINE stakers can vote on community fund grants, protocol updates, launchpad projects, parameter changes, new features development, and other ecosystem expansion initiatives. Every winning proposal will be then reviewed and applied by Pylon's core development and management team.

## Pylon Token (MINE)

The Minerals Token (MINE) serves as Pylon Protocol's governance token. Only users with a staked MINE position can vote on polls, and each user receives voting power weighted by their amount of staked MINE. For every poll, a user can choose to allocate up to their total staked MINE. Users with higher MINE stake will have more influence when deciding in governance polls.


# Community Grants

The **community pool** is a reserve of MINE tokens that is held by governance, meant for funding future projects and contributors to the Pylon protocol. The community pool will total to 1,600M MINE tokens. The community pool's initial funds are minted at the start when Pylon contracts are first created. A governance poll must be created in order to spend tokens from the fund.

The purpose of the grant is to empower ecosystem teams to build necessary tools and infrastructure that are not provided at the launch of the protocol. Projects that are value additive to the protocol and/or make user experience better such as the creation of new smart contract applications that enable greater access across more markets or dashboards and other tools for managing their assets on the Pylon Protocol are eligible for community grant funding. Any proposal for funding that is deemed acceptable by the community and passes a vote can receive funding from the community pool.

The maximum allowable grant is the current size of the community pool at the submission time of the poll.


# Text Proposal

Any proposal that does not fit the pre-listed proposals can be submitted as a **Text Proposal**. A text poll consists of a simple title that should describe the rationale of the proposal, a short description of the proposal, and an optional field to include an external link.

Given that the text poll smart contract only supports short descriptions (limited to 1024 bytes), it is advisable to attach an external link in the `Information Link` field which includes further rationale on the proposal.


# Pylon Gateway

[Pylon Gateway](https://gateway.pylonprotocol.com/) is a **permissionless project launchpad** that helps investors make secure, **"**&#x6C;ossless," and value-additive crypto investments. Wielding the phrase "Deposit to Invest," users can stake Terra stablecoins (e.g. UST) over a vesting period and receive project tokens as rewards, while project teams receive yields generated from the initial deposits.

Serving as Pylon Protocol's first fully integrated use case and flagship platform, Pylon Gateway is built to serve as a user-friendly token launchpad and crowdfunding platform. From the onset, Pylon Gateway aims to encourage forthcoming projects to launch their tokens on Terra.

Disclaimer: Pylon Gateway does not involve itself in reviewing or auditing contract code for projects. Tokens launching on Pylon do not constitute investment advice. Legal treatment of assets purchased will depend on user/project jurisdiction, and users should partake in careful legal review before depositing any funds.

#### For User Investors

Pylon Gateway provides a forum for users to make "lossless" investments, that is, to make investments with their base capital untouched. The amount, not value, of tokens deposited into Anchor will be returned to the depositor in full post-unlock.

Users can deposit Terra stablecoins for a selected vesting or lockup period to earn project tokens and governance rights. Users can withdraw their full principal after the pledged vesting or lockup period to claim corresponding rewards.

Pylon Gateway allows users to discover hidden gems at early-stage and discounted prices, as well as become a long-term ally for new and exclusive token launches in the Terra ecosystem.

#### For Project Teams

Pylon Gateway enables early-stage and existing ventures to raise funds and scale their ideas, while remaining focused on developing their products as opposed to spending time both building and marketing. Project teams can customize funding options and investments-via-deposits in return for consistent payouts that actively respond to new project developments.

Integrated with both Pylon Protocol and the Terra Network, Pylon Gateway will open up projects to a larger initial audience reach than if they had deployed their own campaigns. Pylon Gateway lowers the barrier of entry for projects launching a token on a strong, secure launchpad.

**Pylon Pools for Deposits**

Project teams can allocate new tokens to a customized **Pylon Pool** where investors can deposit UST (and later, other Terra-based currencies such as MINE or LUNA), and receive project tokens and designated rewards in return. Project teams can customize their own investment pools and token vesting and token claiming schedules in order to meet the specific and evolving needs of each project launch campaign. There are no upper limits on the total amount of tokens an investor can commit to each Pylon Pool. All Pylon Pools remain open for investors to enter at any time until the end of the vesting period, although early investors are rewarded for their long-term support. Project token rewards allocated for each pool will be distributed to all investors, weighted according to their contribution to the pool.

Each Pylon Pool will come with different vesting periods. The investor's deposits in TerraUSD will be locked for the remaining duration of the vesting period, while project tokens will be distributed linearly. Upon completing an initial project token lockup duration (set by each project team), investors can start to claim and withdraw project tokens. Depending on the timeline for each project, investors may be able to claim project tokens earlier than the investor’s pledged UST deposit withdrawal date.

For example, if one Pylon Pool for $PROJECT comes with a token vesting period of 6 months and an initial project token lockup duration of 3 months, an investor’s principal-protected UST deposit would be locked for 6 months in its entirety, while the investor would be able to claim and withdraw $PROJECT tokens starting 3 months from the launch date of that particular Pylon Pool.

**Pylon Pools for NFT Raffles**

NFT projects can feature their own NFTs on Pylon Gateway via lossless NFT raffle pools. NFTs are airdropped to UST and MINE stakers based on duration and amount staked, and users can stake and unstake at any time. Project teams can decide how frequently to send over the NFT airdrops and decide the specific parameters for NFT raffle airdrops and distribution.

**Gateway Fund for Treasury Swaps**

Projects can also delegate some of their tokens to **Gateway Fund**, a yield-based community fund for collective fixed swaps. On this mechanism, users deposit UST in return for collective swaps administered via decentralized voting on promising projects. Project tokens are to be distributed in a linear retrospective fashion, allowing earlier depositors to benefit the most from the continued growth of the fund. Upon lockup period expiry, users can claim their underlying UST deposits.

**Future Crowdfunding Options**

Based on each project team’s preferences for crowdfunding, Pylon Gateway may possibly later accommodate flexible funding options for projects, including dutch auctions, blind auctions, and batch auctions. Beyond token launches, future projects may provide investor rewards in the form of NFTs, participatory rights, and exclusive memberships.

Later versions of Pylon Gateway will introduce for project teams instant loans that pay themselves off via future yields from investor deposits, which will support project teams that may need upfront capital for early bootstrapping. For investors, Pylon Gateway eventually aims to accept deposits in other Terra-native currencies including LUNA and MINE, redirecting staking rewards to project teams.

### MINE Token Launch

MINE is Pylon Protocol’s native utility token and Pylon Gateway's debut token launch project, with its namesake inspired by minerals in Starcraft. MINE is built with a yield-capturing mechanism for all forthcoming platforms and project launches integrated with Pylon Protocol.

There will be three separate MINE Pylon Pools and one MINE Pylon Swap, with a total of 400M MINE tokens distributed via Pylon Gateway, amounting to 16% of genesis token distribution.

#### 💠 Earn MINE

200M MINE tokens are available for investments-via-deposits via **Pylon Pools**. Users can deposit TerraUSD (UST) over a vesting period and receive MINE rewards in return. Once the vesting period ends, users can retrieve their UST deposits in full.

Annual percentage yield (APY) is determined by UST staked, deposit demand, interest generated, total number of MINE tokens allocated per pool, and MINE token pricing.

💎 **Pool 1**. \[18 month vesting] The first pool offers a linear MINE vesting period over 18 months, where investors can claim investment returns beginning 9 months from the date of pledge. There will be a total of 130M MINE tokens allocated.

💎 **Pool 2**. \[12 month vesting] The second pool offers a linear MINE vesting period over 12 months, where investors can claim investment returns beginning 6 months from the date of pledge. There will be a total of 50M MINE tokens allocated.

💎 **Pool 3**. \[6 month vesting] The third pool offers a linear MINE vesting period over 6 months, where investors can claim investment returns beginning 3 months from the date of pledge. There will be a total of 20M MINE tokens allocated.

There are no upper limits on the amount of UST tokens an investor can commit to their investment-via-deposits. MINE tokens allocated for each pool will be divided amongst all investors, weighted according to their contribution to the pool. The amount of MINE tokens investors will earn daily from the Pylon Pools is proportional to the amount of UST investors have subscribed to the pool versus the total number of UST subscribed to the pool.

#### 💠 Claim MINE

The amount of MINE tokens each investor will earn is calculated daily, and investors can begin to harvest pending rewards depending on each pool's designated timeframe for claiming rewards.

Upon claiming MINE, investors can stake MINE using the Pylon WebApp, provide liquidity to the MINE-UST liquidity pool, or trade MINE at market prices on exchanges such as Terraswap.

### Enter Pylon Gateway

Deposit to invest today on Pylon Gateway.

If you are a project team hoping to launch your tokens on Pylon Gateway, please refer to the Pylon Forum post, "[For Projects Submitting Applications](https://forum.pylon.money/t/for-projects-submitting-applications/183)."


# Core

`pylon-protocol/core` contracts define Pylon interest redirection logic, of which:

* any UST deposited to the `Pool` contract is deposited to Anchor, and returned aUST from resulting contracts is held by this contract.
* the `Pool` contract returns **DP tokens** (Deposit Provider tokens) instead, which are pegged 1:1 to UST.
* the `Pool` contract queries new `exchange_rate` parameters from Anchor, and uses this information to calculate how much UST should be returned for DP token redemptions and interest redirection, respectively.
* `exchange_rate` follows a `virtual exchange rate` parameter calculated by the `Exchange Rate` contract, which charges a 10% fee for all generated interest.
* collected fees are sent to the `pylon-protocol/token/collector` contract to be used for **MINE buybacks** for **MINE governance stakers**.


# Pool

**Deployed at:** [**`terra1z5j60wct88yz62ylqa4t8p8239cwx9kjlghkg2`**](https://finder.terra.money/columbus-4/address/terra1z5j60wct88yz62ylqa4t8p8239cwx9kjlghkg2)

### **`config.rs`**

Stores all relevant contract parameters.

```rust
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct Config {
    pub this: CanonicalAddr,
    pub owner: CanonicalAddr,
    pub beneficiary: CanonicalAddr,
    pub moneymarket: CanonicalAddr,
    pub atoken: CanonicalAddr,
    pub stable_denom: String,
    pub dp_token: CanonicalAddr,
}
```

`this`: the address of this pool contract.

`owner`: the owner address of this pool contract.

`beneficiary`: the address of which all interest collected from principal deposits are sent to. could be a single address, or a contract address that oversees additional distribution logic.

`moneymarket`: the address of the Anchor money market contract to accept deposits.

`atoken`: the address of the aUST token contract.

`stable_denom`: base Terra stablecoin denomination of this pool to be deposited to Anchor, i.e. `uusd`.

`dp_token`: the address of the DP token contract minted by this pool.

### **`contract.rs`**

Defines logic entry points for `InitMsg`, `HandleMsg` and `QueryMsg` calls.

```rust
pub fn init<S: Storage, A: Api, Q: Querier>(
    deps: &mut Extern<S, A, Q>,
    env: Env,
    msg: InitMsg,
) -> StdResult<InitResponse> {
    let sender = env.message.sender;
    let raw_sender = deps.api.canonical_address(&sender)?;

    let mut config = config::Config {
        this: deps.api.canonical_address(&env.contract.address)?,
        owner: raw_sender,
        beneficiary: deps.api.canonical_address(&msg.beneficiary)?,
        fee_collector: deps.api.canonical_address(&msg.fee_collector)?,
        exchange_rate_feeder: deps.api.canonical_address(&msg.exchange_rate_feeder)?,
        moneymarket: deps.api.canonical_address(&msg.moneymarket)?,
        stable_denom: String::default(),
        atoken: CanonicalAddr::default(),
        dp_token: CanonicalAddr::default(),
    };

    let market_config = querier::anchor::config(deps, &config.moneymarket)?;

    config.stable_denom = market_config.stable_denom.clone();
    config.atoken = deps.api.canonical_address(&market_config.aterra_contract)?;

    config::store(&mut deps.storage, &config)?;

    Ok(InitResponse {
        messages: vec![CosmosMsg::Wasm(WasmMsg::Instantiate {
            code_id: msg.dp_code_id,
            send: vec![],
            label: None,
            msg: to_binary(&Cw20InitMsg {
                name: format!("Deposit Token - {}", msg.pool_name),
                symbol: "PylonDP".to_string(),
                decimals: 6u8,
                initial_balances: vec![],
                mint: Some(MinterResponse {
                    minter: env.contract.address.clone(),
                    cap: None,
                }),
                init_hook: Some(Cw20InitHook {
                    contract_addr: env.contract.address,
                    msg: to_binary(&HandleMsg::RegisterDPToken {})?,
                }),
            })?,
        })],
        log: vec![],
    })
}
```

Initializes a new pool contract. Updates data storage as defined with `config.rs`, and initializes a new DP token contract linked to this pool contract.

```rust
pub fn handle<S: Storage, A: Api, Q: Querier>(
    deps: &mut Extern<S, A, Q>,
    env: Env,
    msg: HandleMsg,
) -> StdResult<HandleResponse> {
    match msg {
        HandleMsg::Receive(msg) => CoreHandler::receive(deps, env, msg),
        HandleMsg::Deposit {} => CoreHandler::deposit(deps, env),
        HandleMsg::ClaimReward {} => CoreHandler::claim_reward(deps, env),
        HandleMsg::RegisterDPToken {} => CoreHandler::register_dp_token(deps, env),
    }
}

```

Defines `HandleMsg` endpoints. Calls the following functions per `HandleMsg`:

* `Receive(msg)` : calls `receive(deps, env, msg)` defined under `handler_exec.rs`.
* `Deposit {}` : calls `deposit(deps, env)` defined under `handler_exec.rs`.
* `ClaimReward {}` : calls `claim_reward(deps, env)` defined under `handler_exec.rs`.
* **\[INTERNAL]** `RegisterDPToken {}` : calls `register_dp_token(deps, env)` defined under `handler_exec.rs`.

```rust
pub fn query<S: Storage, A: Api, Q: Querier>(
    deps: &Extern<S, A, Q>,
    msg: QueryMsg,
) -> StdResult<Binary> {
    match msg {
        QueryMsg::DepositAmountOf { owner } => QueryHandler::deposit_amount(deps, owner), // dp_token.balanceOf(msg.sender)
        QueryMsg::TotalDepositAmount {} => QueryHandler::total_deposit_amount(deps), // dp_token.totalSupply()
        QueryMsg::Config {} => QueryHandler::config(deps),                           // config
        QueryMsg::ClaimableReward {} => QueryHandler::claimable_reward(deps), // config.strategy.reward()
    }
}

```

Defines `QueryMsg` endpoints. Calls the following functions per `QueryMsg`:

* `DepositAmountOf { owner }` : calls `deposit_amount(deps, owner)` defined under `handler_query.rs`; returns the current DP token balance of the sender of this message.
* `TotalDepositAmount {}` : calls `total_deposit_amount(deps)` defined under `handler_query.rs`; returns the total DP token balanced linked to this pool contract.
* `Config {}` : calls `config(deps)` defined under `handler/query.rs`; returns the following:
  * `beneficiary`: returns the current beneficiary address set for this pool contract.
  * `moneymarket`: returns the Anchor money market contract set for this pool contract to call for `deposit_stable` and `redeem_stable` messages. For further information regarding logic of the Anchor money market, please refer to Anchor Protocol's official documentation.
  * `stable_denom`: returns the current Terra stablecoin denomination that the underlying Anchor money market contract accepts.
  * `anchor_token`: returns the aToken contract address that the underlying Anchor money market contract returns on deposits.
  * `dp_token`: returns the DP token contract address minted by this pool contract on new deposits.
* `GetClaimableReward {}` : calls `claimable_reward(deps)` defined under `handler_query.rs`; returns all claimable UST rewards for all UST deposits held by this pool.

### **`handler/core.rs`**

Defines core contract execution logic. Functions are as follows:

* `receive`: defines a CW-20 token contract **receive hook**, which is executed when a Pylon DP token is sent to this Pylon pool.
* `deposit`: deposits UST to this Pylon pool, deposits them to Anchor, and mints Pylon DP tokens back to the depositor.
* `redeem`: consecutively called on a CW-20 `receive` call. Burns received DP tokens, retrieves equivalent amounts of UST from Anchor, and returns principal UST deposits excluding any interest generated.
* `claim_reward`: claims any remaining interest remaining in the pool, and sends them over to the beneficiary address. Interest is calculated as `(total_aust_amount * exchange_rate) - (total_dp_balance)`
* `register_dp_token`: registers a DP token contract controlled by this Pylon deposit pool for new DP token mints/burns on deposits/redemptions.

```rust
pub fn receive<S: Storage, A: Api, Q: Querier>(
    deps: &Extern<S, A, Q>,
    env: Env,
    cw20_msg: Cw20ReceiveMsg,
) -> StdResult<HandleResponse> {
    let sender = env.message.sender.clone();
    if let Some(msg) = cw20_msg.msg {
        match from_binary(&msg)? {
            Cw20HookMsg::Redeem {} => {
                // only asset contract can execute this message
                let config: config::Config = config::read(&deps.storage)?;
                if deps.api.canonical_address(&sender)? != config.dp_token {
                    return Err(StdError::unauthorized());
                }

                redeem(deps, env, cw20_msg.sender, cw20_msg.amount)
            }
        }
    } else {
        Err(StdError::generic_err(
            "Invalid request: \"redeem\" message not included in request",
        ))
    }
}

```

If a CW-20 transfer to this contract includes a `Redeem {}` `Cw20HookMsg`:

* checks if the sender of this `HookMsg` is the registered DP token address (i.e. not any other token contract address being sent to this pool) - return `unauthorized()` error if not, else continue
* if passed, call `redeem(deps, _env, cw20_msg.sender, cw20_msg.amount)`

If a `Redeem {}` message is not included with this function call, return an `invalid_request` error.

```rust
pub fn deposit<S: Storage, A: Api, Q: Querier>(
    deps: &Extern<S, A, Q>,
    env: Env,
) -> StdResult<HandleResponse> {
    let config = config::read(&deps.storage)?;

    // check deposit
    let received: Uint256 = env
        .message
        .sent_funds
        .iter()
        .find(|c| c.denom == config.stable_denom)
        .map(|c| Uint256::from(c.amount))
        .unwrap_or_else(Uint256::zero);

    if received.is_zero() {
        return Err(StdError::generic_err(format!(
            "Pool: insufficient token amount {}",
            config.stable_denom,
        )));
    }

    let deposit_amount = deduct_tax(
        deps,
        Coin {
            denom: config.stable_denom.clone(),
            amount: received.into(),
        },
    )?
    .amount;

    Ok(HandleResponse {
        messages: [
            querier::feeder::update_msg(deps, &config.exchange_rate_feeder, &config.dp_token)?,
            querier::anchor::deposit_stable_msg(
                deps,
                &config.moneymarket,
                &config.stable_denom,
                deposit_amount,
            )?,
            vec![CosmosMsg::Wasm(WasmMsg::Execute {
                contract_addr: deps.api.human_address(&config.dp_token)?,
                msg: to_binary(&Cw20HandleMsg::Mint {
                    recipient: env.message.sender.clone(),
                    amount: deposit_amount,
                })?,
                send: vec![],
            })],
        ]
        .concat(),
        log: vec![
            log("action", "deposit"),
            log("sender", env.message.sender),
            log("amount", deposit_amount.to_string()),
        ],
        data: None,
    })
}

```

Sending native Terra stablecoins (UST) with this `MsgExecuteContract` call:

* Check how much deposits have been made to this pool contract for `stable_denom`.
  * If there are no deposits, return a `generic_err`.
* Issue a `HandleResponse` issuing the following messages:
  * call `deposit_stable` from the Anchor money market contract for `deposit_amount` units of `stable_denom`(e.g. 100 UST). aUST will be returned from the Anchor money market contract to this pool contract.
  * issue another `MsgExecuteContract` call that mints `deposit_amount` units of Pylon DP tokens for this particular pool to the caller.

```rust
pub fn redeem<S: Storage, A: Api, Q: Querier>(
    deps: &Extern<S, A, Q>,
    env: Env,
    sender: HumanAddr,
    amount: Uint128,
) -> StdResult<HandleResponse> {
    let config = config::read(&deps.storage)?;

    let (market_redeem_amount, pool_redeem_amount, _) =
        querier::pool::calculate_return_amount(deps, &config, Uint256::from(amount))?;

    Ok(HandleResponse {
        messages: [
            querier::feeder::update_msg(deps, &config.exchange_rate_feeder, &config.dp_token)?,
            vec![CosmosMsg::Wasm(WasmMsg::Execute {
                contract_addr: deps.api.human_address(&config.dp_token)?,
                msg: to_binary(&Cw20HandleMsg::Burn { amount })?,
                send: vec![],
            })],
            querier::anchor::redeem_stable_msg(
                deps,
                &config.moneymarket,
                &config.atoken,
                market_redeem_amount.into(),
            )?,
            vec![CosmosMsg::Bank(BankMsg::Send {
                from_address: env.contract.address,
                to_address: sender,
                amount: vec![pool_redeem_amount.clone()],
            })],
        ]
        .concat(),
        log: vec![
            log("action", "redeem"),
            log("sender", env.message.sender),
            log("amount", pool_redeem_amount.amount),
        ],
        data: None,
    })
}

```

When a `Redeem {}` `Cw20HookMsg` is called:

* Query the current `epoch_state` from the Anchor money market.
* Calculate how much aUST needs to be redeemed back to UST to maintain principle: `dp_token_balance / epoch_state.exchange_rate`
* Calculate how much Terra tax is charged during redemptions. As tax is charged for every Terra stablecoin `MsgSend`s on the Terra blockchain, `deduct_tax` should be called twice, as there are two cases when Terra tax is charged for UST transfers during redemptions:
  * when UST is transferred from the Anchor money market to this Pylon pool contract
  * when UST is transferred from this Pylon pool contract to the user's wallet
* Issue a `HandleResponse` containing the following messages:
  * burn `amount` units of DP tokens for this Pylon pool.
  * redeem `market_redeem_amount` aUST (calculated as `dp_token_balance / epoch_state.exchange_rate`) for `pool_redeem_amount` UST.
  * `MsgSend`s `pool_redeem_amount` back to the caller of this contract

```rust
pub fn claim_reward<S: Storage, A: Api, Q: Querier>(
    deps: &Extern<S, A, Q>,
    env: Env,
) -> StdResult<HandleResponse> {
    // calculate (total_aust_amount * exchange_rate) - (total_dp_balance)
    let config = config::read(&deps.storage)?;
    if config.beneficiary != deps.api.canonical_address(&env.message.sender)? {
        return Err(StdError::unauthorized());
    }

    let (reward_amount, fee_amount) =
        querier::pool::calculate_reward_amount(deps, &config, Option::from(env.block.time))?;
    let (market_redeem_amount, _, _) =
        querier::pool::calculate_return_amount(deps, &config, reward_amount.add(fee_amount))?;
    let (_, beneficiary_redeem_amount, _) =
        querier::pool::calculate_return_amount(deps, &config, reward_amount)?;
    let (_, collector_redeem_amount, _) =
        querier::pool::calculate_return_amount(deps, &config, fee_amount)?;

    Ok(HandleResponse {
        messages: [
            querier::feeder::update_msg(deps, &config.exchange_rate_feeder, &config.dp_token)?,
            querier::anchor::redeem_stable_msg(
                deps,
                &config.moneymarket,
                &config.atoken,
                market_redeem_amount.into(),
            )?,
            vec![
                CosmosMsg::Bank(BankMsg::Send {
                    from_address: env.contract.address.clone(),
                    to_address: deps.api.human_address(&config.beneficiary)?,
                    amount: vec![beneficiary_redeem_amount.clone()],
                }),
                CosmosMsg::Bank(BankMsg::Send {
                    from_address: env.contract.address.clone(),
                    to_address: deps.api.human_address(&config.fee_collector)?,
                    amount: vec![collector_redeem_amount.clone()],
                }),
            ],
        ]
        .concat(),
        log: vec![
            log("action", "claim_reward"),
            log("sender", env.message.sender),
            log("amount", beneficiary_redeem_amount.amount),
            log("fee", collector_redeem_amount.amount),
        ],
        data: None,
    })
}

```

On a `ClaimReward {}` `HandleMsg` call:

* calculate how much aUST should be redeemed: `(total_aust_amount * exchange_rate) - (total_dp_balance)`
* apply a **virtual exchange rate** queryable from the **Pylon** **Exchange Rate contract**. This effectively re-calculates how much UST should be claimed **excluding MINE token buybacks**, which is sent to the **Collector** contract.
* calculates how much UST should be redeemed for:
  * `market_redeem_amount` : amount of aUST for redemptions **before** Terra blockchain tax for both `beneficiary` and `collector`. returns `Uint256`.
  * `beneficiary_redeem_amount` : amount of aUST for redemptions **after** Terra blockchain tax for `beneficiary`. returns a `Coin` object.
  * `collector_redeem_amount` : amount of aUST for redemptions **after** Terra blockchain tax for `collector`, sent to the **Collector** contract for buybacks. returns a `Coin` object.
* Issue a `HandleResponse` that includes the following messages:
  * update **virtual exchange rate**
  * redeem `market_redeem_amount` aUST from Anchor
  * send `beneficiary_redeem_amount` to beneficiary account
  * send `collector_redeem_amount` to **Collector contract**


# Exchange Rate

**Deployed at:** [**`terra1zvsv534gx7xppq4yfstslmsgc3jmkfak4mlrv4`**](https://finder.terra.money/columbus-4/address/terra1zvsv534gx7xppq4yfstslmsgc3jmkfak4mlrv4)

### **`state.rs`**

Stores all relevant contract parameters.

```rust
pub struct Config {
    pub owner: HumanAddr,
}

```

`owner`: the owner address of this contract.

```rust
pub struct Token {
    pub status: Status,
    pub exchange_rate: Decimal256,
    pub epoch_period: u64,
    pub weight: Decimal256,
    pub last_updated_at: u64,
}

```

`status`: virtual exchange rate enforcement status - `Neutral`, `Running`, or `Stopped`

* `Neutral`: logic not yet initialized, throws an error when queried
* `Running`: exchange rate calculations valid, returns current `exchange_rate` when queried & executes update
* `Stopped`: exchange rate no longer updating, returns a constant value when queried

`exchange_rate`: current virtual exchange rate for this pool

`epoch_period`: minimum time gap between `update()` calls.

### **`contract.rs`**

Defines logic entry points for `InitMsg`, `HandleMsg` and `QueryMsg` calls.

```rust
pub fn init<S: Storage, A: Api, Q: Querier>(
    deps: &mut Extern<S, A, Q>,
    env: Env,
    _: InitMsg,
) -> StdResult<InitResponse> {
    state::store_config(
        &mut deps.storage,
        &state::Config {
            owner: env.message.sender,
        },
    )?;

    Ok(InitResponse::default())
}

```

Initializes a new Exchange Rate contract.

```rust
pub fn handle<S: Storage, A: Api, Q: Querier>(
    deps: &mut Extern<S, A, Q>,
    env: Env,
    msg: HandleMsg,
) -> StdResult<HandleResponse> {
    match msg {
        HandleMsg::Update { token } => Ok(ExecHandler::update(deps, env, token)?),
        HandleMsg::ConfigToken {
            token,
            exchange_rate,
            epoch_period,
            weight,
        } => Ok(ExecHandler::config_token(
            deps,
            env,
            token,
            exchange_rate,
            epoch_period,
            weight,
        )?),
        HandleMsg::AddToken {
            token,
            base_rate,
            period,
            weight,
        } => Ok(ExecHandler::add_token(
            deps, env, token, base_rate, period, weight,
        )?),
        HandleMsg::Start { tokens } => Ok(ExecHandler::start(deps, env, tokens)?),
        HandleMsg::Stop { tokens } => Ok(ExecHandler::stop(deps, env, tokens)?),
    }
}

```

Defines `HandleMsg` endpoints. Calls the following functions per `HandleMsg`:

`Update { token }` : calls `update(deps, env, token)` defined under `handler_exec.rs`.

`ConfigToken { token, exchange_rate, epoch_period, weight, }` : calls `config_token(deps, env, token, exchange_rate, epoch_period, weight, )` defined under `handler_exec.rs`.

`AddToken { token, base_rate, period, weight, }` : calls `add_token(deps, env, token, base_rate, period, weight, )` defined under `handler_exec.rs`.

`Start { tokens }` : calls `start(deps, env, tokens)` defined under `handler_exec.rs`.

`Stop { tokens }` : calls `stop(deps, env, tokens)` defined under `handler_exec.rs`.

```rust
pub fn query<S: Storage, A: Api, Q: Querier>(
    deps: &Extern<S, A, Q>,
    msg: QueryMsg,
) -> StdResult<Binary> {
    match msg {
        QueryMsg::ExchangeRateOf { token, blocktime } => {
            Ok(QueryHandler::exchange_rate_of(deps, &token, blocktime)?)
        }
    }
}

```

Defines `QueryMsg` endpoints. Calls the following functions per `QueryMsg`:

`ExchangeRateOf { token, blocktime }` : calls `exchange_rate_of(deps, &token, blocktime)` defined under `handler_query.rs`; Queries the current `exchange_rate` for `token`.

### **`handler_exec.rs`**

Defines core contract execution logic. Functions are as follows:

`update`: recalculates the current virtual exchange rate for `token`.

`config_token`: updates target `token` profile for calculating virtual exchange rate.

`add_token`: adds a new target `token` profile for calculating virtual exchange rate.

`start`: enables virtual exchange rate calculation.

`stop`: disables virtual exchange rate calculation.

```rust
pub fn update<S: Storage, A: Api, Q: Querier>(
    deps: &mut Extern<S, A, Q>,
    env: Env,
    token: HumanAddr,
) -> StdResult<HandleResponse> {
    let token_addr: CanonicalAddr = deps.api.canonical_address(&token)?;

    let mut token: state::Token = state::read_token(&deps.storage, &token_addr)?;
    if token.status.ne(&state::Status::Running) {
        return Err(StdError::unauthorized());
    }

    let elapsed = env.block.time.sub(token.last_updated_at);
    if elapsed < token.epoch_period {
        return Ok(HandleResponse::default());
    }

    let exchange_rate_before = token.exchange_rate;
    let pow_count = elapsed.div(token.epoch_period);
    for _ in 0..pow_count {
        token.exchange_rate = token.exchange_rate.mul(token.weight);
    }

    token.last_updated_at = env.block.time;

    state::store_token(&mut deps.storage, &token_addr, &token)?;

    Ok(HandleResponse {
        messages: vec![],
        log: vec![
            log("action", "update"),
            log("sender", env.message.sender),
            log("er_before", exchange_rate_before),
            log("er_after", token.exchange_rate),
        ],
        data: None,
    })
}

```

Recalculates virtual exchange rate for a particular `token`.

`exchange_rate` is calculated as:

* count how many epochs have elapsed since `last_updated_at`
  * do nothing if at least one epoch has not passed
* `exchange_rate = exchange_rate * weight ^ epochs_passed`

```rust
pub fn config_token<S: Storage, A: Api, Q: Querier>(
    deps: &mut Extern<S, A, Q>,
    env: Env,
    token: HumanAddr,
    exchange_rate: Option<Decimal256>,
    epoch_period: Option<u64>,
    weight: Option<Decimal256>,
) -> StdResult<HandleResponse> {
    check_owner(deps, &env.message.sender)?;

    let token_addr: CanonicalAddr = deps.api.canonical_address(&token)?;
    let mut token: state::Token = state::read_token(&deps.storage, &token_addr)?;

    if let Some(er) = exchange_rate {
        if token.exchange_rate.gt(&er) {
            return Err(StdError::unauthorized());
        }
        token.exchange_rate = er;
    }
    if let Some(ep) = epoch_period {
        token.epoch_period = ep;
    }
    if let Some(w) = weight {
        token.weight = w;
    }

    state::store_token(&mut deps.storage, &token_addr, &token)?;

    Ok(HandleResponse::default())
}

```

Updates virtual exchange rate parameters for `token`. Accepts:

* `token`: address of the target token subject to exchange rate updates.
* `exchange_rate`: initial exchange rate parameter to be used as a baseline. should be reset on significant deviation.
* `epoch_period`: time length of a single epoch used for `update` calls.
* `weight`: exchange rate delta enforced per `epoch`.

```rust
pub fn add_token<S: Storage, A: Api, Q: Querier>(
    deps: &mut Extern<S, A, Q>,
    env: Env,
    token: HumanAddr,
    base_rate: Decimal256,
    period: u64,
    weight: Decimal256,
) -> StdResult<HandleResponse> {
    check_owner(deps, &env.message.sender)?;

    let token_addr: CanonicalAddr = deps.api.canonical_address(&token)?;

    state::store_token(
        &mut deps.storage,
        &token_addr,
        &state::Token {
            exchange_rate: base_rate,
            epoch_period: period,
            status: state::Status::Neutral,
            weight,
            last_updated_at: env.block.time,
        },
    )?;

    Ok(HandleResponse::default())
}
```

Adds a new `token` target profile for calculating `exchange_rate`. Accepts:

* `token`: address of the target token subject to exchange rate updates.
* `exchange_rate`: initial exchange rate parameter to be used as a baseline. should be reset on significant deviation.
* `epoch_period`: time length of a single epoch used for `update` calls.
* `weight`: exchange rate delta enforced per `epoch`.

```rust
pub fn start<S: Storage, A: Api, Q: Querier>(
    deps: &mut Extern<S, A, Q>,
    env: Env,
    tokens: Vec<HumanAddr>,
) -> StdResult<HandleResponse> {
    check_owner(deps, &env.message.sender)?;
    for token in tokens {
        _start(deps, &token, &env.block.time)?;
    }
    Ok(HandleResponse::default())
}

fn _start<S: Storage, A: Api, Q: Querier>(
    deps: &mut Extern<S, A, Q>,
    token: &HumanAddr,
    block_time: &u64,
) -> StdResult<()> {
    let token_addr: CanonicalAddr = deps.api.canonical_address(&token)?;
    let mut token: state::Token = state::read_token(&deps.storage, &token_addr)?;

    token.status = state::Status::Running;
    token.last_updated_at = *block_time;

    Ok(())
}

```

Changes `token.status` to `Running` for all tokens registered with the Exchange Rate contract.

```rust
pub fn stop<S: Storage, A: Api, Q: Querier>(
    deps: &mut Extern<S, A, Q>,
    env: Env,
    tokens: Vec<HumanAddr>,
) -> StdResult<HandleResponse> {
    check_owner(deps, &env.message.sender)?;
    for token in tokens {
        _stop(deps, token)?;
    }

    Ok(HandleResponse {
        messages: vec![],
        log: vec![log("action", "stop"), log("sender", env.message.sender)],
        data: None,
    })
}

fn _stop<S: Storage, A: Api, Q: Querier>(
    deps: &mut Extern<S, A, Q>,
    token: HumanAddr,
) -> StdResult<()> {
    let token_addr: CanonicalAddr = deps.api.canonical_address(&token)?;
    let mut token: state::Token = state::read_token(&deps.storage, &token_addr)?;

    token.status = state::Status::Stopped;

    Ok(())
}

```

Changes `token.status` to `Stopped` for all tokens registered with the Exchange Rate contract.


# Launchpad

`pylon-protocol/launchpad` contracts define launchpad logic used for Pylon Investment Pools and Pylon Swap.

* `pylon-protocol/launchpad/lockup` contracts wrap around `pylon-protocol/core/pool` contracts, by accepting UST but locking DP tokens released within the lockup contract until a pre-set expiry period has passsed. This only allows depositors to claim back their deposits after the given lockup period.
* `pylon-protocol/launchpad/swap` contracts define a virtual AMM, of which:
  * all UST entering this pool is locked within this contract, and returns PROJECT tokens at a fixed ratio after minimum lockup period have passed.
  * **if traders try to reclaim UST before the lockup period**:
    * define `max_swappable`
    * define a virtual Uniswap-like AMM mechanism, whereby:
      * liquidity given equals `max_swappable`. for instance, if `max_swappable` is given as 5M, there exists a 5M UST - 5M PROJECT virtual AMM pool.
    * any PROJECT accepted by the swap pool is burned, but internal accounting logic treats them as a swap rather than a burn. For example:
      * Alice wants to swap her 1M vested PROJECT back to UST. Assuming that no one else have swapped beforehand, this will result in:
        * a virtual balance increase from 5M PROJECT to 6M, and an effective balance decrease of 1M PROJECT.
        * approximately 0.83M UST is returned to Alice instead of the initial 1M deposited (calculated as: `5M - { 5M UST * 5M PROJECT / (5M + 1M) PROJECT }` UST ), resulting in a 0.17M UST loss in total for Alice.
        * virtual AMM state is updated to: 4.17 UST - 6M PROJECT
      * If Bob were to swap another 1M vested PROJECT back to UST, Bob would receive 0.6M UST, resulting in a 0.4M UST loss in total for Bob.

{% hint style="info" %}
Pylon Swap is designed to exponentially decrease PROJECT token prices as more traders reverse-swap, exponentially penalizing traders attempting to withdraw before lockup period expiry.
{% endhint %}

{% hint style="danger" %}
All tokens reverse-swapped on Pylon Swap will be **permanently burned**.&#x20;
{% endhint %}


# Lockup

### **`state.rs`** <a href="#state-rs" id="state-rs"></a>

Stores all relevant contract parameters.

```rust
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]

pub struct Config {
    pub owner: CanonicalAddr,
    pub share_token: CanonicalAddr,
    pub reward_token: CanonicalAddr,
    pub start_time: u64,    
    pub cliff_time: u64,    
    pub finish_time: u64,    
    pub reward_rate: Decimal256,
}​
```

`owner`: the owner address of this contract.

`share_token`: address of the DP token contract used by this lockup pool.

`reward_token`: token contract address of the token emitted by this pool after a minimum lockup period has passed.

`start_time`: timestamp of which lockup logic will be valid from.

`cliff_time`: timestamp of which `reward_token` distribution logic will be valid from.

`finish_time`: timestamp of which lockup logic will expire

`reward_rate`: defines at which rate `reward_token` will be given out to `lockup` contract depositors

```rust
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]

pub struct Reward {
    pub total_deposit: Uint256,    
    pub last_update_time: u64,    
    pub reward_per_token_stored: Decimal256,
}​
```

`total_deposit`: total principal tokens deposited.

`last_update_time`: last reward tokens distribution timestamp.

`reward_per_token_stored`: number of reward tokens to be sent out per deposit token (DP tokens).

```rust
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]

pub struct User {
    pub amount: Uint256,    
    pub reward: Uint256,    
    pub reward_per_token_paid: Decimal256,
}​
```

`amount`: the number of DP tokens a user has deposited.

`reward`: the number of reward tokens distributed.

`reward_per_token_paid`: the number of reward tokens already paid per token.


