Skip to content

Commit

Permalink
Merge branch 'nfts-trailblazers-badges-contracts' of ssh://github.com…
Browse files Browse the repository at this point in the history
…/taikoxyz/taiko-mono into nfts-trailblazers-badges-contracts
  • Loading branch information
bearni95 committed Jun 11, 2024
2 parents f2158bb + 0ebd726 commit 081403e
Show file tree
Hide file tree
Showing 25 changed files with 415 additions and 67 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script lang="ts">
import { t } from 'svelte-i18n';
import { importDone } from '$components/Bridge/state';
import { calculatingProcessingFee, importDone } from '$components/Bridge/state';
import { BridgeSteps, BridgingStatus } from '$components/Bridge/types';
import { ActionButton } from '$components/Button';
import { Icon } from '$components/Icon';
Expand Down Expand Up @@ -66,7 +66,7 @@
manuallyConfirmedRecipientStep = false;
};
$: disabled = !$account || !$account.isConnected;
$: disabled = !$account || !$account.isConnected || $calculatingProcessingFee;
$: nextStepButtonText = getStepText();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script lang="ts">
import { t } from 'svelte-i18n';
import { importDone } from '$components/Bridge/state';
import { calculatingProcessingFee, importDone } from '$components/Bridge/state';
import { BridgeSteps, BridgingStatus, ImportMethod } from '$components/Bridge/types';
import { ActionButton } from '$components/Button';
import { StepBack } from '$components/Stepper';
Expand Down Expand Up @@ -69,7 +69,7 @@
{/if}
{/if}
{#if activeStep === BridgeSteps.REVIEW}
<ActionButton priority="primary" on:click={() => handleNextStep()}>
<ActionButton priority="primary" disabled={$calculatingProcessingFee} on:click={() => handleNextStep()}>
<span class="body-bold">{nextStepButtonText}</span>
</ActionButton>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import Alert from '$components/Alert/Alert.svelte';
import FlatAlert from '$components/Alert/FlatAlert.svelte';
import { gasLimitZero, processingFee, processingFeeMethod } from '$components/Bridge/state';
import { calculatingProcessingFee, gasLimitZero, processingFee, processingFeeMethod } from '$components/Bridge/state';
import { ActionButton, CloseButton } from '$components/Button';
import { InputBox } from '$components/InputBox';
import { LoadingText } from '$components/LoadingText';
Expand All @@ -26,7 +26,6 @@
let dialogId = `dialog-${uid()}`;
let recommendedAmount = BigInt(0);
let calculatingRecommendedAmount = false;
let errorCalculatingRecommendedAmount = false;
let calculatingEnoughEth = false;
Expand Down Expand Up @@ -161,7 +160,7 @@
<div class="f-between-center">
<span class="text-secondary-content">{$t('processing_fee.title')}</span>
<span class=" text-primary-content mt-[4px]">
{#if calculatingRecommendedAmount}
{#if $calculatingProcessingFee}
<LoadingText mask="0.0017730224073" /> ETH
{:else if errorCalculatingRecommendedAmount && $processingFeeMethod === ProcessingFeeMethod.RECOMMENDED}
<FlatAlert type="warning" message={$t('processing_fee.recommended.error')} />
Expand All @@ -175,7 +174,7 @@
</div>
{:else if textOnly}
<span class="text-primary-content mt-[4px] {$$props.class}">
{#if calculatingRecommendedAmount}
{#if $calculatingProcessingFee}
<LoadingText mask="0.0017730224073" />
{:else if errorCalculatingRecommendedAmount && $processingFeeMethod === ProcessingFeeMethod.RECOMMENDED}
<span class="text-warning-sentiment">{$t('processing_fee.recommended.error')}</span>
Expand All @@ -201,7 +200,7 @@
</div>

<span class="body-small-regular text-secondary-content mt-[4px]">
{#if calculatingRecommendedAmount}
{#if $calculatingProcessingFee}
<LoadingText mask="0.0001" /> ETH
{:else if errorCalculatingRecommendedAmount && $processingFeeMethod === ProcessingFeeMethod.RECOMMENDED}
<FlatAlert type="warning" message={$t('processing_fee.recommended.error')} />
Expand Down Expand Up @@ -234,7 +233,7 @@
</label>
<span class="body-small-regular text-secondary-content">
<!-- TODO: think about the UI for this part. Talk to Jane -->
{#if calculatingRecommendedAmount}
{#if $calculatingProcessingFee}
<LoadingText mask="0.0001" /> ETH
{:else if errorCalculatingRecommendedAmount}
<FlatAlert type="warning" message={$t('processing_fee.recommended.error')} />
Expand Down Expand Up @@ -383,10 +382,7 @@
</div>
{/if}

<RecommendedFee
bind:amount={recommendedAmount}
bind:calculating={calculatingRecommendedAmount}
bind:error={errorCalculatingRecommendedAmount} />
<RecommendedFee bind:amount={recommendedAmount} bind:error={errorCalculatingRecommendedAmount} />

<NoneOption
bind:enoughEth={hasEnoughEth}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
<script lang="ts">
import { onDestroy, onMount } from 'svelte';
import { destNetwork, selectedToken } from '$components/Bridge/state';
import { calculatingProcessingFee, destNetwork, selectedToken } from '$components/Bridge/state';
import { processingFeeComponent } from '$config';
import { recommendProcessingFee } from '$libs/fee';
import type { NFT, Token } from '$libs/token';
import { connectedSourceChain } from '$stores/network';
export let amount: bigint;
export let calculating = false;
export let error = false;
let interval: ReturnType<typeof setInterval>;
Expand All @@ -17,7 +16,7 @@
// Without token nor destination chain we cannot compute this fee
if (!token || !destChainId) return;
calculating = true;
$calculatingProcessingFee = true;
error = false;
try {
Expand All @@ -30,7 +29,7 @@
console.error(err);
error = true;
} finally {
calculating = false;
$calculatingProcessingFee = false;
}
}
Expand Down
1 change: 1 addition & 0 deletions packages/bridge-ui/src/components/Bridge/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export const bridging = writable<boolean>(false);
export const approving = writable<boolean>(false);
export const computingBalance = writable<boolean>(false);
export const validatingAmount = writable<boolean>(false);
export const calculatingProcessingFee = writable<boolean>(false);

// Errors state
export const errorComputingBalance = writable<boolean>(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
{ value: MessageStatus.RETRIABLE, label: $t('transactions.filter.retry') },
{ value: MessageStatus.DONE, label: $t('transactions.filter.claimed') },
{ value: MessageStatus.FAILED, label: $t('transactions.filter.failed') },
{ value: MessageStatus.RECALLED, label: $t('transactions.filter.released') },
];
const select = (option: (typeof options)[0]) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
{ value: MessageStatus.RETRIABLE, label: $t('transactions.filter.retry') },
{ value: MessageStatus.DONE, label: $t('transactions.filter.claimed') },
{ value: MessageStatus.FAILED, label: $t('transactions.filter.failed') },
{ value: MessageStatus.RECALLED, label: $t('transactions.filter.released') },
];
const toggleMenu = () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,9 @@
<button class="status-btn" on:click={release} on:click={handleReleaseClick}>
{$t('transactions.button.release')}
</button>
{:else if bridgeTxStatus === MessageStatus.RECALLED}
<StatusDot type="error" />
<span>{$t('transactions.status.released.name')}</span>
{:else}
<!-- TODO: look into this possible state -->
<StatusDot type="error" />
Expand Down
10 changes: 7 additions & 3 deletions packages/bridge-ui/src/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"nft_scan_again": "Scan again"
},
"alerts": {
"not_enough_funds": "You do not have enough ETH to cover the processing fee and transaction fee",
"not_enough_funds": "You do not have enough ETH to cover the processing fee and transaction fee. Please add more ETH to your wallet (>= 0.0015 ETH).",
"slow_bridging": "Please note: Bridging to L1 will take around 24hrs!",
"smart_contract_wallet": "It seems you are using a smart contract wallet. Please double check that the recipient matches your wallet on the destination or change it accordingly.",
"stable_coin": "You are bridging a stable coin. For USDC, we are currently partnering with <a target=\"_blank\" href=\"https://stargate.finance/transfer\" class=\"link\">Stargate Bridge</a> for liquidity. Consider using their bridge, as the ecosystem partners are likely using their bridged version",
Expand Down Expand Up @@ -291,7 +291,7 @@
},
"title": "Faucet",
"warning": {
"insufficient_balance": "You don't have enough ETH to complete the transaction. Please add some ETH to your wallet.",
"insufficient_balance": "You don't have enough ETH to complete the transaction. Please add more ETH to your wallet (>= 0.0015 ETH)",
"no_connected": "Please connect your wallet to mint tokens.",
"not_mintable": "This token is not mintable on this network. Please switch to the correct network.",
"token_minted": "You have already minted this token.",
Expand Down Expand Up @@ -503,7 +503,7 @@
"title": "What is \"Connected to the correct chain\"?"
},
"funds": {
"description": "In order to claim the transaction yourself, you need enough funds on the destination chain. If you've kept the default processing fee, the relayer will likely claim for you soon.",
"description": "In order to claim the transaction yourself, you need enough funds on the destination chain (>= 0.0015 ETH). If you've kept the default processing fee, the relayer will likely claim for you soon.",
"title": "What is \"Sufficient funds to claim\"?"
},
"quota": {
Expand Down Expand Up @@ -532,6 +532,7 @@
"claimed": "Claimed",
"failed": "Failed",
"processing": "Processing",
"released": "Released",
"retry": "Retriable",
"title": "Filters"
},
Expand Down Expand Up @@ -592,6 +593,9 @@
"description": "Your bridged asset cannot be processed and is now accessible to you on the source chain.",
"name": "Release"
},
"released": {
"name": "Released"
},
"releasing": "Releasing",
"retry": {
"description": "The relayer was unable to process this message, and you will need to retry the processing yourself.",
Expand Down
2 changes: 1 addition & 1 deletion packages/bridge-ui/src/libs/bridge/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export enum MessageStatus {
RETRIABLE,
DONE,
FAILED,
PROVEN, // UI ONLY
RECALLED,
}

// struct Message {
Expand Down
24 changes: 24 additions & 0 deletions packages/bridge-ui/src/libs/polling/messageStatusPoller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ export function startPolling(bridgeTx: BridgeTransaction, runImmediately = true)
transport: http(),
});

const srcChainClient = createPublicClient({
chain: chains.find((chain) => chain.id === Number(srcChainId)),
transport: http(),
});

// We are gonna be polling the destination bridge contract
const destBridgeAddress = routingContractsMap[Number(destChainId)][Number(srcChainId)].bridgeAddress;
const destBridgeContract = getContract({
Expand All @@ -79,6 +84,14 @@ export function startPolling(bridgeTx: BridgeTransaction, runImmediately = true)
client: destChainClient,
});

// In case for recalled messages we need to check the source bridge contract
const srcBridgeAddress = routingContractsMap[Number(srcChainId)][Number(destChainId)].bridgeAddress;
const srcBridgeContract = getContract({
address: srcBridgeAddress,
abi: bridgeAbi,
client: srcChainClient,
});

const stopPolling = () => {
const interval = hashIntervalMap[hash];
if (interval) {
Expand Down Expand Up @@ -108,6 +121,17 @@ export function startPolling(bridgeTx: BridgeTransaction, runImmediately = true)
const messageStatus: MessageStatus = await destBridgeContract.read.messageStatus([bridgeTx.msgHash]);
emitter.emit(PollingEvent.STATUS, messageStatus);

if (messageStatus === MessageStatus.FAILED) {
// check if the message is recalled
const recallStatus = await srcBridgeContract.read.messageStatus([bridgeTx.msgHash]);
if (recallStatus === MessageStatus.RECALLED) {
log(`Message ${bridgeTx.msgHash} has been recalled.`);
emitter.emit(PollingEvent.STATUS, MessageStatus.RECALLED);
stopPolling();
return;
}
}

let blockNumber: Hex;
if (!bridgeTx.blockNumber) {
const receipt = await getTransactionReceipt(config, { hash: bridgeTx.hash });
Expand Down
34 changes: 31 additions & 3 deletions packages/bridge-ui/src/libs/proof/BridgeProver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ export class BridgeProver {
}

async getEncodedSignalProofForRecall({ bridgeTx }: { bridgeTx: BridgeTransaction }) {
const { message, msgHash } = bridgeTx;
const { blockNumber, message, msgHash } = bridgeTx;

log('msgHash', msgHash);
if (!message) throw new ProofGenerationError('Message is not defined');
Expand Down Expand Up @@ -304,8 +304,36 @@ export class BridgeProver {
// Get the signalServiceAddress for the source chain
const destSignalServiceAddress =
routingContractsMap[Number(destChainId)][Number(srcChainId)].signalServiceAddress;
const srcSignalServiceAddress = routingContractsMap[Number(srcChainId)][Number(destChainId)].signalServiceAddress;

const syncedChainData = await readContract(config, {
address: srcSignalServiceAddress,
abi: signalServiceAbi,
functionName: 'getSyncedChainData',
args: [destChainId, keccak256(toBytes('STATE_ROOT')), 0n],
chainId: Number(srcChainId),
});

log('syncedChainData', syncedChainData);

const latestSyncedblock = syncedChainData[0];

const synced = latestSyncedblock >= hexToBigInt(blockNumber);
log('synced', synced, latestSyncedblock, hexToBigInt(blockNumber));
if (!synced) {
throw new BlockNotSyncedError('block is not synced yet');
}

const block = await destChainClient.getBlock({ blockTag: 'latest' });
// Get the block based on the blocknumber from the destination chain
let block;
try {
block = await destChainClient.getBlock({ blockNumber: latestSyncedblock });
if (!block || block.hash === null || block.number === null) {
throw new BlockNotFoundError({ blockNumber: latestSyncedblock });
}
} catch {
throw new BlockNotFoundError({ blockNumber: latestSyncedblock });
}

const signal = await this.getSignalForFailedMessage(msgHash);

Expand All @@ -330,7 +358,7 @@ export class BridgeProver {

// Build the hopProof
const hopProof: HopProof = {
chainId: BigInt(destChainId),
chainId: BigInt(srcChainId),
blockId: BigInt(block.number),
rootHash: block.stateRoot,
cacheOption: 0n, // Todo: could be configurable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ contract TrailblazersBadges is ERC721EnumerableUpgradeable, ECDSAWhitelist {
external
initializer
{
__ERC721_init("TrailblazersBadges", "TBB");
__ERC721_init("Trailblazers Badges", "TBB");
_baseURIExtended = _rootURI;
__ECDSAWhitelist_init(_owner, _mintSigner, _blacklistAddress);
}
Expand Down Expand Up @@ -126,7 +126,6 @@ contract TrailblazersBadges is ERC721EnumerableUpgradeable, ECDSAWhitelist {
/// @param _badgeId The badge ID to mint
function _mintBadgeTo(bytes memory _signature, address _minter, uint256 _badgeId) internal {
if (_badgeId > BADGE_SHINTO) revert INVALID_BADGE_ID();
if (!canMint(_signature, _minter, _badgeId)) revert MINTER_NOT_WHITELISTED();

_consumeMint(_signature, _minter, _badgeId);

Expand Down
3 changes: 1 addition & 2 deletions packages/protocol/contracts/tokenvault/ERC20Vault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -355,8 +355,6 @@ contract ERC20Vault is BaseVault {
private
returns (address token_)
{
_consumeTokenQuota(token_, _amount);

if (_ctoken.chainId == block.chainid) {
token_ = _ctoken.addr;
IERC20(token_).safeTransfer(_to, _amount);
Expand All @@ -366,6 +364,7 @@ contract ERC20Vault is BaseVault {
// check.
IBridgedERC20(token_).mint(_to, _amount);
}
_consumeTokenQuota(token_, _amount);
}

/// @dev Handles the message on the source chain and returns the encoded
Expand Down
Loading

0 comments on commit 081403e

Please sign in to comment.