Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
6eadbad
feat: dynamicGasLimit added to queues and unit tests completed
0xHarbs Jul 29, 2025
fdd635b
chore: staging impl addresses updates and missing spokes added to dep…
0xHarbs Aug 7, 2025
6e309e0
feat: deploy scripts tron
0xHarbs Mar 26, 2025
12eb31a
fix: tron deploy script working
0xHarbs Apr 9, 2025
7341bbe
chore: linting
0xHarbs May 29, 2025
7b2b570
fix: gateway deploy and read scripts
0xHarbs Jun 30, 2025
16c91aa
feat: polymer config
0xHarbs Jul 1, 2025
4862fd9
chore: deployment addresses
0xHarbs Jul 11, 2025
6446e36
chore: new gateway address
0xHarbs Jul 11, 2025
15cdde3
chore: constants file
0xHarbs Jul 15, 2025
7606c87
chore: feeAdapter prod
0xHarbs Jul 15, 2025
8a8e958
feat: tron scripts
0xHarbs Aug 7, 2025
c6caeed
feat: upgrade deployment script (wip)
0xHarbs Aug 7, 2025
696a986
feat: tron signer script and pending tx
0xHarbs Aug 7, 2025
e70c154
fix: signing upgradeToAndCall
0xHarbs Aug 7, 2025
b1459ef
feat: updated sign script and prod tx
0xHarbs Aug 7, 2025
10f5826
feat: new deploy script and txs
0xHarbs Aug 8, 2025
d7f26a7
fix: updateFeeAdapter to tx
0xHarbs Aug 8, 2025
b3cf548
feat: signatures added
0xHarbs Aug 8, 2025
9877ea1
feat: updated signing scripts to support hot wallets
0xHarbs Aug 13, 2025
05b7c0d
fix: tron multi-sig signing
0xHarbs Oct 7, 2025
67727ef
chore: updating constants
0xHarbs Oct 8, 2025
15ac61f
fix: viem package issue
0xHarbs Oct 8, 2025
ffbb48f
fix: removing console from tests
0xHarbs Oct 8, 2025
907d70e
fix: tronweb types
0xHarbs Oct 16, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/build-test-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ jobs:
MONITOR_POLLER_IMAGE: chimera-${{ github.sha }}
LIGHTHOUSE_IMAGE: chimera-${{ github.sha }}
CARTOGRAPHER_IMAGE: chimera-${{ github.sha }}
WEB3_SIGNER_PRIVATE_KEY_RELAYER: '0x0dbbe8e4ae425a6d2687f1a7e3ba17bc98c673636790f1b8ad91193c05875ef1'
WEB3_SIGNER_PRIVATE_KEY_RELAYER: ''
MAINNET_RPC: ${{ secrets.MAINNET_RPC }}
SEPOLIA_RPC: ${{ secrets.SEPOLIA_RPC }}
BNB_TESTNET_RPC: ${{ secrets.BSC_RPC }}
Expand Down Expand Up @@ -426,7 +426,7 @@ jobs:
MONITOR_POLLER_IMAGE: chimera-${{ github.sha }}
LIGHTHOUSE_IMAGE: chimera-${{ github.sha }}
CARTOGRAPHER_IMAGE: chimera-${{ github.sha }}
WEB3_SIGNER_PRIVATE_KEY_RELAYER: '0x0dbbe8e4ae425a6d2687f1a7e3ba17bc98c673636790f1b8ad91193c05875ef1'
WEB3_SIGNER_PRIVATE_KEY_RELAYER: ''
MNEMONIC: 'candy maple cake sugar pudding cream honey rich smooth crumble sweet treat'
SCROLL_SEPOLIA_RPC: 'https://sepolia-rpc.scroll.io'
SEPOLIA_RPC: 'https://ethereum-sepolia-rpc.publicnode.com'
Expand Down
80 changes: 73 additions & 7 deletions .gitleaks.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,78 @@

[[rules]]
id = "tron-hex-private-key"
description = "64-char hex TRON private key"
regex = '''(?i)\b[0-9a-f]{64}\b'''
description = "TRON private key in raw hex (64 chars) with context"
severity = "HIGH"

