Skip to content

Commit

Permalink
Merge pull request #318 from oraichain/feat/affiliates
Browse files Browse the repository at this point in the history
fee affiliates
  • Loading branch information
haunv3 authored Aug 13, 2024
2 parents 598c309 + 33e30a5 commit 5ba1467
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 25 deletions.
2 changes: 1 addition & 1 deletion packages/universal-swap/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@oraichain/oraidex-universal-swap",
"version": "1.0.99",
"version": "1.1.0",
"main": "build/index.js",
"files": [
"build/"
Expand Down
64 changes: 56 additions & 8 deletions packages/universal-swap/src/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ import { GasPrice } from "@cosmjs/stargate";
import { OraiswapRouterQueryClient } from "@oraichain/oraidex-contracts-sdk";
import { Affiliate } from "@oraichain/oraidex-contracts-sdk/build/OraiswapMixedRouter.types";

const AFFILIATE_DECIMAL = 1e4; // 10_000
export class UniversalSwapHandler {
constructor(
public swapData: UniversalSwapData,
Expand Down Expand Up @@ -112,6 +113,7 @@ export class UniversalSwapHandler {
// if to token is on Oraichain then we wont need to transfer IBC to the other chain
const { chainId: toChainId, coinGeckoId: toCoinGeckoId } = this.swapData.originalToToken;
const { coinGeckoId: fromCoinGeckoId } = this.swapData.originalFromToken;
const { affiliates } = this.swapData;
const { cosmos: sender } = this.swapData.sender;
if (toChainId === "Oraichain") {
const msgSwap = this.generateMsgsSwap();
Expand Down Expand Up @@ -148,13 +150,22 @@ export class UniversalSwapHandler {
this.generateMsgsIbcWasm(ibcInfo, ibcReceiveAddr, this.swapData.originalToToken.denom, "")
);
} else {
let tokenAmount = this.swapData.simulateAmount;
if (affiliates?.length) {
const totalBasisPoints = affiliates.reduce((acc, cur) => acc + parseFloat(cur.basis_points_fee), 0);
const amountAffilate = totalBasisPoints / AFFILIATE_DECIMAL;
tokenAmount = Math.trunc(
new BigDecimal(tokenAmount).sub(parseFloat(tokenAmount) * amountAffilate).toNumber()
).toString();
}

msgTransfer = [
{
typeUrl: "/ibc.applications.transfer.v1.MsgTransfer",
value: MsgTransfer.fromPartial({
sourcePort: ibcInfo.source,
sourceChannel: ibcInfo.channel,
token: coin(this.swapData.simulateAmount, toTokenInOrai.denom),
token: coin(tokenAmount, toTokenInOrai.denom),
sender: sender,
receiver: ibcReceiveAddr,
memo: "",
Expand Down Expand Up @@ -324,7 +335,8 @@ export class UniversalSwapHandler {
route: Routes,
{ oraiAddress, injAddress },
isOnlySwap: boolean,
isInitial: boolean
isInitial: boolean,
flagAffiliate?: boolean
) {
const { prefixReceiver, chainInfoReceiver } = this.getPrefixCosmos(route);
let post_swap_action = {};
Expand All @@ -348,10 +360,19 @@ export class UniversalSwapHandler {
};
});

const minimumReceive = Math.trunc(
let minimumReceive = Math.trunc(
new BigDecimal(route.tokenOutAmount).mul((100 - this.swapData.userSlippage) / 100).toNumber()
).toString();

const { affiliates } = this.swapData;
if (affiliates?.length && flagAffiliate) {
const totalBasisPoints = affiliates.reduce((acc, cur) => acc + parseFloat(cur.basis_points_fee), 0);
const amountAffiliate = totalBasisPoints / AFFILIATE_DECIMAL;
minimumReceive = Math.trunc(
new BigDecimal(minimumReceive).sub(parseFloat(minimumReceive) * amountAffiliate).toNumber()
).toString();
}

const msg = {
msg: {
swap_and_action: {
Expand Down Expand Up @@ -456,19 +477,35 @@ export class UniversalSwapHandler {
return { prefixRecover, prefixReceiver, chainInfoRecover, chainInfoReceiver };
};

public getMsgTransfer = (route: Routes, { oraiAddress, injAddress }, isLastRoute: boolean) => {
public getMsgTransfer = (
route: Routes,
{ oraiAddress, injAddress },
isLastRoute: boolean,
flagAffiliate?: boolean
) => {
const { prefixReceiver, prefixRecover, chainInfoRecover, chainInfoReceiver } = this.getPrefixCosmos(route);
const addressReceiver = this.getAddress(
prefixReceiver,
{ address60: injAddress, address118: oraiAddress },
chainInfoReceiver.bip44.coinType
);

let tokenInAmount = route.tokenInAmount;
const { affiliates } = this.swapData;
if (affiliates?.length && flagAffiliate) {
const totalBasisPoints = affiliates.reduce((acc, cur) => acc + parseFloat(cur.basis_points_fee), 0);
const amountAffiliate = totalBasisPoints / AFFILIATE_DECIMAL;
tokenInAmount = Math.trunc(
new BigDecimal(tokenInAmount).sub(parseFloat(tokenInAmount) * amountAffiliate).toNumber()
).toString();
}

return {
sourcePort: route.bridgeInfo.port,
sourceChannel: route.bridgeInfo.channel,
receiver: isLastRoute ? addressReceiver : this.getReceiverIBCHooks(route.tokenOutChainId, addressReceiver),
token: {
amount: route.tokenInAmount,
amount: tokenInAmount,
denom: route.tokenIn
},
sender: this.getAddress(
Expand All @@ -486,6 +523,7 @@ export class UniversalSwapHandler {
let msgTransfers = [];
let pathProperty = [];
let pathReceiver = [];
let flagAffiliate = [];

routeFlatten.forEach((route: Routes, index: number, routes: Routes[]) => {
const isLastRoute = route.isLastPath;
Expand All @@ -497,7 +535,10 @@ export class UniversalSwapHandler {

if (route.chainId === "Oraichain" && !isBridge) {
// swap in oraichain
if (isSwap) messages.push(...this.generateMsgsSmartRouterSwap(route, isLastRoute));
if (isSwap) {
flagAffiliate[route.path] = true;
messages.push(...this.generateMsgsSmartRouterSwap(route, isLastRoute));
}
if (isConvert) messages.push(this.generateMsgsConvertSmartRouterSwap(route));
} else {
// initial msgTransfer
Expand All @@ -508,15 +549,21 @@ export class UniversalSwapHandler {
route,
{ oraiAddress, injAddress },
isLastRoute,
true
true,
flagAffiliate[route.path]
);
msgTransfers[route.path] = msgActionSwap;
pathProperty[route.path] = "msg.swap_and_action.post_swap_action";
pathReceiver[route.path] = isLastRoute
? pathProperty[route.path] + ".transfer.to_address"
: pathProperty[route.path] + ".ibc_transfer.ibc_info.receiver";
} else {
msgTransfers[route.path] = this.getMsgTransfer(route, { oraiAddress, injAddress }, isLastRoute);
msgTransfers[route.path] = this.getMsgTransfer(
route,
{ oraiAddress, injAddress },
isLastRoute,
flagAffiliate[route.path]
);
pathProperty[route.path] = "memo";
pathReceiver[route.path] = "receiver";
}
Expand Down Expand Up @@ -1288,6 +1335,7 @@ export class UniversalSwapHandler {
swapOps: ops
};
});

const msgs: ExecuteInstruction[] = this.buildSwapMsgsFromSmartRoute(
routes,
fromTokenOnOrai,
Expand Down
51 changes: 35 additions & 16 deletions packages/universal-swap/src/universal-demos/alpha-smart-router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -471,33 +471,46 @@ import { cosmosTokens, flattenTokens, generateError, getTokenOnOraichain, toAmou

const router = {
swapAmount: "1000000",
returnAmount: "66772",
returnAmount: "14084260",
routes: [
{
swapAmount: "1000000",
returnAmount: "66772",
returnAmount: "14084260",
paths: [
{
chainId: "Oraichain",
tokenIn: "ibc/9C4DCD21B48231D0BC2AC3D1B74A864746B37E4292694C93C617324250D002FC",
tokenIn: "orai",
tokenInAmount: "1000000",
tokenOut: "orai",
tokenOutAmount: "66772",
tokenOutChainId: "Oraichain",
tokenOut: "uosmo",
tokenOutAmount: "14084260",
tokenOutChainId: "osmosis-1",
actions: [
{
type: "Swap",
protocol: "Oraidex",
tokenIn: "ibc/9C4DCD21B48231D0BC2AC3D1B74A864746B37E4292694C93C617324250D002FC",
tokenIn: "orai",
tokenInAmount: "1000000",
tokenOut: "orai",
tokenOutAmount: "66772",
tokenOut: "ibc/9C4DCD21B48231D0BC2AC3D1B74A864746B37E4292694C93C617324250D002FC",
tokenOutAmount: "14084260",
swapInfo: [
{
poolId: "orai1d37artrk4tkhz2qyjmaulc2jzjkx7206tmpfug",
tokenOut: "orai"
tokenOut: "ibc/9C4DCD21B48231D0BC2AC3D1B74A864746B37E4292694C93C617324250D002FC"
}
]
},
{
type: "Bridge",
protocol: "Bridge",
tokenIn: "ibc/9C4DCD21B48231D0BC2AC3D1B74A864746B37E4292694C93C617324250D002FC",
tokenInAmount: "14084260",
tokenOut: "uosmo",
tokenOutAmount: "14084260",
tokenOutChainId: "osmosis-1",
bridgeInfo: {
port: "transfer",
channel: "channel-13"
}
}
]
}
Expand All @@ -508,11 +521,11 @@ const router = {

const alphaSwapToOraichain = async () => {
const wallet = new CosmosWalletImpl(process.env.MNEMONIC);
const sender = await wallet.getKeplrAddr("osmosis-1");
const sender = await wallet.getKeplrAddr("Oraichain");
const fromAmount = 1;
console.log("sender: ", sender);
const originalFromToken = cosmosTokens.find((t) => t.coinGeckoId === "osmosis" && t.chainId === "osmosis-1");
const originalToToken = flattenTokens.find((t) => t.coinGeckoId === "oraichain-token" && t.chainId === "0x38");
const originalFromToken = flattenTokens.find((t) => t.coinGeckoId === "oraichain-token" && t.chainId === "Oraichain");
const originalToToken = cosmosTokens.find((t) => t.coinGeckoId === "osmosis" && t.chainId === "osmosis-1");

if (!originalToToken) throw generateError("Could not find original to token");
if (!originalFromToken) throw generateError("Could not find original from token");
Expand All @@ -532,13 +545,19 @@ const alphaSwapToOraichain = async () => {
// recipientAddress: "orai1hvr9d72r5um9lvt0rpkd4r75vrsqtw6yujhqs2",
// recipientAddress: "osmo12zyu8w93h0q2lcnt50g3fn0w3yqnhy4fh4twhr",
// recipientAddress: "inj133lq4pqjdxspcz4n388glv70z59ffeuh3ktnaj",
simulatePrice: "91825481",
simulatePrice: "14082182",
simulateAmount: toAmount(fromAmount, originalToToken.decimals).toString(),
alphaSmartRoutes: router
alphaSmartRoutes: router,
affiliates: [
{
address: "orai1h8rg7zknhxmffp3ut5ztsn8zcaytckfemdkp8n",
basis_points_fee: "25"
}
]
},
{
cosmosWallet: wallet,
swapOptions: { isAlphaSmartRouter: true, isIbcWasm: true, isSourceReceiverTest: true, ibcInfoTestMode: true }
swapOptions: { isAlphaSmartRouter: true, isIbcWasm: false }
}
);

Expand Down

0 comments on commit 5ba1467

Please sign in to comment.