Skip to content

Commit

Permalink
Merge pull request #45 from IndexCoop/feat/add-eth2x
Browse files Browse the repository at this point in the history
feat: add eth2x
  • Loading branch information
janndriessen authored Mar 13, 2024
2 parents 0e37a60 + 2c88057 commit 23f6832
Show file tree
Hide file tree
Showing 12 changed files with 202 additions and 55 deletions.
6 changes: 4 additions & 2 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,19 @@ jobs:
node-version: [18.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- run: npm ci
- run: npm run lint
- run: npm run build --if-present
- run: npm run hardhat & npm run test:btc2x
- run: npm run hardhat & npm run test:cdeti
- run: npm run hardhat & npm run test:dseth
- run: npm run hardhat & npm run test:eth2x
- run: npm run hardhat & npm run test:gtceth
- run: npm run hardhat & npm run test:iceth
# - run: npm run hardhat & npm run test:icreth
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@
"lint": "prettier -c . && eslint ./src",
"lint:fix": "prettier -w . && eslint ./src --fix",
"test": "jest",
"test:btc2x": "npm test src/tests/btc2x.test.ts",
"test:cdeti": "npm test src/tests/cdeti",
"test:dseth": "npm test src/tests/dseth",
"test:eth2x": "npm test src/tests/eth2x.test.ts",
"test:eth2xfli": "npm test src/tests/eth2xfli",
"test:gtceth": "npm test src/tests/gtceth",
"test:iceth": "npm test src/tests/iceth",
Expand Down
10 changes: 10 additions & 0 deletions src/constants/tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,16 @@ export const GitcoinStakedETHIndex: Token = {
symbol: 'gtcETH',
}

export const IndexCoopBitcoin2xIndex: Token = {
address: '0xD2AC55cA3Bbd2Dd1e9936eC640dCb4b745fDe759',
symbol: 'BTC2X',
}

export const IndexCoopEthereum2xIndex: Token = {
address: '0x65c4C0517025Ec0843C9146aF266A2C5a2D148A2',
symbol: 'ETH2X',
}

export const InterestCompoundingETHIndex: Token = {
symbol: 'icETH',
address: '0x7C07F7aBe10CE8e33DC6C5aD68FE033085256A84',
Expand Down
4 changes: 4 additions & 0 deletions src/quote/indexQuoteProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import {
DiversifiedStakedETHIndex,
ETH2xFlexibleLeverageIndex,
GitcoinStakedETHIndex,
IndexCoopBitcoin2xIndex,
IndexCoopEthereum2xIndex,
InterestCompoundingETHIndex,
LeveragedrEthStakingYield,
MetaverseIndex,
Expand Down Expand Up @@ -177,6 +179,8 @@ function getContractType(token: string): FlashMintContractType | null {
if (
token === BTC2xFlexibleLeverageIndex.symbol ||
token === ETH2xFlexibleLeverageIndex.symbol ||
token === IndexCoopBitcoin2xIndex.symbol ||
token === IndexCoopEthereum2xIndex.symbol ||
token === InterestCompoundingETHIndex.symbol ||
token === LeveragedrEthStakingYield.symbol
)
Expand Down
42 changes: 42 additions & 0 deletions src/tests/btc2x.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import {
LocalhostProvider,
QuoteTokens,
SignerAccount4,
TestFactory,
wei,
ZeroExApiSwapQuote,
} from './utils'

const { btc2x, eth } = QuoteTokens
const zeroExApi = ZeroExApiSwapQuote

describe('BTC2X (mainnet)', () => {
let factory: TestFactory
beforeEach(async () => {
const provider = LocalhostProvider
const signer = SignerAccount4
factory = new TestFactory(provider, signer, zeroExApi)
})

test('can mint with ETH', async () => {
await factory.fetchQuote({
isMinting: true,
inputToken: eth,
outputToken: btc2x,
indexTokenAmount: wei('1'),
slippage: 0.5,
})
await factory.executeTx()
})

test('can redeem with ETH', async () => {
await factory.fetchQuote({
isMinting: false,
inputToken: btc2x,
outputToken: eth,
indexTokenAmount: wei('1'),
slippage: 0.5,
})
await factory.executeTx()
})
})
42 changes: 42 additions & 0 deletions src/tests/eth2x.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import {
LocalhostProvider,
QuoteTokens,
SignerAccount4,
TestFactory,
wei,
ZeroExApiSwapQuote,
} from './utils'

const { eth, eth2x } = QuoteTokens
const zeroExApi = ZeroExApiSwapQuote

describe('ETH2X (mainnet)', () => {
let factory: TestFactory
beforeEach(async () => {
const provider = LocalhostProvider
const signer = SignerAccount4
factory = new TestFactory(provider, signer, zeroExApi)
})

test('can mint with ETH', async () => {
await factory.fetchQuote({
isMinting: true,
inputToken: eth,
outputToken: eth2x,
indexTokenAmount: wei('1'),
slippage: 0.5,
})
await factory.executeTx()
})

test('can redeem with ETH', async () => {
await factory.fetchQuote({
isMinting: false,
inputToken: eth2x,
outputToken: eth,
indexTokenAmount: wei('1'),
slippage: 0.5,
})
await factory.executeTx()
})
})
26 changes: 25 additions & 1 deletion src/tests/iceth.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ import {
SignerAccount4,
TestFactory,
wei,
wrapETH,
ZeroExApiSwapQuote,
} from './utils'

const { eth, iceth } = QuoteTokens
const { eth, iceth, weth } = QuoteTokens
const zeroExApi = ZeroExApiSwapQuote

describe('icETH (mainnet)', () => {
Expand Down Expand Up @@ -41,4 +42,27 @@ describe('icETH (mainnet)', () => {
})
await factory.executeTx(BigNumber.from(5_000_000))
})

test('can mint with WETH', async () => {
const quote = await factory.fetchQuote({
isMinting: true,
inputToken: weth,
outputToken: iceth,
indexTokenAmount: wei('0.1'),
slippage: 1,
})
await wrapETH(quote.inputOutputAmount, factory.getSigner())
await factory.executeTx()
})

test('can redeem for WETH', async () => {
await factory.fetchQuote({
isMinting: false,
inputToken: iceth,
outputToken: weth,
indexTokenAmount: wei('0.1'),
slippage: 1,
})
await factory.executeTx()
})
})
16 changes: 16 additions & 0 deletions src/tests/utils/quoteTokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import {
ETH,
ETH2xFlexibleLeverageIndex,
GitcoinStakedETHIndex,
IndexCoopBitcoin2xIndex,
IndexCoopEthereum2xIndex,
InterestCompoundingETHIndex,
LeveragedrEthStakingYield,
MetaverseIndex,
Expand All @@ -21,6 +23,12 @@ import {
} from 'constants/tokens'
import { QuoteToken } from 'quote/quoteToken'

const btc2x: QuoteToken = {
address: IndexCoopBitcoin2xIndex.address!,
decimals: 18,
symbol: IndexCoopBitcoin2xIndex.symbol,
}

const btc2xfli: QuoteToken = {
address: BTC2xFlexibleLeverageIndex.address!,
decimals: 18,
Expand Down Expand Up @@ -57,6 +65,12 @@ const eth: QuoteToken = {
address: ETH.address!,
}

const eth2x: QuoteToken = {
symbol: IndexCoopEthereum2xIndex.symbol!,
decimals: 18,
address: IndexCoopEthereum2xIndex.address!,
}

const eth2xfli: QuoteToken = {
symbol: ETH2xFlexibleLeverageIndex.symbol,
decimals: 18,
Expand Down Expand Up @@ -129,12 +143,14 @@ const wseth: QuoteToken = {
}

export const QuoteTokens = {
btc2x,
btc2xfli,
cdeti,
dai,
dpi,
dseth,
eth,
eth2x,
eth2xfli,
gtcETH,
iceth,
Expand Down
37 changes: 25 additions & 12 deletions src/utils/contracts.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import {
GitcoinStakedETHIndex,
LeveragedrEthStakingYield,
CoinDeskEthTrendIndex,
IndexCoopEthereum2xIndex,
IndexCoopBitcoin2xIndex,
} from 'constants/tokens'

import {
Expand All @@ -26,7 +28,6 @@ import {
getExchangeIssuanceZeroExContractAddress,
getFlashMintZeroExContract,
getFlashMintZeroExContractForToken,
getIndexFlashMintZeroExContract,
getFlashMintLeveragedContractForToken,
} from './contracts'

Expand Down Expand Up @@ -292,22 +293,34 @@ describe('getFlashMintZeroExContractForToken()', () => {
})
})

describe('getIndexFlashMintZeroExContract()', () => {
test('return correct contract for mainnet', async () => {
const expectedAddress = FlashMintZeroExMainnetAddress
const contract = getIndexFlashMintZeroExContract(undefined, 1)
describe('BTC2X', () => {
test('return correct contract for token', async () => {
const expectedAddress = FlashMintLeveragedAddress
const contract = getFlashMintLeveragedContractForToken(
IndexCoopBitcoin2xIndex.symbol,
undefined
)
expect(contract.address).toEqual(expectedAddress)
expect(contract.functions.getRequiredIssuanceComponents).toBeDefined()
expect(contract.functions.getRequiredRedemptionComponents).toBeDefined()
expect(contract.functions.getLeveragedTokenData).toBeDefined()
expect(contract.functions.issueExactSetFromERC20).toBeDefined()
expect(contract.functions.issueExactSetFromETH).toBeDefined()
expect(contract.functions.issueExactSetFromToken).toBeDefined()
expect(contract.functions.redeemExactSetForERC20).toBeDefined()
expect(contract.functions.redeemExactSetForETH).toBeDefined()
expect(contract.functions.redeemExactSetForToken).toBeDefined()
})
})

test('returns mainnet contract by default', async () => {
const expectedAddress = FlashMintZeroExMainnetAddress
const contract = getIndexFlashMintZeroExContract(undefined)
describe('ETH2X', () => {
test('return correct contract for token', async () => {
const expectedAddress = FlashMintLeveragedAddress
const contract = getFlashMintLeveragedContractForToken(
IndexCoopEthereum2xIndex.symbol,
undefined
)
expect(contract.address).toEqual(expectedAddress)
expect(contract.functions.getLeveragedTokenData).toBeDefined()
expect(contract.functions.issueExactSetFromERC20).toBeDefined()
expect(contract.functions.issueExactSetFromETH).toBeDefined()
expect(contract.functions.redeemExactSetForERC20).toBeDefined()
expect(contract.functions.redeemExactSetForETH).toBeDefined()
})
})
52 changes: 12 additions & 40 deletions src/utils/contracts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import {
GitcoinStakedETHIndex,
LeveragedrEthStakingYield,
CoinDeskEthTrendIndex,
IndexCoopEthereum2xIndex,
IndexCoopBitcoin2xIndex,
} from '../constants/tokens'

export function getExchangeIssuanceLeveragedContractAddress(
Expand Down Expand Up @@ -56,15 +58,6 @@ export const getFlashMintLeveragedContract = (
)
}

export const getIndexFlashMintLeveragedContractAddress = (
chainId = ChainId.Mainnet
) => {
switch (chainId) {
default:
return FlashMintLeveragedAddress
}
}

/**
* Returns an instance of the Index FlashMintLeveraged contract (mainnet)
*
Expand All @@ -74,10 +67,9 @@ export const getIndexFlashMintLeveragedContractAddress = (
* @returns an instance of a FlashMintLeveraged contract
*/
export const getIndexFlashMintLeveragedContract = (
signerOrProvider: Signer | Provider | undefined,
chainId: number = ChainId.Mainnet
signerOrProvider: Signer | Provider | undefined
): Contract => {
const contractAddress = getIndexFlashMintLeveragedContractAddress(chainId)
const contractAddress = FlashMintLeveragedAddress
return new Contract(
contractAddress,
EXCHANGE_ISSUANCE_LEVERAGED_ABI,
Expand Down Expand Up @@ -120,8 +112,10 @@ export const getFlashMintLeveragedContractForToken = (
case BTC2xFlexibleLeverageIndex.symbol:
case ETH2xFlexibleLeverageIndex.symbol:
return getFlashMintLeveragedForCompoundContract(signerOrProvider)
case IndexCoopBitcoin2xIndex.symbol:
case IndexCoopEthereum2xIndex.symbol:
case LeveragedrEthStakingYield.symbol:
return getIndexFlashMintLeveragedContract(signerOrProvider, chainId)
return getIndexFlashMintLeveragedContract(signerOrProvider)
default:
return getFlashMintLeveragedContract(signerOrProvider, chainId)
}
Expand Down Expand Up @@ -175,34 +169,12 @@ export const getFlashMintZeroExContractForToken = (
case DiversifiedStakedETHIndex.symbol:
case GitcoinStakedETHIndex.symbol:
case wsETH2.symbol:
return getIndexFlashMintZeroExContract(providerSigner, chainId)
return new Contract(
FlashMintZeroExMainnetAddress,
FLASHMINT_ZEROEX_ABI,
providerSigner
)
default:
return getFlashMintZeroExContract(providerSigner, chainId)
}
}

export function getIndexFlashMintZeroExContractAddress(
chainId: number
): string {
switch (chainId) {
default:
return FlashMintZeroExMainnetAddress
}
}

/**
* Returns an instance of an FlashMintZeroEx contract for Index Protocol (based
* on the chain).
*
* @param providerSigner A provider or signer
* @param chainId The chain ID for the network (default Mainnet)
*
* @returns An instance of a FlashMintZeroEx contract
*/
export const getIndexFlashMintZeroExContract = (
providerSigner: Signer | Provider | undefined,
chainId: number = ChainId.Mainnet
): Contract => {
const contractAddress = getIndexFlashMintZeroExContractAddress(chainId)
return new Contract(contractAddress, FLASHMINT_ZEROEX_ABI, providerSigner)
}
Loading

0 comments on commit 23f6832

Please sign in to comment.