Skip to content

Commit e20dfe4

Browse files
committed
WIP
Signed-off-by: Matt Rice <[email protected]>
1 parent b008199 commit e20dfe4

31 files changed

+501
-237
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,5 @@ test-ledger
3838
src/svm/assets
3939
src/svm/clients/*
4040
!src/svm/clients/index.ts
41+
42+
**/.claude/settings.local.json

deployments/deployments.json

+6-3
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@
4242
"UniswapV3_SwapAndBridge": { "address": "0x6f4A733c7889f038D77D4f540182Dda17423CcbF", "blockNumber": 120044742 },
4343
"AcrossMerkleDistributor": { "address": "0xc8b31410340d57417bE62672f6B53dfB9de30aC2", "blockNumber": 114652330 },
4444
"SpokePoolVerifier": { "address": "0x3Fb9cED51E968594C87963a371Ed90c39519f65A", "blockNumber": 135440379 },
45-
"MulticallHandler": { "address": "0x924a9f036260DdD5808007E1AA95f08eD08aA569", "blockNumber": 122513129 }
45+
"MulticallHandler": { "address": "0x924a9f036260DdD5808007E1AA95f08eD08aA569", "blockNumber": 122513129 },
46+
"AcrossOriginSettler": { "address": "0x5cC9dde9Fdc4fE3A910006709bFa7A39155ef93f", "blockNumber": 135580184 }
4647
},
4748
"11155420": {
4849
"SpokePool": { "address": "0x4e8E101924eDE233C13e2D8622DC8aED2872d505", "blockNumber": 7762656 },
@@ -107,7 +108,8 @@
107108
"SpokePoolVerifier": { "address": "0x3Fb9cED51E968594C87963a371Ed90c39519f65A", "blockNumber": 29844942 },
108109
"1inch_SwapAndBridge": { "address": "0x7CFaBF2eA327009B39f40078011B0Fb714b65926", "blockNumber": 14450808 },
109110
"UniswapV3_SwapAndBridge": { "address": "0xbcfbCE9D92A516e3e7b0762AE218B4194adE34b4", "blockNumber": 14450714 },
110-
"MulticallHandler": { "address": "0x924a9f036260DdD5808007E1AA95f08eD08aA569", "blockNumber": 16917922 }
111+
"MulticallHandler": { "address": "0x924a9f036260DdD5808007E1AA95f08eD08aA569", "blockNumber": 16917922 },
112+
"AcrossOriginSettler": { "address": "0x514496264fa0B4Ee0522bC7Db644F78B02AEb1ae", "blockNumber": 29984972 }
111113
},
112114
"34443": {
113115
"SpokePool": { "address": "0x3baD7AD0728f9917d1Bf08af5782dCbD516cDd96", "blockNumber": 8043187 },
@@ -119,7 +121,8 @@
119121
"SpokePoolVerifier": { "address": "0x3Fb9cED51E968594C87963a371Ed90c39519f65A", "blockNumber": 333624754 },
120122
"1inch_SwapAndBridge": { "address": "0xC456398D5eE3B93828252e48beDEDbc39e03368E", "blockNumber": 211175795 },
121123
"UniswapV3_SwapAndBridge": { "address": "0xF633b72A4C2Fb73b77A379bf72864A825aD35b6D", "blockNumber": 211175481 },
122-
"MulticallHandler": { "address": "0x924a9f036260DdD5808007E1AA95f08eD08aA569", "blockNumber": 230779625 }
124+
"MulticallHandler": { "address": "0x924a9f036260DdD5808007E1AA95f08eD08aA569", "blockNumber": 230779625 },
125+
"AcrossOriginSettler": { "address": "0xDE5cFBDE966bF8a187a332EC9c5081A2c8a537c5", "blockNumber": 334742335 }
123126
},
124127
"59144": {
125128
"SpokePool": { "address": "0x7E63A5f1a8F0B4d0934B2f2327DAED3F6bb2ee75", "blockNumber": 2721169 },

foundry.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ via_ir = true
2626
optimizer_runs = 800
2727
solc_version = "0.8.23"
2828
revert_strings = "strip"
29-
3029
solc = "0.8.23"
3130
evm_version = "shanghai"
31+
fs_permissions = [{ access = "read-write", path = "./"}]
3232

3333
[rpc_endpoints]
3434
ethereum = "${NODE_URL_1}"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
// SPDX-License-Identifier: BUSL-1.1
2+
pragma solidity ^0.8.0;
3+
4+
import { Script } from "forge-std/Script.sol";
5+
import { console } from "forge-std/console.sol";
6+
import { ChainUtils } from "../utils/ChainUtils.sol";
7+
import { AcrossOriginSettler } from "../../contracts/erc7683/AcrossOriginSettler.sol";
8+
import { SpokePool } from "../../contracts/SpokePool.sol";
9+
import { IPermit2 } from "../../contracts/external/interfaces/IPermit2.sol";
10+
11+
/**
12+
* @title DeployAcrossOriginSettler
13+
* @notice Deploy script for the AcrossOriginSettler contract
14+
* @dev This contract deploys AcrossOriginSettler and sets up destination settlers for all supported chains
15+
*/
16+
contract DeployAcrossOriginSettler is Script, ChainUtils {
17+
// Standard Permit2 address on most chains
18+
address constant PERMIT2_ADDRESS = 0x000000000022D473030F116dDEE9F6B43aC78BA3;
19+
20+
// Time parameter for calculating quote timestamp
21+
uint256 constant QUOTE_BEFORE_DEADLINE = 1800; // 30 minutes in seconds
22+
23+
// JSON file containing deployments
24+
string constant DEPLOYMENTS_FILE = "./deployments/deployments.json";
25+
26+
function run() external {
27+
string memory deployerMnemonic = vm.envString("MNEMONIC");
28+
uint256 deployerPrivateKey = vm.deriveKey(deployerMnemonic, 0);
29+
address deployer = vm.addr(deployerPrivateKey);
30+
uint256 chainId = block.chainid;
31+
32+
// Get current chain's SpokePool address
33+
address spokePoolAddress = getSpokePoolFromDeployments(chainId);
34+
35+
// If no SpokePool deployment found, use a dummy address for testing
36+
if (spokePoolAddress == address(0)) {
37+
console.log("No SpokePool deployment found for chain %s, using dummy address for testing", chainId);
38+
spokePoolAddress = address(0x1234567890123456789012345678901234567890);
39+
}
40+
41+
console.log("Deploying AcrossOriginSettler on chain %s", chainId);
42+
console.log("Deployer: %s", deployer);
43+
console.log("SpokePool: %s", spokePoolAddress);
44+
console.log("Permit2: %s", PERMIT2_ADDRESS);
45+
console.log("Quote Before Deadline: %s", QUOTE_BEFORE_DEADLINE);
46+
47+
vm.startBroadcast(deployerPrivateKey);
48+
49+
// Deploy AcrossOriginSettler
50+
AcrossOriginSettler originSettler = new AcrossOriginSettler(
51+
SpokePool(payable(spokePoolAddress)),
52+
IPermit2(PERMIT2_ADDRESS),
53+
QUOTE_BEFORE_DEADLINE
54+
);
55+
console.log("AcrossOriginSettler deployed at: %s", address(originSettler));
56+
57+
// Set up destination settlers for supported chains
58+
// Each supported chain will have its SpokePool registered as a destination settler
59+
setDestinationSettlers(originSettler);
60+
61+
// Renounce ownership after setting up all destination settlers
62+
// This means no further changes can be made to the destination settlers
63+
console.log("Renouncing ownership of AcrossOriginSettler contract");
64+
originSettler.renounceOwnership();
65+
console.log("Ownership renounced");
66+
67+
// Log deployment information for manual addition to deployments.json
68+
console.log("");
69+
console.log("=== DEPLOYMENT SUMMARY ===");
70+
console.log("Chain ID: %s", chainId);
71+
console.log("AcrossOriginSettler deployed at: %s", address(originSettler));
72+
console.log("Block number: %s", block.number);
73+
console.log("");
74+
console.log("Please add this entry to deployments.json:");
75+
console.log("{");
76+
console.log(' "%s": {', chainId);
77+
console.log(' "AcrossOriginSettler": {');
78+
console.log(' "address": "%s",', address(originSettler));
79+
console.log(' "blockNumber": %s', block.number);
80+
console.log(" }");
81+
console.log(" }");
82+
console.log("}");
83+
console.log("=========================");
84+
85+
vm.stopBroadcast();
86+
}
87+
88+
/**
89+
* @notice Set destination settlers for all supported chains
90+
* @param originSettler The deployed AcrossOriginSettler contract
91+
*/
92+
function setDestinationSettlers(AcrossOriginSettler originSettler) internal {
93+
// Array of supported chain IDs to set destinations for
94+
uint256[] memory supportedChains = getSupportedChains();
95+
96+
for (uint256 i = 0; i < supportedChains.length; i++) {
97+
uint256 destChainId = supportedChains[i];
98+
99+
// Skip current chain as we don't need to set it as a destination
100+
if (destChainId == block.chainid) continue;
101+
102+
// Get the SpokePool address from deployments.json
103+
address spokePoolAddress = getSpokePoolFromDeployments(destChainId);
104+
105+
// Skip chains with no deployment
106+
if (spokePoolAddress == address(0)) {
107+
console.log("No SpokePool found for chain %s, skipping", destChainId);
108+
continue;
109+
}
110+
111+
console.log("Setting destination settler for chain %s: %s", destChainId, spokePoolAddress);
112+
originSettler.setDestinationSettler(destChainId, spokePoolAddress);
113+
}
114+
}
115+
116+
/**
117+
* @notice Returns list of supported chain IDs
118+
* @return Array of supported chain IDs
119+
*/
120+
function getSupportedChains() internal pure returns (uint256[] memory) {
121+
// Include all mainnet chains from deployments.json
122+
uint256[] memory chains = new uint256[](15);
123+
chains[0] = MAINNET; // Ethereum
124+
chains[1] = OPTIMISM; // Optimism
125+
chains[2] = ARBITRUM; // Arbitrum
126+
chains[3] = POLYGON; // Polygon
127+
chains[4] = BASE; // Base
128+
chains[5] = ZK_SYNC; // ZkSync
129+
chains[6] = LINEA; // Linea
130+
chains[7] = SCROLL; // Scroll
131+
chains[8] = BLAST; // Blast
132+
chains[9] = MODE; // Mode
133+
chains[10] = ZORA; // Zora
134+
chains[11] = BSC; // BNB Chain
135+
chains[12] = 41455; // Aleph Zero (actual chain ID used in deployments.json)
136+
chains[13] = 232; // Lisk (based on deployments.json)
137+
chains[14] = 57073; // Redstone (based on deployments.json)
138+
return chains;
139+
}
140+
141+
/**
142+
* @notice Get SpokePool address from deployments.json
143+
* @param chainId The chain ID to find the SpokePool for
144+
* @return The SpokePool address for the given chain, or address(0) if not found
145+
*/
146+
function getSpokePoolFromDeployments(uint256 chainId) internal view returns (address) {
147+
string memory json = vm.readFile(DEPLOYMENTS_FILE);
148+
string memory chainIdStr = vm.toString(chainId);
149+
string memory queryPath = string.concat(".", chainIdStr, ".SpokePool.address");
150+
151+
console.log("Looking for SpokePool for chain ID %s", chainIdStr);
152+
153+
try vm.parseJson(json, queryPath) returns (bytes memory data) {
154+
address spokePoolAddress = abi.decode(data, (address));
155+
if (spokePoolAddress != address(0)) {
156+
console.log("Found SpokePool entry in deployments.json: %s", spokePoolAddress);
157+
return spokePoolAddress;
158+
}
159+
} catch (bytes memory) {
160+
// Try SVM spoke for Solana-based chains
161+
try vm.parseJson(json, string.concat(".", chainIdStr, ".SvmSpoke.address")) returns (bytes memory data) {
162+
address spokePoolAddress = abi.decode(data, (address));
163+
if (spokePoolAddress != address(0)) {
164+
console.log("Found SvmSpoke entry in deployments.json: %s", spokePoolAddress);
165+
return spokePoolAddress;
166+
}
167+
} catch (bytes memory) {
168+
console.log("No SpokePool entry found in deployments.json for chain %s", chainIdStr);
169+
}
170+
}
171+
172+
return address(0);
173+
}
174+
}

script/deployments/DeployAlephzeroSpokePool.s.sol

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ contract DeployAlephzeroSpokePool is Script, ChainUtils {
4545
vm.startBroadcast(deployerPrivateKey);
4646

4747
// Deploy implementation contract
48-
// Alephzero_SpokePool spokePoolImplementationImplementation = new Alephzero_SpokePool(
48+
// Alephzero_SpokePool spokePoolImplementation = new Alephzero_SpokePool(
4949
// wrappedNativeToken,
5050
// QUOTE_TIME_BUFFER,
5151
// FILL_DEADLINE_BUFFER,

script/deployments/DeployArbitrumSpokePool.s.sol

+3-3
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ contract DeployArbitrumSpokePool is Script, ChainUtils {
4444
vm.startBroadcast(deployerPrivateKey);
4545

4646
// Deploy implementation contract
47-
Arbitrum_SpokePool spokePoolImplementationImplementation = new Arbitrum_SpokePool(
47+
Arbitrum_SpokePool spokePoolImplementation = new Arbitrum_SpokePool(
4848
weth,
4949
QUOTE_TIME_BUFFER,
5050
FILL_DEADLINE_BUFFER,
@@ -74,8 +74,8 @@ contract DeployArbitrumSpokePool is Script, ChainUtils {
7474
vm.stopBroadcast();
7575
}
7676

77-
// Placeholder function for getting L2 addresses - this would be implemented in ChainUtils
78-
function getL2Address(uint256 chainId, string memory key) internal pure returns (address) {
77+
// Override getL2Address with specific Arbitrum implementation
78+
function getL2Address(uint256 chainId, string memory key) public pure override returns (address) {
7979
if (chainId == ARBITRUM) {
8080
if (compareStrings(key, "l2GatewayRouter")) return 0x5288c571Fd7aD117beA99bF60FE0846C4E84F933;
8181
if (compareStrings(key, "cctpTokenMessenger")) return 0x19330d10D9Cc8751218eaf51E8885D058642E08A;

script/deployments/DeployBobaSpokePool.s.sol

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ contract DeployBobaSpokePool is Script, ChainUtils {
4545
vm.startBroadcast(deployerPrivateKey);
4646

4747
// Deploy implementation contract
48-
// Boba_SpokePool spokePoolImplementationImplementation = new Boba_SpokePool(
48+
// Boba_SpokePool spokePoolImplementation = new Boba_SpokePool(
4949
// wrappedNativeToken,
5050
// QUOTE_TIME_BUFFER,
5151
// FILL_DEADLINE_BUFFER,

script/deployments/DeployCherSpokePool.s.sol

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ contract DeployCherSpokePool is Script, ChainUtils {
4545
vm.startBroadcast(deployerPrivateKey);
4646

4747
// Deploy implementation contract
48-
// Cher_SpokePool spokePoolImplementationImplementation = new Cher_SpokePool(
48+
// Cher_SpokePool spokePoolImplementation = new Cher_SpokePool(
4949
// wrappedNativeToken,
5050
// QUOTE_TIME_BUFFER,
5151
// FILL_DEADLINE_BUFFER,

script/deployments/DeployEthereumSpokePool.s.sol

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ contract DeployEthereumSpokePool is Script, ChainUtils {
3636
vm.startBroadcast(deployerPrivateKey);
3737

3838
// Deploy implementation contract
39-
Ethereum_SpokePool spokePoolImplementationImplementation = new Ethereum_SpokePool(
39+
Ethereum_SpokePool spokePoolImplementation = new Ethereum_SpokePool(
4040
weth,
4141
QUOTE_TIME_BUFFER,
4242
FILL_DEADLINE_BUFFER

script/deployments/DeployEvmSpokePool.s.sol

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ contract DeployEvmSpokePool is Script, ChainUtils {
4545
vm.startBroadcast(deployerPrivateKey);
4646

4747
// Deploy implementation contract
48-
// Evm_SpokePool spokePoolImplementationImplementation = new Evm_SpokePool(
48+
// Evm_SpokePool spokePoolImplementation = new Evm_SpokePool(
4949
// wrappedNativeToken,
5050
// QUOTE_TIME_BUFFER,
5151
// FILL_DEADLINE_BUFFER,

script/deployments/DeployInkSpokePool.s.sol

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ contract DeployInkSpokePool is Script, ChainUtils {
4545
vm.startBroadcast(deployerPrivateKey);
4646

4747
// Deploy implementation contract
48-
// Ink_SpokePool spokePoolImplementationImplementation = new Ink_SpokePool(
48+
// Ink_SpokePool spokePoolImplementation = new Ink_SpokePool(
4949
// wrappedNativeToken,
5050
// QUOTE_TIME_BUFFER,
5151
// FILL_DEADLINE_BUFFER,

script/deployments/DeployLensSpokePool.s.sol

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ contract DeployLensSpokePool is Script, ChainUtils {
4545
vm.startBroadcast(deployerPrivateKey);
4646

4747
// Deploy implementation contract
48-
// Lens_SpokePool spokePoolImplementationImplementation = new Lens_SpokePool(
48+
// Lens_SpokePool spokePoolImplementation = new Lens_SpokePool(
4949
// wrappedNativeToken,
5050
// QUOTE_TIME_BUFFER,
5151
// FILL_DEADLINE_BUFFER,

script/deployments/DeployLineaSpokePool.s.sol

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ contract DeployLineaSpokePool is Script, ChainUtils {
4545
vm.startBroadcast(deployerPrivateKey);
4646

4747
// Deploy implementation contract
48-
// Linea_SpokePool spokePoolImplementationImplementation = new Linea_SpokePool(
48+
// Linea_SpokePool spokePoolImplementation = new Linea_SpokePool(
4949
// wrappedNativeToken,
5050
// QUOTE_TIME_BUFFER,
5151
// FILL_DEADLINE_BUFFER,

script/deployments/DeployLiskSpokePool.s.sol

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ contract DeployLiskSpokePool is Script, ChainUtils {
4545
vm.startBroadcast(deployerPrivateKey);
4646

4747
// Deploy implementation contract
48-
// Lisk_SpokePool spokePoolImplementationImplementation = new Lisk_SpokePool(
48+
// Lisk_SpokePool spokePoolImplementation = new Lisk_SpokePool(
4949
// wrappedNativeToken,
5050
// QUOTE_TIME_BUFFER,
5151
// FILL_DEADLINE_BUFFER,

script/deployments/DeployModeSpokePool.s.sol

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ contract DeployModeSpokePool is Script, ChainUtils {
4545
vm.startBroadcast(deployerPrivateKey);
4646

4747
// Deploy implementation contract
48-
// Mode_SpokePool spokePoolImplementationImplementation = new Mode_SpokePool(
48+
// Mode_SpokePool spokePoolImplementation = new Mode_SpokePool(
4949
// wrappedNativeToken,
5050
// QUOTE_TIME_BUFFER,
5151
// FILL_DEADLINE_BUFFER,

0 commit comments

Comments
 (0)