Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add rwa issuance #1357

Merged
merged 21 commits into from
Jun 19, 2024
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,15 @@ Open [http://localhost:3000](http://localhost:3000) with your browser to see the
- Add that token object to [tokenslist](src/constants/tokenlists.ts)
- If the token is only available for either Swap or FlashMint, add an entry to `isAvailableForFlashMint` or `isAvailableForSwap` in [token utils](src/lib/utils/tokens.ts). Write a test too!

## New Presale

- Make sure the token data was added to [tokenlists](https://github.com/IndexCoop/tokenlists)
- Add logo in [assets](public/assets) - as defined in tokenlists
- Update tokenlists dependency
- Add token in [tokens.ts](src/constants/tokens.ts)
- Add presale config in [src/app/presales/constants.ts](src/app/presales/constants.ts) and update `getTokenForPresaleToken`
- Test locally w/ hardhat

## Testing

### Unit tests
Expand Down
12 changes: 9 additions & 3 deletions hardhat.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,20 @@ module.exports = {
},
}

task('accounts', 'prints the list of accounts', async (taskArgs, hre) => {
task('accounts', 'prints the list of accounts', async (_, hre) => {
console.log(hre.ethers)
console.log('network:', hre.network.name)
// format: [token, whale]
// format: [token, whale, amount]
const tokens = [
[
'0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // USDC
'0xda9ce944a37d218c3302f6b82a094844c6eceb17',
'1000000000',
],
[
'0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0', // wstETH
'0x5ef0f3C15b2371E7355f5b6594F706aB7417655e',
'1000000000000000000',
],
]
const account = process.env.HARDHAT_FUNDING_ACCOUNT
Expand All @@ -34,7 +40,7 @@ task('accounts', 'prints the list of accounts', async (taskArgs, hre) => {
transferFromWhale(
token[1],
account,
'1000000000',
token[2],
token[0],
hre.ethers.provider,
),
Expand Down
34 changes: 27 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"@heroicons/react": "^2.1.3",
"@indexcoop/analytics-sdk": "0.17.0",
"@indexcoop/flash-mint-sdk": "3.1.0",
"@indexcoop/tokenlists": "1.44.0",
"@indexcoop/tokenlists": "1.46.0",
"@rainbow-me/rainbowkit": "^2.0.7",
"@sentry/nextjs": "8.8.0",
"@tanstack/react-query": "5.36.2",
Expand Down
8 changes: 4 additions & 4 deletions src/app/presales/components/faq-section/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,11 @@ export function FaqSection() {
</FaqItem>
<FaqItem question='How high are my rewards?'>
<p>
There is a fixed supply of 10,000 PRTs for all products with PRTs. The
There is a fixed supply of PRTs for all products with PRTs. The
presale will show how many PRTs will be distributed in the event of a
success, meeting the threshold by the deadline. For example, if 3,000
PRTs are distributed in the presale, 30% are allocated for presale
depositors.
success, meeting the threshold by the deadline. For example, if a
product has a supply of 10,000 PRTs and 3,000 PRTs are distributed in
the presale, 30% are allocated for presale depositors.
</p>
<p>
Each presale will have a distribution curve for PRTs, and the
Expand Down
6 changes: 3 additions & 3 deletions src/app/presales/components/popup/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { Modal, ModalBody, ModalContent, ModalOverlay } from '@chakra-ui/react'

import { HighYieldETHIndex } from '@/constants/tokens'

import { getTokenForPresaleToken } from '../../constants'
import { DepositProvider } from '../../providers/deposit-provider'
import { PreSaleToken } from '../../types'
import { PreSaleTokenCard } from '../pre-sale-token-card'
Expand All @@ -15,12 +14,13 @@ type PreSalePopupProps = {

export const PreSalePopup = (props: PreSalePopupProps) => {
const { isOpen, onClose, token } = props
const preSaleToken = getTokenForPresaleToken(token)
return (
<Modal onClose={onClose} isOpen={isOpen} isCentered>
<ModalOverlay className='bg-ic-black bg-opacity-60 backdrop-blur' />
<ModalContent className='h-[500px] max-w-4xl bg-transparent shadow-none'>
<ModalBody className='dark m-0 bg-transparent p-0'>
<DepositProvider preSaleToken={HighYieldETHIndex}>
<DepositProvider preSaleToken={preSaleToken}>
<div className='flex h-full'>
<div className='align-center max-h-4xl mx-auto my-auto flex max-w-4xl flex-row items-start gap-3'>
{token && (
Expand Down
20 changes: 20 additions & 0 deletions src/app/presales/components/pre-sale-section/disclaimer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import Link from 'next/link'

export function Disclaimer() {
return (
<p className='text-ic-gray-400 mt-4 text-[10px] font-medium leading-5'>
*Product-specific PRT staking will be made available in the Index Coop
app; staking will not be available to Restricted Persons (including US
Persons) as defined{' '}
<Link
className='underline'
href='https://indexcoop.com/tokens-restricted-for-restricted-persons'
target='_blank'
>
here
</Link>
. More information on PRT distribution and staking will be published when
a successful presale product is formally launched.
</p>
)
}
33 changes: 14 additions & 19 deletions src/app/presales/components/pre-sale-section/index.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,30 @@
'use client'

import { useDisclosure } from '@chakra-ui/react'
import Link from 'next/link'
import { useRouter } from 'next/navigation'
import { useState } from 'react'

import { preSaleTokens } from '../../constants'
import { PreSaleStatus } from '../../types'
import { PreSaleStatus, PreSaleToken } from '../../types'
import { PreSalePopup } from '../popup'
import { PreSaleTokenCard } from '../pre-sale-token-card'

import { Disclaimer } from './disclaimer'

export function PreSaleSection() {
const [presaleToken, setPresaleToken] = useState<PreSaleToken>(
preSaleTokens[1],
janndriessen marked this conversation as resolved.
Show resolved Hide resolved
)
const {
isOpen: isPreSalePopupOpen,
onOpen: onOpenPreSalePopup,
onClose: onClosePreSalePopup,
} = useDisclosure()
const router = useRouter()

const openPopup = (token: PreSaleToken) => {
setPresaleToken(token)
onOpenPreSalePopup()
}
return (
<div className='py-10'>
<div className='grid grid-cols-1 gap-6 md:grid-cols-2'>
Expand All @@ -28,28 +36,15 @@ export function PreSaleSection() {
if (preSaleToken.status === PreSaleStatus.TOKEN_LAUNCHED) {
router.push(`/swap/eth/${preSaleToken.symbol}`)
} else {
onOpenPreSalePopup()
openPopup(preSaleToken)
}
}}
/>
))}
</div>
<p className='text-ic-gray-400 mt-4 text-[10px] font-medium leading-5'>
*Product-specific PRT staking will be made available in the Index Coop
app; staking will not be available to Restricted Persons (including US
Persons) as defined{' '}
<Link
className='underline'
href='https://indexcoop.com/tokens-restricted-for-restricted-persons'
target='_blank'
>
here
</Link>
. More information on PRT distribution and staking will be published
when a successful presale product is formally launched.
</p>
<Disclaimer />
<PreSalePopup
token={preSaleTokens[0]}
token={presaleToken}
isOpen={isPreSalePopupOpen}
onClose={onClosePreSalePopup}
/>
Expand Down
2 changes: 1 addition & 1 deletion src/app/presales/components/pre-sale-widget/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ export function PreSaleWidget({ token }: { token: PreSaleToken }) {
<WarningComp
warning={{
title: 'PRT eligibility',
node: "Deposits to the contract must be maintained until the end of the post-launch period (60 days after presale closes) in order to maintain PRT eligibility. Once a presale has ended, you can still deposit into a token but there won't be any PRT rewards for doing so.",
node: "Deposits to the contract must be maintained until the end of the post-launch period (140 days after presale closes) in order to maintain PRT eligibility. Once a presale has ended, you can still deposit into a token but there won't be any PRT rewards for doing so.",
}}
/>
{transactionReview && (
Expand Down
37 changes: 26 additions & 11 deletions src/app/presales/constants.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,24 @@
import { HighYieldETHIndex } from '@/constants/tokens'
import {
HighYieldETHIndex,
RealWorldAssetIndex,
Token,
} from '@/constants/tokens'

import { PreSaleStatus, PreSaleToken } from './types'

export const preSaleTokens: PreSaleToken[] = [
{
status: PreSaleStatus.ACTIVE,
symbol: RealWorldAssetIndex.symbol,
logo: RealWorldAssetIndex.image,
description:
'The Fortunafi Real World Assets Index (RWA) allows token holders to gain diversified exposure to projects and protocols that concentrate on tokenizing offchain assets.',
componentsFrom: ['MKR', 'ONDO', 'ENA', 'CFG', 'CANTO', 'MPL'],
infoLink: 'https://indexcoop.com/blog/previewing-rwa-index-presale',
prtRewards: '10,000 / 100,000',
targetFundraise: 500,
timestampEndDate: 1724068800000,
},
{
status: PreSaleStatus.TOKEN_LAUNCHED,
symbol: HighYieldETHIndex.symbol,
Expand All @@ -17,18 +33,17 @@ export const preSaleTokens: PreSaleToken[] = [
launchDate: 'August 19th, 2024',
timestampEndDate: 1715356800000,
},
{
status: PreSaleStatus.NOT_STARTED,
symbol: 'RWA',
description:
'The Fortunafi Real World Assets Index (RWA) allows token holders to gain diversified exposure to projects and protocols that concentrate on tokenizing offchain assets.',
componentsFrom: ['MKR', 'ONDO', 'ENA', 'CFG', 'CANTO', 'MPL'],
prtRewards: '10,000 / 100,000',
targetFundraise: 500,
timestampEndDate: 1724068800000,
},
]

export function getTokenForPresaleToken(
presaleToken: PreSaleToken | null,
): Token {
if (presaleToken?.symbol === RealWorldAssetIndex.symbol) {
return RealWorldAssetIndex
}
return HighYieldETHIndex
}

export const presaleChipLabels = {
[PreSaleStatus.ACTIVE]: 'Presale active',
[PreSaleStatus.CLOSED_TARGET_MET]: 'Presale closed, target met',
Expand Down
Loading