Skip to content

Commit

Permalink
feat(bridge-ui): recommend fee (#457)
Browse files Browse the repository at this point in the history
  • Loading branch information
cyberhorsey authored Dec 21, 2022
1 parent 1e0e352 commit c373194
Show file tree
Hide file tree
Showing 12 changed files with 349 additions and 37 deletions.
6 changes: 4 additions & 2 deletions packages/bridge-ui/src/components/AddressDropdown.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
import { fromChain } from "../store/chain";
import { truncateString } from "../utils/truncateString";
let address: string;
let addressAvatarImgData: string;
let address: string = "";
let addressAvatarImgData: string = "";
let tokenBalance: string = "";
onMount(async () => {
Expand All @@ -26,6 +26,8 @@
$: getUserBalance($signer);
$: setAddress($signer);
async function getUserBalance(signer) {
if (signer) {
const userBalance = await signer.getBalance("latest");
Expand Down
7 changes: 4 additions & 3 deletions packages/bridge-ui/src/components/form/BridgeForm.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@
let requiresAllowance: boolean = true;
let btnDisabled: boolean = true;
let tokenBalance: string;
let customFee: string = "0.01";
let customFee: string = "0";
let recommendedFee: string = "0";
let memo: string = "";
let loading: boolean = false;
Expand Down Expand Up @@ -249,7 +250,7 @@
}
if ($processingFee === ProcessingFeeMethod.RECOMMENDED) {
return ethers.utils.parseEther("0.01");
return BigNumber.from(ethers.utils.parseEther(recommendedFee));
}
}
</script>
Expand Down Expand Up @@ -281,7 +282,7 @@
</label>
</div>

<ProcessingFee bind:customFee />
<ProcessingFee bind:customFee bind:recommendedFee />

<Memo bind:memo />

Expand Down
17 changes: 16 additions & 1 deletion packages/bridge-ui/src/components/form/ProcessingFee.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,23 @@
import { _ } from "svelte-i18n";
import { processingFee } from "../../store/fee";
import { ProcessingFeeMethod, PROCESSING_FEE_META } from "../../domain/fee";
import { toChain, fromChain } from "../../store/chain";
import { token } from "../../store/token";
import { signer } from "../../store/signer";
import { recommendProcessingFee } from "../../utils/recommendProcessingFee";
export let customFee: string;
export let recommendedFee: string = "0";
$: recommendProcessingFee(
$toChain,
$fromChain,
$processingFee,
$token,
$signer
)
.then((fee) => (recommendedFee = fee))
.catch((e) => console.error(e));
function selectProcessingFee(fee) {
$processingFee = fee;
Expand Down Expand Up @@ -45,7 +60,7 @@
</label>
{:else if $processingFee === ProcessingFeeMethod.RECOMMENDED}
<div class="flex items-left justify-between">
<span class="mt-2 text-sm">0.01 ETH </span>
<span class="mt-2 text-sm">{recommendedFee} ETH </span>
</div>
{/if}
</div>
2 changes: 2 additions & 0 deletions packages/bridge-ui/src/domain/proof.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ type GenerateProofOpts = {
signal: string;
sender: string;
srcBridgeAddress: string;
destChain: number;
destHeaderSyncAddress: string;
srcChain: number;
};

Expand Down
10 changes: 10 additions & 0 deletions packages/bridge-ui/src/erc20/bridge.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,8 @@ describe("bridge tests", () => {
bridge.Claim({
message: {
srcChainId: BigNumber.from(167001),
destChainId: BigNumber.from(31336),
gasLimit: BigNumber.from(1),
} as unknown as Message,
signal: "0x",
srcBridgeAddress: "0x",
Expand All @@ -272,6 +274,8 @@ describe("bridge tests", () => {
bridge.Claim({
message: {
srcChainId: BigNumber.from(167001),
destChainId: BigNumber.from(31336),
gasLimit: BigNumber.from(1),
} as unknown as Message,
signal: "0x",
srcBridgeAddress: "0x",
Expand Down Expand Up @@ -299,6 +303,8 @@ describe("bridge tests", () => {
message: {
owner: "0x",
srcChainId: BigNumber.from(167001),
destChainId: BigNumber.from(31336),
gasLimit: BigNumber.from(1),
} as unknown as Message,
signal: "0x",
srcBridgeAddress: "0x",
Expand Down Expand Up @@ -331,7 +337,9 @@ describe("bridge tests", () => {
message: {
owner: "0x",
srcChainId: BigNumber.from(167001),
destChainId: BigNumber.from(31336),
sender: "0x01",
gasLimit: BigNumber.from(1),
} as unknown as Message,
signal: "0x",
srcBridgeAddress: "0x",
Expand Down Expand Up @@ -365,7 +373,9 @@ describe("bridge tests", () => {
message: {
owner: "0x",
srcChainId: BigNumber.from(167001),
destChainId: BigNumber.from(31336),
sender: "0x01",
gasLimit: BigNumber.from(1),
} as unknown as Message,
signal: "0x",
srcBridgeAddress: "0x",
Expand Down
4 changes: 4 additions & 0 deletions packages/bridge-ui/src/erc20/bridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import ERC20 from "../constants/abi/ERC20";
import type { Prover } from "../domain/proof";
import { MessageStatus } from "../domain/message";
import BridgeABI from "../constants/abi/Bridge";
import { chains } from "../domain/chain";

class ERC20Bridge implements Bridge {
private readonly prover: Prover;
Expand Down Expand Up @@ -145,6 +146,9 @@ class ERC20Bridge implements Bridge {
signal: opts.signal,
sender: opts.srcBridgeAddress,
srcBridgeAddress: opts.srcBridgeAddress,
destChain: opts.message.destChainId.toNumber(),
destHeaderSyncAddress:
chains[opts.message.destChainId.toNumber()].headerSyncAddress,
});

return await contract.processMessage(opts.message, proof, {
Expand Down
9 changes: 8 additions & 1 deletion packages/bridge-ui/src/eth/bridge.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { mainnet, taiko } from "../domain/chain";
import type { Bridge, BridgeOpts } from "../domain/bridge";
import ETHBridge from "./bridge";
import { Message, MessageStatus } from "../domain/message";
import { src_url_equal } from "svelte/internal";

const mockSigner = {
getAddress: jest.fn(),
Expand Down Expand Up @@ -133,6 +132,8 @@ describe("bridge tests", () => {
bridge.Claim({
message: {
srcChainId: BigNumber.from(167001),
destChainId: BigNumber.from(31336),
gasLimit: BigNumber.from(1),
} as unknown as Message,
signal: "0x",
srcBridgeAddress: "0x",
Expand Down Expand Up @@ -160,6 +161,8 @@ describe("bridge tests", () => {
message: {
owner: "0x",
srcChainId: BigNumber.from(167001),
destChainId: BigNumber.from(31336),
gasLimit: BigNumber.from(1),
} as unknown as Message,
signal: "0x",
srcBridgeAddress: "0x",
Expand Down Expand Up @@ -192,7 +195,9 @@ describe("bridge tests", () => {
message: {
owner: "0x",
srcChainId: BigNumber.from(167001),
destChainId: BigNumber.from(31336),
sender: "0x01",
gasLimit: BigNumber.from(1),
} as unknown as Message,
signal: "0x",
srcBridgeAddress: "0x",
Expand Down Expand Up @@ -226,7 +231,9 @@ describe("bridge tests", () => {
message: {
owner: "0x",
srcChainId: BigNumber.from(167001),
destChainId: BigNumber.from(31336),
sender: "0x01",
gasLimit: BigNumber.from(1),
} as unknown as Message,
signal: "0x",
srcBridgeAddress: "0x",
Expand Down
14 changes: 10 additions & 4 deletions packages/bridge-ui/src/eth/bridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import TokenVault from "../constants/abi/TokenVault";
import type { Prover } from "../domain/proof";
import { MessageStatus } from "../domain/message";
import Bridge from "../constants/abi/Bridge";
import { chains } from "../domain/chain";

class ETHBridge implements BridgeInterface {
private readonly prover: Prover;
Expand Down Expand Up @@ -90,19 +91,24 @@ class ETHBridge implements BridgeInterface {
}

if (messageStatus === MessageStatus.New) {
const proof = await this.prover.GenerateProof({
const proofOpts = {
srcChain: opts.message.srcChainId.toNumber(),
signal: opts.signal,
sender: opts.srcBridgeAddress,
srcBridgeAddress: opts.srcBridgeAddress,
});
destChain: opts.message.destChainId.toNumber(),
destHeaderSyncAddress:
chains[opts.message.destChainId.toNumber()].headerSyncAddress,
};

const proof = await this.prover.GenerateProof(proofOpts);

return await contract.processMessage(opts.message, proof, {
gasLimit: 1500000,
gasLimit: opts.message.gasLimit.add(1000000),
});
} else {
return await contract.retryMessage(opts.message, {
gasLimit: 1500000,
gasLimit: opts.message.gasLimit.add(1000000),
});
}
}
Expand Down
51 changes: 28 additions & 23 deletions packages/bridge-ui/src/proof/service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,18 @@ const mockProvider = {
send: jest.fn(),
};

const mockContract = {
getLatestSyncedHeader: jest.fn(),
};

jest.mock("ethers", () => ({
/* eslint-disable-next-line */
...(jest.requireActual("ethers") as object),
Contract: function () {
return mockContract;
},
}));

const block = {
parentHash:
"0xa7881266ca0a344c43cb24175d9dbd243b58d45d6ae6ad71310a273a3d1d3afb",
Expand Down Expand Up @@ -67,6 +79,13 @@ const expectedProof =
const expectedProofWithBaseFee =
"0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000360a7881266ca0a344c43cb24175d9dbd243b58d45d6ae6ad71310a273a3d1d3afb1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347000000000000000000000000ea674fdde714fd979de3edf0f56aa9716b898ec8c0dcf937b3f6136dd70a1ad11cc57b040fd410f3c49a5146f20c732895a3cc217273ade6b6ed865a9975ac281da23b90b141a8b607d874d2cd95e65e81336f8e74bb61e381e9238a08b169580f3cbf9b8b79d7d5ee708d3e286103eb291dfd0800000000000400000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000020000000000000000000000000000000000000000000000000100000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b000000000000000000000000000000000000000000000000000000000000007b000000000000000000000000000000000000000000000000000000000000007b000000000000000000000000000000000000000000000000000000000000007b000000000000000000000000000000000000000000000000000000000000007b00000000000000000000000000000000000000000000000000000000000002e0f5ba25df1e92e89a09e0b32063b81795f631100801158f5fa733f2ba26843bd0000000000000000000000000000000000000000000000000000000000000007b0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000001265746865726d696e652d75732d7765737431000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022e1a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";

const srcChain = 167001;
const destChain = 31336;

const map = new Map<number, ethers.providers.JsonRpcProvider>();
map.set(srcChain, mockProvider as unknown as ethers.providers.JsonRpcProvider);
map.set(destChain, mockProvider as unknown as ethers.providers.JsonRpcProvider);

describe("prover tests", () => {
beforeEach(() => {
jest.resetAllMocks();
Expand All @@ -76,7 +95,7 @@ describe("prover tests", () => {
it("throws on invalid proof", async () => {
mockProvider.send.mockImplementation(
(method: string, params: unknown[]) => {
if (method === "eth_getBlockByNumber") {
if (method === "eth_getBlockByHash") {
return block;
}

Expand All @@ -86,13 +105,6 @@ describe("prover tests", () => {
}
);

const srcChain = 167001;
const map = new Map<number, ethers.providers.JsonRpcProvider>();
map.set(
srcChain,
mockProvider as unknown as ethers.providers.JsonRpcProvider
);

const prover: ProofService = new ProofService(map);

await expect(
Expand All @@ -101,14 +113,16 @@ describe("prover tests", () => {
sender: ethers.constants.AddressZero,
srcBridgeAddress: ethers.constants.AddressZero,
srcChain: srcChain,
destChain: destChain,
destHeaderSyncAddress: ethers.constants.AddressZero,
})
).rejects.toThrowError("invalid proof");
});

it("generates proof", async () => {
mockProvider.send.mockImplementation(
(method: string, params: unknown[]) => {
if (method === "eth_getBlockByNumber") {
if (method === "eth_getBlockByHash") {
return block;
}

Expand All @@ -118,28 +132,23 @@ describe("prover tests", () => {
}
);

const srcChain = 167001;
const map = new Map<number, ethers.providers.JsonRpcProvider>();
map.set(
srcChain,
mockProvider as unknown as ethers.providers.JsonRpcProvider
);

const prover: ProofService = new ProofService(map);

const proof = await prover.GenerateProof({
signal: ethers.constants.HashZero,
sender: ethers.constants.AddressZero,
srcBridgeAddress: ethers.constants.AddressZero,
srcChain: srcChain,
destChain: destChain,
destHeaderSyncAddress: ethers.constants.AddressZero,
});
expect(proof).toBe(expectedProof);
});

it("generates proof with baseFeePerGas set", async () => {
mockProvider.send.mockImplementation(
(method: string, params: unknown[]) => {
if (method === "eth_getBlockByNumber") {
if (method === "eth_getBlockByHash") {
return block;
}

Expand All @@ -150,12 +159,6 @@ describe("prover tests", () => {
);

block.baseFeePerGas = "1";
const srcChain = 167001;
const map = new Map<number, ethers.providers.JsonRpcProvider>();
map.set(
srcChain,
mockProvider as unknown as ethers.providers.JsonRpcProvider
);

const prover: ProofService = new ProofService(map);

Expand All @@ -164,6 +167,8 @@ describe("prover tests", () => {
sender: ethers.constants.AddressZero,
srcBridgeAddress: ethers.constants.AddressZero,
srcChain: srcChain,
destChain: destChain,
destHeaderSyncAddress: ethers.constants.AddressZero,
});
expect(proof).toBe(expectedProofWithBaseFee);
});
Expand Down
15 changes: 12 additions & 3 deletions packages/bridge-ui/src/proof/service.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ethers } from "ethers";
import { Contract, ethers } from "ethers";
import { RLP } from "ethers/lib/utils.js";
import HeaderSync from "../constants/abi/HeaderSync";
import type { Block, BlockHeader } from "../domain/block";
import type {
Prover,
Expand All @@ -24,8 +25,16 @@ class ProofService implements Prover {

const provider = this.providerMap.get(opts.srcChain);

const block: Block = await provider.send("eth_getBlockByNumber", [
"latest",
const contract = new Contract(
opts.destHeaderSyncAddress,
HeaderSync,
this.providerMap.get(opts.destChain)
);

const latestSyncedHeader = await contract.getLatestSyncedHeader();

const block: Block = await provider.send("eth_getBlockByHash", [
latestSyncedHeader,
false,
]);

Expand Down
Loading

0 comments on commit c373194

Please sign in to comment.