[[rules]]
id = "tron-base58-private-key"
description = "Base58 private key starting with T"
regex = '''\bT[1-9A-HJ-NP-Za-km-z]{50,55}\b'''
severity = "HIGH"
# ───── primary pattern ─────
# \b … \b guarantees the blob is bounded by a non‑word character
# (quote, whitespace, colon, newline, etc.) or start/end of line.
regex = '''(?i)\b([0-9a-f]{64})\b'''
secretGroup = 1 # <-- the single capture is the key itself

# ───── fast pre‑filter ─────
keywords = [
"tron", "trx",
"private_key", "priv_key",
"secret", "priv"
]

# ───── proximity check ─────
[[rules.required]]
id = "tron-context"
regex = '''(?i)(tron).*?(priv(?:ate)?|key)'''
withinLines = 2 # only alert if these words are ±2 lines away

# ───── optional allow‑list ─────
[[rules.allowlists]]
description = "CID‑v1 (sha2‑256) multihash"
regexTarget = "secret" # test the captured secret itself
regexes = ['''(?i)^1220[0-9a-f]{60}$''']

[[rules.allowlists]]
description = "Test keys and constants"
regexTarget = "secret" # test the captured secret itself
regexes = [
'''(?i)^da146374a75310b9666e834ee4ad0866d6f4035967bfc76217c5a495fff9f0d0$''', # test key
'''(?i)^f4a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2$''', # test key
'''(?i)^1234567890123456789012345678901234567890123456789012345678901234$''', # test key
'''(?i)^9876543210987654321098765432109876543210987654321098765432109876$''', # test key
'''(?i)^d7c1222cb9b938dffb88f406623278e5d53b8b2c93b5dd2e876ea69f8703df7b$''', # test key
'''(?i)^60ae88d633895594a5ca9d3c901e709f44d2743ab87371299cff49a87c0cb947$''', # transaction hash
'''(?i)^c7923bfa09cb350d4fca3715b1a44ead8e546086f891386584bca2a3a1c35d10$''', # test key
'''(?i)^ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff$''', # maxUint constant
'''(?i)^000000000000000000000000000000000000000000000000000000000004cce0$''', # token ID
'''(?i)^bc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b$''', # event selector
'''(?i)^7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f$''', # event selector
'''(?i)^1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e$''', # event selector
'''(?i)^c7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2$''', # event selector
'''(?i)^8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0$''', # event selector
'''(?i)^0bd568acd9b697a50a11ec16a1a231542877bf551632163d9cfc61b40e7f6e22$''', # transaction hash
]

[[rules.allowlists]]
description = "Event selectors and contract artifacts"
regexTarget = "match" # test the full match context
regexes = [
'''(?i)eventSelector''', # event selectors in contract artifacts
'''(?i)maxUint''', # Solidity constants
'''(?i)TEST_''', # test files
'''(?i)test-''', # test files
'''(?i)\.spec\.''', # test files
'''(?i)\.test\.''', # test files
'''(?i)build/contracts''', # build artifacts
'''(?i)lib/''', # library files
]

