Skip to content

Commit

Permalink
Fix bridge issues (#1232)
Browse files Browse the repository at this point in the history
* restore history for relaychain & sora parachain in one flow

* refactoring sub history restoration

* fix transfer min & max amounts

* update add token button

* dont remove walletconnect session after provider change

* fix evm address check

* fix loLowerCase check
  • Loading branch information
Nikita-Polyakov authored and Sociopacific committed Dec 1, 2023
1 parent 051458e commit 742bc20
Show file tree
Hide file tree
Showing 11 changed files with 259 additions and 190 deletions.
43 changes: 36 additions & 7 deletions src/components/mixins/BridgeMixin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ import WalletConnectMixin from '@/components/mixins/WalletConnectMixin';
import { PageNames } from '@/consts';
import router from '@/router';
import { getter, state } from '@/store/decorators';
import { subBridgeApi } from '@/utils/bridge/sub/api';

import type { CodecString } from '@sora-substrate/util';
import type { RegisteredAccountAsset } from '@sora-substrate/util/build/assets/types';
import type { SubNetwork } from '@sora-substrate/util/build/bridgeProxy/sub/consts';

@Component
export default class BridgeMixin extends Mixins(mixins.LoadingMixin, WalletConnectMixin) {
Expand All @@ -17,6 +19,7 @@ export default class BridgeMixin extends Mixins(mixins.LoadingMixin, WalletConne
@state.bridge.outgoingMaxLimit outgoingMaxLimit!: Nullable<FPNumber>;
@state.bridge.incomingMinLimit incomingMinAmount!: FPNumber;
@state.bridge.soraNetworkFee soraNetworkFee!: CodecString;
@state.bridge.isSoraToEvm isSoraToEvm!: boolean;

@getter.web3.isValidNetwork isValidNetwork!: boolean;
@getter.bridge.asset asset!: Nullable<RegisteredAccountAsset>;
Expand All @@ -34,38 +37,64 @@ export default class BridgeMixin extends Mixins(mixins.LoadingMixin, WalletConne
return this.nativeToken?.externalDecimals;
}

get assetLockedOnSora(): boolean {
return !subBridgeApi.isSoraParachain(this.networkSelected as SubNetwork);
}

get outgoingMaxAmount(): FPNumber | null {
const filtered = [this.assetLockedBalance, this.outgoingMaxLimit].filter((item) => !!item) as FPNumber[];
const locks = [this.outgoingMaxLimit];

if (this.assetLockedOnSora) locks.push(this.assetLockedBalance);

const filtered = locks.filter((item) => !!item) as FPNumber[];

if (!filtered.length) return null;

return FPNumber.min(...filtered);
}

isGreaterThanOutgoingMaxAmount(
get incomingMaxAmount(): FPNumber | null {
if (this.assetLockedOnSora) return null;

return this.assetLockedBalance ?? null;
}

getTransferMaxAmount(isOutgoing: boolean): FPNumber | null {
return isOutgoing ? this.outgoingMaxAmount : this.incomingMaxAmount;
}

getTransferMinAmount(isOutgoing: boolean): FPNumber | null {
return isOutgoing ? null : this.incomingMinAmount;
}

isGreaterThanTransferMaxAmount(
amount: string,
asset: Nullable<RegisteredAccountAsset>,
isSoraToEvm: boolean,
isRegisteredAsset = true
): boolean {
if (!(asset && isRegisteredAsset && isSoraToEvm && this.outgoingMaxAmount)) return false;
const maxAmount = this.getTransferMaxAmount(isSoraToEvm);

if (!(asset && isRegisteredAsset && maxAmount)) return false;

const fpAmount = new FPNumber(amount);

return FPNumber.gt(fpAmount, this.outgoingMaxAmount);
return FPNumber.gt(fpAmount, maxAmount);
}

isLowerThanIncomingMinAmount(
isLowerThanTransferMinAmount(
amount: string,
asset: Nullable<RegisteredAccountAsset>,
isSoraToEvm: boolean,
isRegisteredAsset = true
) {
if (!(asset && isRegisteredAsset && !isSoraToEvm)) return false;
const minAmount = this.getTransferMinAmount(isSoraToEvm);

if (!(asset && isRegisteredAsset && minAmount)) return false;

const fpAmount = new FPNumber(amount);

return FPNumber.lt(fpAmount, this.incomingMinAmount);
return FPNumber.lt(fpAmount, minAmount);
}

handleViewTransactionsHistory(): void {
Expand Down
24 changes: 16 additions & 8 deletions src/components/pages/Bridge/TransferNotification.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,12 @@
<dialog-base :visible.sync="visibility" class="bridge-transfer-notification">
<simple-notification modal-content success @submit.native.prevent="close">
<template #title>{{ t('bridgeTransferNotification.title') }}</template>
<s-button
v-if="addTokenBtnVisibility"
type="secondary"
@click="addToken"
class="add-token-btn s-typography-button--big"
>
<s-button v-if="addTokenBtnVisibility" @click="addToken" class="add-token-btn s-typography-button--big">
<span>{{ t('bridgeTransferNotification.addToken', { symbol: assetSymbol }) }}</span>
<div class="token-icons">
<token-logo :token="asset" />
<token-logo size="small" :token="asset" />
</div>
<span>{{ t('operations.andText') }} {{ t('closeText') }}</span>
</s-button>
</simple-notification>
</dialog-base>
Expand Down Expand Up @@ -84,15 +80,27 @@ export default class BridgeTransferNotification extends Mixins(TranslationMixin)
const { externalAddress, externalDecimals, symbol, address } = this.asset;
const image = this.whitelist[address]?.icon;
await ethersUtil.addToken(externalAddress, symbol, +externalDecimals, image);
this.visibility = false;
}
}
</script>

<style lang="scss">
.bridge-transfer-notification {
.el-button + .el-button {
margin-left: 0;
}
}
</style>

<style lang="scss" scoped>
.add-token-btn {
width: 100%;
.token-icons {
display: flex;
margin-left: $inner-spacing-mini;
margin: 0 $inner-spacing-tiny;
}
}
</style>
10 changes: 5 additions & 5 deletions src/store/bridge/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -554,12 +554,12 @@ const actions = defineActions({
},

async updateExternalHistory(context, clearHistory = false): Promise<void> {
const { commit, getters, rootState } = bridgeActionContext(context);
const { networkSelected } = rootState.web3;
const { commit, getters } = bridgeActionContext(context);
const { networkHistoryId } = getters;

if (!networkSelected || getters.networkHistoryLoading) return;
if (!networkHistoryId || getters.networkHistoryLoading) return;

commit.setNetworkHistoryLoading(networkSelected);
commit.setNetworkHistoryLoading(networkHistoryId);

if (getters.isEthBridge) {
await updateEthHistory(context, clearHistory);
Expand All @@ -571,7 +571,7 @@ const actions = defineActions({
console.info('Evm history not implemented');
}

commit.resetNetworkHistoryLoading(networkSelected);
commit.resetNetworkHistoryLoading(networkHistoryId);
},

removeHistory(context, { tx, force = false }: { tx: Partial<IBridgeTransaction>; force: boolean }): void {
Expand Down
17 changes: 14 additions & 3 deletions src/store/bridge/getters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@ import { defineGetters } from 'direct-vuex';

import { ZeroStringValue } from '@/consts';
import { bridgeGetterContext } from '@/store/bridge';
import { subBridgeApi } from '@/utils/bridge/sub/api';
import { formatSubAddress } from '@/utils/bridge/sub/utils';

import type { BridgeState } from './types';
import type { IBridgeTransaction, CodecString } from '@sora-substrate/util';
import type { RegisteredAccountAsset } from '@sora-substrate/util/build/assets/types';
import type { SubNetwork } from '@sora-substrate/util/build/bridgeProxy/sub/consts';
import type { BridgeNetworkId } from '@sora-substrate/util/build/bridgeProxy/types';

const getters = defineGetters<BridgeState>()({
asset(...args): Nullable<RegisteredAccountAsset> {
Expand Down Expand Up @@ -174,11 +177,19 @@ const getters = defineGetters<BridgeState>()({

return getters.history[state.historyId] ?? null;
},
networkHistoryLoading(...args): boolean {
const { state, rootState } = bridgeGetterContext(args);
networkHistoryId(...args): Nullable<BridgeNetworkId> {
const { getters, rootState } = bridgeGetterContext(args);
const { networkSelected } = rootState.web3;

return !!(networkSelected && state.historyLoading[networkSelected]);
if (!networkSelected) return null;

return getters.isSubBridge ? subBridgeApi.getRelayChain(networkSelected as SubNetwork) : networkSelected;
},
networkHistoryLoading(...args): boolean {
const { getters, state } = bridgeGetterContext(args);
const { networkHistoryId } = getters;

return !!(networkHistoryId && state.historyLoading[networkHistoryId]);
},
});

Expand Down
7 changes: 3 additions & 4 deletions src/store/web3/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,6 @@ const actions = defineActions({
const { commit, dispatch, state } = web3ActionContext(context);
try {
commit.setEvmProviderLoading(provider);
// reset prev connection
dispatch.resetEvmProviderConnection();
// create new connection
const address = await ethersUtil.connectEvmProvider(provider, {
chains: [state.ethBridgeEvmNetwork],
Expand All @@ -91,14 +89,15 @@ const actions = defineActions({
},

resetEvmProviderConnection(context): void {
const { commit } = web3ActionContext(context);
const { commit, state } = web3ActionContext(context);
const provider = state.evmProvider;
// reset store
commit.resetEvmAddress();
commit.resetEvmProvider();
commit.resetEvmProviderNetwork();
commit.resetEvmProviderSubscription();
// reset connection
ethersUtil.disconnectEvmProvider();
ethersUtil.disconnectEvmProvider(provider);
},

async disconnectExternalNetwork(context): Promise<void> {
Expand Down
2 changes: 1 addition & 1 deletion src/utils/bridge/eth/classes/history.ts
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ export class EthBridgeHistory {
const data = (tx as any).input; // 'data' is named as 'input'
const decodedInput = BRIDGE_INTERFACE.parseTransaction({ data });

if (decodedInput?.args.getValue('txHash').toLowerCase() === hash.toLowerCase()) {
if (decodedInput?.args.getValue('txHash')?.toLowerCase() === hash.toLowerCase()) {
return tx;
}
} catch (err) {
Expand Down
1 change: 0 additions & 1 deletion src/utils/bridge/sub/classes/adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,6 @@ export class SubAdapter {
}

public async getTokenBalance(accountAddress: string, tokenSymbol?: string): Promise<CodecString> {
if (tokenSymbol && this.api.registry.chainTokens[0] !== tokenSymbol) return ZeroStringValue;
return await this.getAccountBalance(accountAddress);
}

Expand Down
Loading

0 comments on commit 742bc20

Please sign in to comment.