Skip to content

Commit

Permalink
swap and lp router (#77)
Browse files Browse the repository at this point in the history
* update

* update docs

* fix test

* fix fee receiver addr

* fix test

* add rescue endpoint

* update doc

* bump

* polish and add tests

* drop and boostrap stake router

* bump v1.9.0-4

* update doc

* add feeToken params

* bump v1.9.0-5

* added tests

* fix and more tests

* skip swap and route tests

* tests for ldot as fee token

* fix

* clean up swap and lp stuff

* cleanup

* fix

* swap and lp router

This reverts commit 41dd570.

* polish

* add tests

* increase timeout

* tests for rescue
  • Loading branch information
shunjizhan authored Oct 23, 2024
1 parent b6b184e commit b0adda0
Show file tree
Hide file tree
Showing 15 changed files with 615 additions and 25 deletions.
94 changes: 94 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,100 @@ POST /routeDropAndBootstrap
}
```

### `/shouldRouteSwapAndLp`
checks if the relayer can route this request, returns router address
```
GET /shouldRouteSwapAndLp
params: {
poolId: string; // euphrates pool id
recipient: string; // dest evm address
swapAmount: string; // how many token to swap before adding liquidity
minShareAmount?: string; // add liquidity min share amount (default: 0)
}
```

example
```
GET /shouldRouteSwapAndLp?recipient=0x0085560b24769dAC4ed057F1B2ae40746AA9aAb6&swapAmount=100000000&poolId=7
=>
{
"data": {
"shouldRoute": true,
"routerAddr": "0xC5a363695957469963c15Bf87B00B25eAbE8D234"
}
}
```

### `/routeSwapAndLp`
- swap small amount of token and airdrop ACA to recipient
- swap `swapAmount` token to LDOT, then add LP, refund the remaining token recipient
- stake Lp to euphrates for the recipient
- returns the txhash
```
POST /routeSwapAndLp
data: {
poolId: string; // euphrates pool id
recipient: string; // dest evm address
token: string; // token to route
swapAmount: string; // how many token to swap before adding liquidity
minShareAmount?: string; // add liquidity min share amount (default: 0)
}
```

example
```
POST /routeSwapAndLp
data: {
"poolId": 7,
"recipient": "0x0085560b24769dAC4ed057F1B2ae40746AA9aAb6",
"token": "0xa7fb00459f5896c3bd4df97870b44e868ae663d7",
"swapAmount": 100000000
}
=> tx hash
{
data: '0xe1c82c53796d82d87d2e31e289b3cc8ff18e304b8ac95f2bd7548a1706bb8655'
}
/* ---------- when error ---------- */
// similar to /routeXcm
```

### `/rescueSwapAndLp`
- perform gas drop
- rescue token to recipient

```
POST /rescueSwapAndLp
data: {
poolId: string; // euphrates pool id
recipient: string; // dest evm address
token: string; // token to route
swapAmount: string; // how many token to swap before adding liquidity
minShareAmount?: string; // add liquidity min share amount (default: 0)
}
```

example
```
POST /rescueSwapAndLp
data: {
"poolId": 7,
"recipient": "0x0085560b24769dAC4ed057F1B2ae40746AA9aAb6",
"token": "0xa7fb00459f5896c3bd4df97870b44e868ae663d7",
"swapAmount": 100000000
}
=> tx hash
{
data: '0xe1c82c53796d82d87d2e31e289b3cc8ff18e304b8ac95f2bd7548a1706bb8655'
}
/* ---------- when error ---------- */
// similar to /routeXcm
```


## Routing Process
A complete working flow can be found in [routing e2e tests](./src/__tests__/route.test.ts).

Expand Down
19 changes: 19 additions & 0 deletions src/__tests__/__snapshots__/swapAndLp.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`/shouldRouteSwapAndLp > when should route 1`] = `
{
"data": {
"routerAddr": "0x8ed211e6e940955A8ccF2ec2BA792eDfd7Cca9bD",
"shouldRoute": true,
},
}
`;

exports[`/shouldRouteSwapAndLp > when should route 2`] = `
{
"data": {
"routerAddr": "0x8ed211e6e940955A8ccF2ec2BA792eDfd7Cca9bD",
"shouldRoute": true,
},
}
`;
55 changes: 43 additions & 12 deletions src/__tests__/bootstrap.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { ADDRESSES, ROUTER_TOKEN_INFO } from '@acala-network/asset-router/dist/consts';
import { AcalaJsonRpcProvider } from '@acala-network/eth-providers';
import { ADDRESSES } from '@acala-network/asset-router/dist/consts';
import { ApiPromise, WsProvider } from '@polkadot/api';
import { ERC20__factory } from '@certusone/wormhole-sdk/lib/cjs/ethers-contracts';
import { FeeRegistry__factory } from '@acala-network/asset-router/dist/typechain-types';
Expand All @@ -10,30 +9,29 @@ import { parseEther, parseUnits } from 'ethers/lib/utils';
import { toHuman } from '@acala-network/asset-router/dist/utils';

import { DropAndBootstrapParams } from '../utils';
import { ETH_RPC, EUPHRATES_ADDR } from '../consts';
import { EUPHRATES_ADDR } from '../consts';
import {
JITOSOL_ADDR,
JITOSOL_DECIMALS,
JITOSOL_LDOT_LP_PREDEPLOY_CODE,
LDOT_DECIMALS,
NEW_DEX_CODE,
TEST_ADDR_RELAYER,
TEST_ADDR_USER,
TEST_KEY,
} from './testConsts';
import {
alice,
api,
expectError,
provider,
relayer,
sudoSendAndWait,
sudoTransferToken,
transferToken,
} from './testUtils';

const provider = new AcalaJsonRpcProvider(ETH_RPC.LOCAL);
const relayer = new Wallet(TEST_KEY.RELAYER, provider);
const user = Wallet.createRandom().connect(provider);

const JITOSOL_DECIMALS = 9;
const LDOT_DECIMALS = 10;
const JITOSOL_ADDR = ROUTER_TOKEN_INFO.jitosol.acalaAddr;

const recipient = user.address;
const boostrapAmountJitosol = '0.1';
const boostrapAmountLdot = '10';
Expand Down Expand Up @@ -73,8 +71,8 @@ describe('prepare', () => {
{ Erc20: JITOSOL_ADDR },
1,
1,
parseUnits('10', 10).toBigInt(),
parseUnits('10', 9).toBigInt(),
parseUnits('0.1', 10).toBigInt(),
parseUnits('0.1', 9).toBigInt(),
0,
);
await sudoSendAndWait(api, tx);
Expand All @@ -87,6 +85,8 @@ describe('prepare', () => {
JITOSOL_ADDR,
5,
);

await api.disconnect();
});
});

Expand Down Expand Up @@ -482,3 +482,34 @@ describe('/routeDropAndBootstrap', () => {
expect(bal3.userBal.sub(bal2.userBal).toBigInt()).to.eq(0n);
});
});

describe('end bootstrap', () => {
it('end bootstrap', async () => {
const api = await ApiPromise.create({
provider: new WsProvider('ws://localhost:8000'),
});

console.log('end provisioning ...');
const endProvisionTx = api.tx.dex.endProvisioning(
{ Token: 'LDOT' },
{ Erc20: JITOSOL_ADDR },
);
const tx = api.tx.sudo.sudoAs(alice.address, endProvisionTx);
await sudoSendAndWait(api, tx);

// console.log('enable trading pair ...');
// tx = api.tx.dex.enableTradingPair(
// { Token: 'LDOT' },
// { Erc20: JITOSOL_ADDR },
// );
// await sudoSendAndWait(api, tx);

const tradingPairStatus = await api.query.dex.tradingPairStatuses([
{ Token: 'LDOT' },
{ Erc20: JITOSOL_ADDR },
]);
expect(tradingPairStatus.toHuman()).to.eq('Enabled');

await api.disconnect();
});
});
2 changes: 1 addition & 1 deletion src/__tests__/configs/acala.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
endpoint:
- wss://acala-rpc.aca-api.network
- wss://acala-rpc.dwellir.com
- wss://acala-rpc.aca-api.network
mock-signature-host: true
# block: ${env.ACALA_BLOCK_NUMBER}
db: ./db.sqlite
Expand Down
14 changes: 5 additions & 9 deletions src/__tests__/euphrates.test.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,28 @@
import { ADDRESSES } from '@acala-network/asset-router/dist/consts';
import { AcalaJsonRpcProvider } from '@acala-network/eth-providers';
import { DOT, LCDOT_13 as LCDOT, LDOT } from '@acala-network/contracts/utils/AcalaTokens';
import { ERC20__factory } from '@certusone/wormhole-sdk/lib/cjs/ethers-contracts';
import { FeeRegistry__factory } from '@acala-network/asset-router/dist/typechain-types';
import { HOMA } from '@acala-network/contracts/utils/Predeploy';
import { IHoma__factory } from '@acala-network/contracts/typechain';
import { ONE_ACA, almostEq, toHuman } from '@acala-network/asset-router/dist/utils';
import { Wallet } from 'ethers';
import { describe, expect, it } from 'vitest';
import { describe, expect, it } from 'vitest';
import { formatEther, parseEther, parseUnits } from 'ethers/lib/utils';

import { ETH_RPC, EUPHRATES_ADDR, EUPHRATES_POOLS } from '../consts';
import { EUPHRATES_ADDR, EUPHRATES_POOLS } from '../consts';
import { RouteParamsEuphrates } from '../utils';
import {
TEST_ADDR_RELAYER,
TEST_ADDR_USER,
TEST_KEY,
} from './testConsts';
import {
api,
expectError,
provider,
relayer,
transferToken,
user,
} from './testUtils';

const provider = new AcalaJsonRpcProvider(ETH_RPC.LOCAL);
const relayer = new Wallet(TEST_KEY.RELAYER, provider); // 0xe3234f433914d4cfCF846491EC5a7831ab9f0bb3
const user = new Wallet(TEST_KEY.USER, provider); // 0x0085560b24769dAC4ed057F1B2ae40746AA9aAb6

// [inToken, outToken]
const WTDOT = '0xe1bd4306a178f86a9214c39abcd53d021bedb0f9';
const EUPHRAETS_POOL_INFO = {
Expand Down
Loading

0 comments on commit b0adda0

Please sign in to comment.