[allowlist]
description = "Ignore node_modules and env files"
paths = [
"node_modules/",
".*\\.env$",
"packages/contracts/lib/", # ignore library files
"packages/contracts/build/", # ignore build artifacts
".*/build/.*", # ignore all build directories
".*/test/.*", # ignore test directories
".*\\.spec\\..*", # ignore spec files
".*\\.test\\..*", # ignore test files
]
2 changes: 1 addition & 1 deletion packages/adapters/chainservice/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,6 @@
"ethers": "5.7.2",
"interval-promise": "1.4.0",
"p-queue": "6.6.2",
"tronweb": "^6.0.3"
"tronweb": "beta"
}
}
5 changes: 4 additions & 1 deletion packages/contracts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,14 +79,17 @@
"@coral-xyz/anchor": "^0.30.1",
"@hyperlane-xyz/core": "3.8.1",
"@inquirer/prompts": "^5.3.8",
"@ledgerhq/hw-app-trx": "^6.31.4",
"@ledgerhq/hw-transport-node-hid": "^6.29.9",
"@openzeppelin/contracts": "5.0.2",
"@openzeppelin/contracts-upgradeable": "5.0.2",
"@solana-developers/helpers": "^2.8.1",
"dotenv": "^16.4.5",
"isolmate": "github:defi-wonderland/isolmate#59e18043c2450fef550f1744b3705ce9ebcaf1c8",
"tronweb": "beta",
"ts-node": "^10.9.2",
"tweetnacl": "^1.0.3",
"viem": "^2.19.8"
"viem": "2.19.8"
},
"devDependencies": {
"@commitlint/cli": "17.0.3",
Expand Down
9 changes: 5 additions & 4 deletions packages/contracts/script/MainnetStaging.sol
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,10 @@ abstract contract Ethereum {
IEverclearSpoke public ETHEREUM_SPOKE = IEverclearSpoke(0xD95Ff203bAAd65A8Fafd5C3dB695FC0a77A809a3);
ISpokeGateway public ETHEREUM_SPOKE_GATEWAY = ISpokeGateway(0xF712520F89d295dFdcC4d71B7E8787c060f44e39);
ICallExecutor public ETHEREUM_EXECUTOR = ICallExecutor(0xcA48aCE7387574a6120392722eB6f2018C60eF3B);
address public ETHEREUM_SPOKE_IMPL = 0x8B5401516fBf40621fec17A3b8D15D5E16754107;

address public constant ETHEREUM_FEE_ADAPTER = 0x7621D1085559Ab35513E2a41EC948a8524F619D9;
IXERC20Module public ETHEREUM_XERC20_MODULE = IXERC20Module(0xDEe6fD45a585fa890BA12262AFc2312adE23e41e);
address public ETHEREUM_SPOKE_IMPL = 0x8B5401516fBf40621fec17A3b8D15D5E16754107;
address public constant ETHEREUM_ENG_MULTISIG = 0xBc8988C7a4b77c1d6df7546bd876Ea4D42DF0837;
}

abstract contract ArbitrumOne {
Expand All @@ -103,7 +104,7 @@ abstract contract Optimism {
ISpokeGateway public OPTIMISM_SPOKE_GATEWAY = ISpokeGateway(0xe051C7AdB6F24Ee8c9d94DD23106C51D94858d12);
ICallExecutor public OPTIMISM_EXECUTOR = ICallExecutor(0x81fFF6085F4A77a2e1E6fd31d0F5b972fE869226);
IXERC20Module public OPTIMISM_XERC20_MODULE = IXERC20Module(0xE4197BC6b18E2BE0BAF09c13DA8239B40005D541);
address public OPTIMISM_SPOKE_IMPL = 0x172A786fA844A3fa0aEE2031D7955F82f7a8a984;
address public OPTIMISM_SPOKE_IMPL = 0x3404e2F93ebE912a0C2b8315f7eD1c6eC5686873;
address public constant OPTIMISM_ENG_MULTISIG = 0xf20d5277aD2f301E2F18e2948fF3e72Ad0A6dfF9;

address public OPTIMISM_FEE_ADAPTER = 0xF4a697B7A48e9c7C1944a68a11d3b8D5E716d169;
Expand Down Expand Up @@ -136,7 +137,7 @@ abstract contract Base {
ICallExecutor public BASE_EXECUTOR = ICallExecutor(0x81fFF6085F4A77a2e1E6fd31d0F5b972fE869226);

IXERC20Module public BASE_XERC20_MODULE = IXERC20Module(0xE4197BC6b18E2BE0BAF09c13DA8239B40005D541);
address public BASE_SPOKE_IMPL = 0xdC30374790080dA7AFc5b2dFc300029eDE9BfE71;
address public BASE_SPOKE_IMPL = 0x3404e2F93ebE912a0C2b8315f7eD1c6eC5686873;
address public constant BASE_ENG_MULTISIG = 0xf20d5277aD2f301E2F18e2948fF3e72Ad0A6dfF9;

address public BASE_FEE_ADAPTER = 0x4F35c530D3C023717E2BBafdfEacEeE79C4c1e89;
Expand Down
9 changes: 9 additions & 0 deletions packages/contracts/script/deploy/Adapters.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,15 @@ contract MainnetProduction is DeployAdapterBase, MainnetProductionEnvironment {

contract MainnetStaging is DeployAdapterBase, MainnetStagingEnvironment {
function setUp() public {
//// Ethereum
_deploymentParams[ETHEREUM] = DeploymentParams({ // set domain id as mapping key
spoke: address(ETHEREUM_SPOKE),
xerc20Module: address(ETHEREUM_XERC20_MODULE),
feeRecipient: ETHEREUM_ENG_MULTISIG,
feeSigner: L2_FEE_SIGNER,
owner: ETHEREUM_ENG_MULTISIG
});

//// Arbitrum One
_deploymentParams[ARBITRUM_ONE] = DeploymentParams({ // set domain id as mapping key
spoke: address(ARBITRUM_ONE_SPOKE),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.25;

import {ScriptUtils} from '../../utils/Utils.sol';

import {TypeCasts} from 'contracts/common/TypeCasts.sol';
import {Script} from 'forge-std/Script.sol';
import {console2} from 'forge-std/console2.sol';

import {EverclearSpokeV5} from 'contracts/intent/EverclearSpokeV5.sol';

import {MainnetProductionEnvironment} from '../../MainnetProduction.sol';
import {MainnetStagingEnvironment} from '../../MainnetStaging.sol';
import {ICREATE3} from './ICREATE3.sol';

contract DeployDynamicGasLimitUpgrade is Script, ScriptUtils {
using TypeCasts for bytes32;

struct DeploymentParams {
address owner;
address spokeProxy;
address create3;
}

bytes32 internal constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
address public constant CREATE_3 = 0x9fBB3DF7C40Da2e5A0dE984fFE2CCB7C47cd0ABf;

// CREATE3 addresses
address public constant LIFI_CREATE3 = 0x93FEC2C00BfE902F733B57c5a6CeeD7CD1384AE1;
address public constant LIFI_LONDON_CREATE3 = 0x8437A5fE47A4Df14700c96DF1870824e72FA8499;
address public constant LIFI_INK_CREATE3 = 0xeBbbaC35500713C4AD49929e1bE4225c7efF6510;
address public constant LIFI_BERACHAIN_CREATE3 = 0x5f63A2d7850776465b84Bc0fe6284BBC8188dbC7;

mapping(uint256 _chainId => DeploymentParams _params) internal _deploymentParams;

error EmptyProxy();
error Create3DeploymentFailed();

function run() public {
DeploymentParams memory _params = _deploymentParams[block.chainid];
if (_params.spokeProxy == address(0)) revert EmptyProxy();

vm.startBroadcast();
address newEverclearSpoke;

// Generating the inputs for CREATE3
uint8 version = 1;
bytes32 _salt = keccak256(abi.encodePacked(_params.spokeProxy, version));
bytes32 _implementationSalt = keccak256(abi.encodePacked(_salt, 'implementation'));
bytes memory _creation = type(EverclearSpokeV5).creationCode;

// Deploying the new implementation via CREATE3
bytes memory create3Calldata = abi.encodeWithSelector(ICREATE3.deploy.selector, _implementationSalt, _creation);
(bool success, bytes memory returnData) = _params.create3.call(create3Calldata);
if (!success) revert Create3DeploymentFailed();
newEverclearSpoke = abi.decode(returnData, (address));

vm.stopBroadcast();

console2.log('------------------------------------------------');
console2.log('Deployed spoke impl to:', newEverclearSpoke, ' for chainId:', block.chainid);
console2.log('Chain ID:', block.chainid);
console2.log('------------------------------------------------');
}
}

contract MainnetStaging is DeployDynamicGasLimitUpgrade, MainnetStagingEnvironment {
function setUp() public {
//// Ethereum
_deploymentParams[ETHEREUM] =
DeploymentParams({owner: OWNER, spokeProxy: address(ETHEREUM_SPOKE), create3: CREATE_3}); // set domain id as mapping key

//// Arbitrum One
_deploymentParams[ARBITRUM_ONE] =
DeploymentParams({owner: OWNER, spokeProxy: address(ARBITRUM_ONE_SPOKE), create3: CREATE_3}); // set domain id as mapping key

//// Optimism
_deploymentParams[OPTIMISM] =
DeploymentParams({owner: OWNER, spokeProxy: address(OPTIMISM_SPOKE), create3: CREATE_3}); // set domain id as mapping key

// Base
_deploymentParams[BASE] = DeploymentParams({owner: OWNER, spokeProxy: address(BASE_SPOKE), create3: CREATE_3}); // set domain id as mapping key
}
}

contract MainnetProduction is DeployDynamicGasLimitUpgrade, MainnetProductionEnvironment {
function setUp() public {
//// Arbitrum One
_deploymentParams[ARBITRUM_ONE] =
DeploymentParams({owner: OWNER, spokeProxy: address(ARBITRUM_ONE_SPOKE), create3: CREATE_3}); // set domain id as mapping key

//// Optimism
_deploymentParams[OPTIMISM] =
DeploymentParams({owner: OWNER, spokeProxy: address(OPTIMISM_SPOKE), create3: CREATE_3}); // set domain id as mapping key

//// Base
_deploymentParams[BASE] = DeploymentParams({owner: OWNER, spokeProxy: address(BASE_SPOKE), create3: CREATE_3}); // set domain id as mapping key

//// Bnb
_deploymentParams[BNB] = DeploymentParams({owner: OWNER, spokeProxy: address(BNB_SPOKE), create3: CREATE_3}); // set domain id as mapping key

//// Ethereum
_deploymentParams[ETHEREUM] =
DeploymentParams({owner: OWNER, spokeProxy: address(ETHEREUM_SPOKE), create3: CREATE_3}); // set domain id as mapping key

// Zircuit
_deploymentParams[ZIRCUIT] =
DeploymentParams({owner: OWNER, spokeProxy: address(ZIRCUIT_SPOKE), create3: address(0)}); // set domain id as mapping key

// Blast
_deploymentParams[BLAST] = DeploymentParams({owner: OWNER, spokeProxy: address(BLAST_SPOKE), create3: CREATE_3}); // set domain id as mapping key

// Linea
_deploymentParams[LINEA] =
DeploymentParams({owner: OWNER, spokeProxy: address(LINEA_SPOKE), create3: LIFI_LONDON_CREATE3}); // set domain id as mapping key

// Polygon
_deploymentParams[POLYGON] = DeploymentParams({owner: OWNER, spokeProxy: address(POLYGON_SPOKE), create3: CREATE_3}); // set domain id as mapping key

// Avalanche
_deploymentParams[AVALANCHE] =
DeploymentParams({owner: OWNER, spokeProxy: address(AVALANCHE_SPOKE), create3: CREATE_3}); // set domain id as mapping key

// Taiko
_deploymentParams[TAIKO] =
DeploymentParams({owner: OWNER, spokeProxy: address(TAIKO_SPOKE), create3: LIFI_LONDON_CREATE3}); // set domain id as mapping key

// Scroll
_deploymentParams[SCROLL] =
DeploymentParams({owner: OWNER, spokeProxy: address(SCROLL_SPOKE), create3: LIFI_CREATE3}); // set domain id as mapping key

// Apechain
_deploymentParams[APECHAIN] =
DeploymentParams({owner: OWNER, spokeProxy: address(APECHAIN_SPOKE), create3: LIFI_CREATE3}); // set domain id as mapping key

// Mode
_deploymentParams[MODE] = DeploymentParams({owner: OWNER, spokeProxy: address(MODE_SPOKE), create3: LIFI_CREATE3}); // set domain id as mapping key

// Unichain
_deploymentParams[UNICHAIN] =
DeploymentParams({owner: OWNER, spokeProxy: address(UNICHAIN_SPOKE), create3: CREATE_3}); // set domain id as mapping key

// Ronin
_deploymentParams[RONIN] = DeploymentParams({owner: OWNER, spokeProxy: address(RONIN_SPOKE), create3: address(0)}); // set domain id as mapping key

// Gnosis
_deploymentParams[GNOSIS] = DeploymentParams({owner: OWNER, spokeProxy: address(GNOSIS_SPOKE), create3: CREATE_3}); // set domain id as mapping key

// Berachain
_deploymentParams[BERACHAIN] =
DeploymentParams({owner: OWNER, spokeProxy: address(BERACHAIN_SPOKE), create3: LIFI_BERACHAIN_CREATE3}); // set domain id as mapping key

// Mantle
_deploymentParams[MANTLE] =
DeploymentParams({owner: OWNER, spokeProxy: address(MANTLE_SPOKE), create3: LIFI_CREATE3}); // set domain id as mapping key

// Sonic
_deploymentParams[SONIC] = DeploymentParams({owner: OWNER, spokeProxy: address(SONIC_SPOKE), create3: LIFI_CREATE3}); // set domain id as mapping key

// Ink
_deploymentParams[INK] = DeploymentParams({owner: OWNER, spokeProxy: address(INK_SPOKE), create3: LIFI_INK_CREATE3}); // set domain id as mapping key
}
}
Loading
Loading