Skip to content
2 changes: 0 additions & 2 deletions src/adapter/bridges/ArbitrumOrbitBridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,12 @@ import ARBITRUM_ERC20_GATEWAY_L2_ABI from "../../common/abi/ArbitrumErc20Gateway

const bridgeSubmitValue: { [chainId: number]: BigNumber } = {
[CHAIN_IDs.ARBITRUM]: toWei(0.013),
[CHAIN_IDs.ALEPH_ZERO]: toWei(0.45),
// Testnet
[CHAIN_IDs.ARBITRUM_SEPOLIA]: toWei(0.013),
};

const maxFeePerGas: { [chainId: number]: BigNumber } = {
[CHAIN_IDs.ARBITRUM]: toBN(20e9),
[CHAIN_IDs.ALEPH_ZERO]: toBN(24e10),
// Testnet
[CHAIN_IDs.ARBITRUM_SEPOLIA]: toBN(20e9),
};
Expand Down
1 change: 0 additions & 1 deletion src/clients/ProfitClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -664,7 +664,6 @@ export class ProfitClient {
// The relayer _cannot_ be the recipient because the SpokePool skips the ERC20 transfer. Instead, use
// the main RL address because it has all supported tokens and approvals in place on all chains.
const testSymbols = {
[CHAIN_IDs.ALEPH_ZERO]: "USDT", // USDC is not yet supported on AlephZero, so revert to USDT. @todo: Update.
[CHAIN_IDs.BLAST]: "USDB",
[CHAIN_IDs.INK]: "WETH", // USDC deferred on Ink.
[CHAIN_IDs.LENS]: "WETH", // USDC not yet supported.
Expand Down
2 changes: 1 addition & 1 deletion src/common/Config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ export class CommonConfig {
const missing = chainIds.find((chainId) => !lookbackKeys.includes(chainId));
if (missing) {
const message = `Missing MAX_BLOCK_LOOK_BACK configuration for chainId ${missing}`;
logger.warn({ at: "RelayerConfig::validate", message });
logger.warn({ at: "Config::validate", message });
this.maxBlockLookBack[missing] = 5000; // Revert to a safe default.
}
}
Expand Down
23 changes: 3 additions & 20 deletions src/common/Constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ import {
BaseL2BridgeAdapter,
OpStackUSDCBridge as L2OpStackUSDCBridge,
OpStackWethBridge as L2OpStackWethBridge,
ArbitrumOrbitBridge as L2ArbitrumOrbitBridge,
OpStackBridge as L2OpStackBridge,
BinanceCEXBridge as L2BinanceCEXBridge,
UsdcCCTPBridge as L2UsdcCCTPBridge,
Expand Down Expand Up @@ -137,11 +136,11 @@ export const REDIS_URL_DEFAULT = "redis://localhost:6379";
// if the RPC provider allows it. This is why the user should override these lookbacks if they are not using
// Quicknode for example.
export const CHAIN_MAX_BLOCK_LOOKBACK = {
[CHAIN_IDs.ALEPH_ZERO]: 10000,
[CHAIN_IDs.ALEPH_ZERO]: 0, // Disabled
[CHAIN_IDs.ARBITRUM]: 10000,
[CHAIN_IDs.BASE]: 10000,
[CHAIN_IDs.BLAST]: 10000,
[CHAIN_IDs.BOBA]: 4990,
[CHAIN_IDs.BOBA]: 0, // Disabled
[CHAIN_IDs.BSC]: 10000,
[CHAIN_IDs.HYPEREVM]: 1000,
[CHAIN_IDs.INK]: 10000,
Expand Down Expand Up @@ -182,7 +181,7 @@ export const CHAIN_MAX_BLOCK_LOOKBACK = {
// can be matched with a deposit on the origin chain, so something like
// ~1-2 mins per chain.
export const BUNDLE_END_BLOCK_BUFFERS = {
[CHAIN_IDs.ALEPH_ZERO]: 240, // Same as Arbitrum
[CHAIN_IDs.ALEPH_ZERO]: 0, // Chain is disabled.
[CHAIN_IDs.ARBITRUM]: 240, // ~0.25s/block. Arbitrum is a centralized sequencer
[CHAIN_IDs.BASE]: 60, // 2s/block. Same finality profile as Optimism
[CHAIN_IDs.BLAST]: 60,
Expand Down Expand Up @@ -241,7 +240,6 @@ export const IGNORED_HUB_EXECUTED_BUNDLES: number[] = [];
// Provider caching will not be allowed for queries whose responses depend on blocks closer than this many blocks.
// This is intended to be conservative.
export const CHAIN_CACHE_FOLLOW_DISTANCE: { [chainId: number]: number } = {
[CHAIN_IDs.ALEPH_ZERO]: 60,
[CHAIN_IDs.ARBITRUM]: 32,
[CHAIN_IDs.BASE]: 120,
[CHAIN_IDs.BLAST]: 120,
Expand Down Expand Up @@ -285,7 +283,6 @@ export const CHAIN_CACHE_FOLLOW_DISTANCE: { [chainId: number]: number } = {
// These are all intended to be roughly 2 days of blocks for each chain.
// blocks = 172800 / avg_block_time
export const DEFAULT_NO_TTL_DISTANCE: { [chainId: number]: number } = {
[CHAIN_IDs.ALEPH_ZERO]: 691200,
[CHAIN_IDs.ARBITRUM]: 691200,
[CHAIN_IDs.BASE]: 86400,
[CHAIN_IDs.BLAST]: 86400,
Expand Down Expand Up @@ -352,7 +349,6 @@ export const spokesThatHoldNativeTokens = [

// A mapping of L2 chain IDs to an array of tokens Across supports on that chain.
export const SUPPORTED_TOKENS: { [chainId: number]: string[] } = {
[CHAIN_IDs.ALEPH_ZERO]: ["USDT", "WETH"],
[CHAIN_IDs.ARBITRUM]: ["USDC", "USDT", "WETH", "DAI", "WBTC", "UMA", "BAL", "ACX", "POOL", "ezETH"],
[CHAIN_IDs.BASE]: ["BAL", "DAI", "ETH", "WETH", "USDC", "USDT", "POOL", "VLR", "ezETH"],
[CHAIN_IDs.BLAST]: ["DAI", "WBTC", "WETH", "ezETH"],
Expand Down Expand Up @@ -431,7 +427,6 @@ type L1BridgeConstructor<T extends BaseBridgeAdapter> = new (
// Map of chain IDs to all "canonical bridges" for the given chain. Canonical is loosely defined -- in this
// case, it is the default bridge for the given chain.
export const CANONICAL_BRIDGE: Record<number, L1BridgeConstructor<BaseBridgeAdapter>> = {
[CHAIN_IDs.ALEPH_ZERO]: ArbitrumOrbitBridge,
[CHAIN_IDs.ARBITRUM]: ArbitrumOrbitBridge,
[CHAIN_IDs.BASE]: OpStackDefaultERC20Bridge,
[CHAIN_IDs.BLAST]: OpStackDefaultERC20Bridge,
Expand Down Expand Up @@ -477,7 +472,6 @@ export const CANONICAL_L2_BRIDGE: {
): BaseL2BridgeAdapter;
};
} = {
[CHAIN_IDs.ALEPH_ZERO]: L2ArbitrumOrbitBridge,
[CHAIN_IDs.BSC]: L2BinanceCEXBridge,
[CHAIN_IDs.LISK]: L2OpStackBridge,
[CHAIN_IDs.REDSTONE]: L2OpStackBridge,
Expand Down Expand Up @@ -719,10 +713,6 @@ export const CUSTOM_ARBITRUM_GATEWAYS: { [chainId: number]: { [address: string]:

// The default ERC20 gateway is the generic gateway used by Arbitrum Orbit chains to mint tokens which do not have a custom gateway set.
export const DEFAULT_ARBITRUM_GATEWAY: { [chainId: number]: { l1: string; l2: string } } = {
[CHAIN_IDs.ALEPH_ZERO]: {
l1: "0xccaF21F002EAF230c9Fa810B34837a3739B70F7B",
l2: "0x2A5a79061b723BBF453ef7E07c583C750AFb9BD6",
},
[CHAIN_IDs.ARBITRUM]: {
l1: "0xa3A7B6F88361F48403514059F1F16C8E78d60EeC",
l2: "0x09e9222E96E7B4AE2a407B98d48e330053351EEe",
Expand All @@ -749,7 +739,6 @@ export const SCROLL_CUSTOM_GATEWAY: { [chainId: number]: { l1: string; l2: strin

// Expected worst-case time for message from L1 to propagate to L2 in seconds
export const EXPECTED_L1_TO_L2_MESSAGE_TIME = {
[CHAIN_IDs.ALEPH_ZERO]: 20 * 60,
[CHAIN_IDs.ARBITRUM]: 20 * 60,
[CHAIN_IDs.BASE]: 20 * 60,
[CHAIN_IDs.BLAST]: 20 * 60,
Expand Down Expand Up @@ -954,12 +943,6 @@ export const ARBITRUM_ORBIT_L1L2_MESSAGE_FEE_DATA: {
amountWei: 0.02,
amountMultipleToFund: 1,
},
[CHAIN_IDs.ALEPH_ZERO]: {
amountWei: 0.49,
amountMultipleToFund: 50,
feePayer: "0x0d57392895Db5aF3280e9223323e20F3951E81B1", // DonationBox
feeToken: TOKEN_SYMBOLS_MAP.AZERO.addresses[CHAIN_IDs.MAINNET],
},
};

// source: https://github.com/hyperlane-xyz/hyperlane-registry/blob/346b18c4314cf96b41ae2da781f58fb832dbe1f8/deployments/warp_routes/EZETH/arbitrum-base-berachain-blast-bsc-ethereum-fraxtal-linea-mode-optimism-sei-swell-taiko-unichain-worldchain-zircuit-config.yaml
Expand Down
21 changes: 0 additions & 21 deletions src/common/ContractAddresses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,24 +162,13 @@ export const CONTRACT_ADDRESSES: {
address: "0x0B9857ae2D4A3DBe74ffE1d7DF045bb7F96E4840",
abi: ARBITRUM_OUTBOX_ABI,
},
orbitOutbox_41455: {
address: "0x73bb50c32a3BD6A1032aa5cFeA048fBDA3D6aF6e",
abi: ARBITRUM_OUTBOX_ABI,
},
orbitErc20GatewayRouter_42161: {
address: "0x72Ce9c846789fdB6fC1f34aC4AD25Dd9ef7031ef",
abi: ARBITRUM_ERC20_GATEWAY_ROUTER_L1_ABI,
},
orbitErc20Gateway_42161: {
abi: ARBITRUM_ERC20_GATEWAY_L1_ABI,
},
orbitErc20GatewayRouter_41455: {
address: "0xeBb17f398ed30d02F2e8733e7c1e5cf566e17812",
abi: ARBITRUM_ERC20_GATEWAY_ROUTER_L1_ABI,
},
orbitErc20Gateway_41455: {
abi: ARBITRUM_ERC20_GATEWAY_L1_ABI,
},
VotingV2: {
address: "0x004395edb43EFca9885CEdad51EC9fAf93Bd34ac",
abi: VOTING_V2_ABI,
Expand Down Expand Up @@ -466,16 +455,6 @@ export const CONTRACT_ADDRESSES: {
abi: ARBITRUM_ERC20_GATEWAY_ROUTER_L2_ABI,
},
},
[CHAIN_IDs.ALEPH_ZERO]: {
erc20GatewayRouter: {
address: "0xD296d45171B97720D3aBdb68B0232be01F1A9216",
abi: ARBITRUM_ERC20_GATEWAY_ROUTER_L2_ABI,
},
arbSys: {
address: "0x0000000000000000000000000000000000000064",
abi: ARBSYS_L2_ABI,
},
},
[CHAIN_IDs.LENS]: {
nativeTokenVault: {
address: "0x0000000000000000000000000000000000010004",
Expand Down
30 changes: 7 additions & 23 deletions src/dataworker/Dataworker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2659,29 +2659,13 @@ export class Dataworker {
token: EvmAddress;
holder: EvmAddress;
}> {
// TODO: Make this code more dynamic in the future. For now, hard code custom gas token fees.
let relayMessageFee: BigNumber;
let token: string;
let holder: string;
if (leaf.chainId === CHAIN_IDs.ALEPH_ZERO) {
// Unlike when handling native ETH, the monitor bot does NOT support sending arbitrary ERC20 tokens to any other
// EOA, so if we're short a custom gas token like AZERO, then we're going to have to keep sending over token
// amounts to the DonationBox contract. Therefore, we'll multiply the final amount by 10 to ensure we don't incur
// a transfer() gas cost on every single pool rebalance leaf execution involving this arbitrum orbit chain.
const { amountWei, feePayer, feeToken, amountMultipleToFund } =
ARBITRUM_ORBIT_L1L2_MESSAGE_FEE_DATA[CHAIN_IDs.ALEPH_ZERO];
relayMessageFee = toBNWei(amountWei).mul(amountMultipleToFund);
token = feeToken;
holder = feePayer;
} else {
// For now, assume arbitrum message fees are the same for all non-custom gas token chains. This obviously needs
// to be changed if we add support for an orbit chains where we pay message fees in ETH but they are different
// parameters than for Arbitrum mainnet.
const { amountWei, amountMultipleToFund } = ARBITRUM_ORBIT_L1L2_MESSAGE_FEE_DATA[CHAIN_IDs.ARBITRUM];
relayMessageFee = toBNWei(amountWei).mul(amountMultipleToFund);
token = ZERO_ADDRESS;
holder = this.clients.hubPoolClient.hubPool.address;
}
// For now, assume arbitrum message fees are the same for all non-custom gas token chains. This obviously needs
// to be changed if we add support for an orbit chains where we pay message fees in ETH but they are different
// parameters than for Arbitrum mainnet.
const { amountWei, amountMultipleToFund } = ARBITRUM_ORBIT_L1L2_MESSAGE_FEE_DATA[leaf.chainId];
const relayMessageFee = toBNWei(amountWei).mul(amountMultipleToFund);
const token = ZERO_ADDRESS;
const holder = this.clients.hubPoolClient.hubPool.address;

// For orbit chains, the bot needs enough ETH to pay for each L1 -> L2 message.
// The following executions trigger an L1 -> L2 message:
Expand Down
4 changes: 0 additions & 4 deletions src/finalizer/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,6 @@ const chainFinalizers: { [chainId: number]: { finalizeOnL2: ChainFinalizer[]; fi
finalizeOnL1: [opStackFinalizer, cctpL2toL1Finalizer],
finalizeOnL2: [cctpL1toL2Finalizer],
},
[CHAIN_IDs.ALEPH_ZERO]: {
finalizeOnL1: [arbStackFinalizer],
finalizeOnL2: [],
},
[CHAIN_IDs.ARBITRUM]: {
finalizeOnL1: [arbStackFinalizer, cctpL2toL1Finalizer],
finalizeOnL2: [cctpL1toL2Finalizer],
Expand Down
26 changes: 2 additions & 24 deletions src/finalizer/utils/arbStack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,30 +45,8 @@ type PartialArbitrumNetwork = Omit<ArbitrumNetwork, "confirmPeriodBlocks"> & {
registered: boolean;
};
// These network configs are defined in the Arbitrum SDK, and we need to register them in the SDK's memory.
// We should export this out of a common file but we don't use this SDK elsewhere currently.
const ARB_ORBIT_NETWORK_CONFIGS: PartialArbitrumNetwork[] = [
{
// Addresses are available here:
// https://raas.gelato.network/rollups/details/public/aleph-zero-evm
chainId: CHAIN_IDs.ALEPH_ZERO,
name: "Aleph Zero",
parentChainId: CHAIN_IDs.MAINNET,
ethBridge: {
bridge: "0x41Ec9456AB918f2aBA81F38c03Eb0B93b78E84d9",
inbox: "0x56D8EC76a421063e1907503aDd3794c395256AEb ",
sequencerInbox: "0xF75206c49c1694594E3e69252E519434f1579876",
outbox: CONTRACT_ADDRESSES[CHAIN_IDs.MAINNET][`orbitOutbox_${CHAIN_IDs.ALEPH_ZERO}`].address,
rollup: "0x1CA12290D954CFe022323b6A6Df92113ed6b1C98",
},
challengePeriodSeconds: 6 * 60 * 60, // ~ 6 hours
retryableLifetimeSeconds: 7 * 24 * 60 * 60,
nativeToken: TOKEN_SYMBOLS_MAP.AZERO.addresses[CHAIN_IDs.MAINNET],
isTestnet: false,
registered: false,
// Must be set to true for L3's
isCustom: true,
},
];
// We should export this out of a common file but we don't use this SDK elsewhere currentlyl.
const ARB_ORBIT_NETWORK_CONFIGS: PartialArbitrumNetwork[] = [];

function getOrbitNetwork(chainId: number): PartialArbitrumNetwork | undefined {
return ARB_ORBIT_NETWORK_CONFIGS.find((network) => network.chainId === chainId);
Expand Down
109 changes: 0 additions & 109 deletions test/Dataworker.executePoolRebalanceUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,9 @@ import {
bnZero,
buildPoolRebalanceLeafTree,
CHAIN_IDs,
ERC20,
EvmAddress,
getCurrentTime,
toBNWei,
TOKEN_SYMBOLS_MAP,
toAddressType,
} from "../src/utils";
import { MAX_L1_TOKENS_PER_POOL_REBALANCE_LEAF, MAX_REFUNDS_PER_RELAYER_REFUND_LEAF, ZERO_ADDRESS } from "./constants";
Expand All @@ -22,7 +20,6 @@ import {
sinon,
randomAddress,
lastSpyLogIncludes,
assert,
lastSpyLogLevel,
} from "./utils";

Expand Down Expand Up @@ -723,112 +720,6 @@ describe("Dataworker: Utilities to execute pool rebalance leaves", async functio
expect(queuedTransactions[2].method).to.equal("executeRootBundle");
expect(queuedTransactions[3].method).to.equal("executeRootBundle");
});
it("funds custom gas token orbit leaf", async function () {
// Replicate custom gas token setups:
const azero = await smock.fake(ERC20.abi, {
address: TOKEN_SYMBOLS_MAP.AZERO.addresses[CHAIN_IDs.MAINNET],
provider: hubPoolClient.hubPool.signer.provider,
});
// Custom gas token funder for AZERO
const { amountWei, amountMultipleToFund, feePayer } = ARBITRUM_ORBIT_L1L2_MESSAGE_FEE_DATA[CHAIN_IDs.ALEPH_ZERO];
assert(feePayer !== undefined);
const customGasTokenFunder = feePayer;
azero.balanceOf.whenCalledWith(customGasTokenFunder).returns(0);
expect(
await balanceAllocator.getBalance(
hubPoolClient.chainId,
EvmAddress.from(azero.address),
EvmAddress.from(customGasTokenFunder)
)
).to.equal(0);

// Adds one fee per net send amount + one extra if groupIndex = 0
const leaves: PoolRebalanceLeaf[] = [
{
chainId: 41455,
groupIndex: 0,
bundleLpFees: [toBNWei("1"), toBNWei("1")],
netSendAmounts: [toBNWei("1"), toBNWei("1")],
runningBalances: [toBNWei("1"), toBNWei("1")],
leafId: 0,
l1Tokens: [token1, token2],
},
{
chainId: 41455,
groupIndex: 1,
bundleLpFees: [toBNWei("1"), toBNWei("1")],
netSendAmounts: [toBNWei("1"), toBNWei("1")],
runningBalances: [toBNWei("1"), toBNWei("1")],
leafId: 0,
l1Tokens: [token1, token2],
},
];
// Should have a total of 2 + 1 + 2 = 5 fees.
const expectedFee = toBNWei(amountWei).mul(amountMultipleToFund);
const expectedFeeLeaf1 = expectedFee.mul(2).add(expectedFee);
const expectedFeeLeaf2 = expectedFee.mul(2);
azero.balanceOf
.whenCalledWith(await hubPoolClient.hubPool.signer.getAddress())
.returns(expectedFeeLeaf1.add(expectedFeeLeaf2));
const result = await dataworkerInstance._executePoolRebalanceLeaves(
spokePoolClients,
leaves,
balanceAllocator,
buildPoolRebalanceLeafTree(leaves)
);
expect(result).to.equal(2);

// Should submit two transactions to load ETH for each leaf plus pool rebalance leaf execution.
expect(multiCallerClient.transactionCount()).to.equal(4);
const queuedTransactions = multiCallerClient.getQueuedTransactions(hubPoolClient.chainId);
expect(queuedTransactions[0].method).to.equal("transfer");
expect(queuedTransactions[0].args).to.deep.equal([customGasTokenFunder, expectedFeeLeaf1]);
expect(queuedTransactions[1].method).to.equal("transfer");
expect(queuedTransactions[1].args).to.deep.equal([customGasTokenFunder, expectedFeeLeaf2]);
expect(queuedTransactions[2].method).to.equal("executeRootBundle");
expect(queuedTransactions[3].method).to.equal("executeRootBundle");
});
it("fails to fund custom gas token orbit leaf", async function () {
// Replicate custom gas token setups, but this time do not set a balance for the custom gas token funder.
const azero = await smock.fake(ERC20.abi, {
address: TOKEN_SYMBOLS_MAP.AZERO.addresses[CHAIN_IDs.MAINNET],
provider: hubPoolClient.hubPool.signer.provider,
});
// Custom gas token funder for AZERO
const customGasTokenFunder = "0x0d57392895Db5aF3280e9223323e20F3951E81B1";
azero.balanceOf.whenCalledWith(customGasTokenFunder).returns(0);
expect(
await balanceAllocator.getBalance(
hubPoolClient.chainId,
EvmAddress.from(azero.address),
EvmAddress.from(customGasTokenFunder)
)
).to.equal(0);

// Adds one fee per net send amount + one extra if groupIndex = 0
const leaves: PoolRebalanceLeaf[] = [
{
chainId: 41455,
groupIndex: 0,
bundleLpFees: [toBNWei("1"), toBNWei("1")],
netSendAmounts: [toBNWei("1"), toBNWei("1")],
runningBalances: [toBNWei("1"), toBNWei("1")],
leafId: 0,
l1Tokens: [token1, token2],
},
];
// Should throw an error if caller doesn't have enough custom gas token to fund
// DonationBox.
const result = await dataworkerInstance._executePoolRebalanceLeaves(
spokePoolClients,
leaves,
balanceAllocator,
buildPoolRebalanceLeafTree(leaves)
);
expect(result).to.equal(0);
expect(lastSpyLogLevel(spy)).to.equal("error");
expect(lastSpyLogIncludes(spy, "Failed to fund")).to.be.true;
});
it("Ignores leaves without sufficient reserves to execute", async function () {
// Should only be able to execute the first leaf
balanceAllocator.testSetBalance(
Expand Down