@across-protocol/contracts

中文文档
5.0.28发布于 2026/11/06AGPL-3.0-onlyTypeScriptCommonJS近 30 天下载 2万

Across-logo

原始使用文档
文档目录13 节
  1. Understanding Upgradeability
  2. Deployed Contract Versions
  3. Requirements
  4. Build
  5. Test
  6. Lint
  7. Deploy and Verify
  8. EVM
  9. SVM
  10. Miscellaneous topics
  11. Slither
  12. ZK Sync Adapter
  13. License

Across-logo

Contains smart contract suite to enable instant token transfers between any two networks. Relays are backstopped by liquidity held in a central HubPool on Ethereum, which also serves as the cross-chain administrator of all contracts in the system. SpokePool contracts are deployed to any network that wants to originate token deposits or be the final destination for token transfers, and they are all governed by the HubPool on Ethereum.

These contracts have been continuously audited by OpenZeppelin and the audit reports can be found here.

Understanding Upgradeability

The SpokePool contracts are UUPSUpgradeable Proxy contracts which means that their addresses will always be the same but their implementation code can change.

All SpokePools can be upgraded if the "admin" of the contract calls upgradeTo. The SpokePool's admin is set by implementing the _requireAdminSender() virtual function in the child contract. For example here are the Arbitrum and Optimism implementations of the admin check.

All SpokePools are implemented such that the admin is the HubPool, and therefore we describe the SpokePools as having "cross-chain ownership". The owner of the HubPool can call this function to send a cross-chain execution of upgradeTo on any SpokePool in order to upgrade it.

This script is useful for creating the calldata to execute a cross-chain upgrade via the HubPool.

Deployed Contract Versions

The latest contract deployments can be found in /broadcast/deployed-addresses.json (auto-generated by yarn extract-addresses).

Requirements

This repository assumes you have Node installed, using the CI version 22.23.4 or a later patched Node 22 release. Depending on what you want to do with the repo you might also need foundry and anchor to also be installed. If you have build issues please ensure these are both installed first.

If you've never used anchor before you might need to run avm use latest as well.

Build

yarn
yarn build # Will build all code. Compile solidity & rust (local toolchain), generate ts outputs
yarn build-verified # Will build all code. Compile solidity & rust (verified docker build), generate ts outputs

EVM builds and tests use the Foundry version pinned in .foundry-version; CI installs exactly that version via foundry-rs/foundry-toolchain. Run yarn pin-foundry to switch your local toolchain to it (a no-op when it already matches). Bump the pin by editing that file.

Test

yarn test # Run all unit tests without gas analysis, using local toolchain SVM build
yarn test-verified # Run all unit tests (without gas analysis) with verified SVM docker build
yarn test:gas-analytics # Run only tests that count gas costs
yarn test:report-gas # Run unit tests with gas reporting enabled
yarn test-evm # Only test EVM code
yarn test-svm # Only test SVM code (local toolchain build)
yarn test-svm-solana-verify # Only test SVM code (verified docker build)

Lint

yarn lint
yarn lint-js # Only lint Javascript
yarn lint-rust # Only lint rust
yarn lint-solidity # Only lint solidity
yarn lint-fix

Deploy and Verify

EVM

Foundry

forge build

forge script script/001DeployHubPool.s.sol:DeployHubPool --rpc-url ethereum --broadcast --verify -vvvv

Foundry (ZKSync)

To enable ZKSync support, the zksync fork of foundry must be installed (see here for instructions).

Also, the FOUNDRY_PROFILE environment variable must be set to zksync.

FOUNDRY_PROFILE=zksync forge script script/016DeployZkSyncSpokePool.s.sol:DeployZkSyncSpokePool --rpc-url zksync --broadcast --verify -vvvv

Alternatively, the yarn forge-script-zksync command can be used to deploy the contract.

yarn forge-script-zksync script/016DeployZkSyncSpokePool.s.sol:DeployZkSyncSpokePool --rpc-url zksync --broadcast --verify -vvvv

SVM

Before deploying for the first time make sure all program IDs in lib.rs and Anchor.toml are the same as listed when running anchor keys list. If not, update them to match the deployment keypairs under target/deploy/ and commit the changes.

Make sure to use the verified docker binaries that can be built:

unset IS_TEST # Ensures the production build is used (not the test feature)
yarn build-svm-solana-verify # Builds verified SVM binaries
yarn generate-svm-artifacts # Builds IDLs

Export required environment variables, e.g.:

export RPC_URL=https://api.devnet.solana.com
export KEYPAIR=~/.config/solana/dev-wallet.json
export PROGRAM=svm_spoke # Also repeat the deployment process for multicall_handler
export PROGRAM_ID=$(cat target/idl/$PROGRAM.json | jq -r ".address")
export MULTISIG= # Export the Squads vault, not the multisig address!
export SOLANA_VERSION=$(grep -A 2 'name = "solana-program"' Cargo.lock | grep 'version' | head -n 1 | cut -d'"' -f2)

For the initial deployment also need these:

export SVM_CHAIN_ID=$(cast to-dec $(cast shr $(cast shl $(cast keccak solana-devnet) 208) 208))
export HUB_POOL=0x14224e63716afAcE30C9a417E0542281869f7d9e # This is for sepolia, update for mainnet
export DEPOSIT_QUOTE_TIME_BUFFER=3600
export FILL_DEADLINE_BUFFER=21600
export MAX_LEN=$(( 2 * $(stat -c %s target/deploy/$PROGRAM.so) )) # Reserve twice the size of the program for future upgrades

Initial deployment

Deploy the program and set the upgrade authority to the multisig:

solana program deploy \
  --url $RPC_URL \
  --keypair $KEYPAIR \
  --program-id target/deploy/$PROGRAM-keypair.json \
  --max-len $MAX_LEN \
  --with-compute-unit-price 100000 \
  --max-sign-attempts 100 \
  --use-rpc \
  target/deploy/$PROGRAM.so
solana program set-upgrade-authority \
  --url $RPC_URL \
  --keypair $KEYPAIR \
  --skip-new-upgrade-authority-signer-check \
  $PROGRAM_ID \
  --new-upgrade-authority $MULTISIG

Update and commit deployments/legacy-addresses.json with the deployed program ID and deployment slot.

Upload the IDL and set the upgrade authority to the multisig:

anchor idl init \
  --provider.cluster $RPC_URL \
  --provider.wallet $KEYPAIR \
  --filepath target/idl/$PROGRAM.json \
  $PROGRAM_ID
anchor idl set-authority \
  --provider.cluster $RPC_URL \
  --provider.wallet $KEYPAIR \
  --program-id $PROGRAM_ID \
  --new-authority $MULTISIG

svm_spoke also requires initialization and transfer of ownership on the first deployment:

anchor run initialize \
  --provider.cluster $RPC_URL \
  --provider.wallet $KEYPAIR -- \
  --chainId $SVM_CHAIN_ID \
  --remoteDomain 0 \
  --crossDomainAdmin $HUB_POOL \
  --svmAdmin $MULTISIG \
  --depositQuoteTimeBuffer $DEPOSIT_QUOTE_TIME_BUFFER \
  --fillDeadlineBuffer $FILL_DEADLINE_BUFFER

Create the vault for accepting deposits, e.g.:

export MINT=4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU # This is USDC on devnet, update with address for mainnet
anchor run createVault \
  --provider.cluster $RPC_URL \
  --provider.wallet $KEYPAIR -- \
  --originToken $MINT

sponsored_cctp_src_periphery requires initialization and setting minimum deposit amount for supported burn token:

# Replace --quoteSigner with actual quote signer address
anchor run initializeSponsoredCctpSrc \
  --provider.cluster $RPC_URL \
  --provider.wallet $KEYPAIR -- \
  --quoteSigner 0x0000000000000000000000000000000000000000
# Below is USDC on devnet, replace --burnToken with mainnet burn token and --amount with required minimum deposit amount (raw value)
anchor run setMinimumDepositSponsoredCctpSrc \
  --provider.cluster $RPC_URL \
  --provider.wallet $KEYPAIR -- \
  --burnToken 4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU \
  --amount 0

Upgrades

Initiate the program upgrade:

solana program write-buffer \
  --url $RPC_URL \
  --keypair $KEYPAIR \
  --with-compute-unit-price 100000 \
  --max-sign-attempts 100 \
  --use-rpc \
  target/deploy/$PROGRAM.so
export BUFFER= # Export the logged buffer address from the command above
solana program set-buffer-authority \
  --url $RPC_URL \
  --keypair $KEYPAIR \
  $BUFFER \
  --new-buffer-authority $MULTISIG

Add the program ID to Squads multisig (https://devnet.squads.so/ for devnet and https://app.squads.so/ for mainnet) in the Developers/Programs section. Then add the upgrade filling in the buffer address and buffer refund. After creating the upgrade verify the buffer authority as prompted and proceed with initiating the upgrade. Once all required signers have approved, execute the upgrade in the transactions section.

Start the IDL upgrade by writing it to the buffer:

anchor idl write-buffer \
  --provider.cluster $RPC_URL \
  --provider.wallet $KEYPAIR \
  --filepath target/idl/$PROGRAM.json \
  $PROGRAM_ID
export IDL_BUFFER= # Export the logged IDL buffer address from the command above
anchor idl set-authority \
  --provider.cluster $RPC_URL \
  --provider.wallet $KEYPAIR \
  --program-id $PROGRAM_ID \
  --new-authority $MULTISIG \
  $IDL_BUFFER

Construct the multisig transaction for finalizing the IDL upgrade. Copy the printed base58 encoded transaction from below command and import it into the Squads multisig for approval and execution:

anchor run squadsIdlUpgrade -- \
  --programId $PROGRAM_ID \
  --idlBuffer $IDL_BUFFER \
  --multisig $MULTISIG \
  --closeRecipient $(solana address --keypair $KEYPAIR)

Verify

Start with verifying locally that the deployed program matches the source code of the public repository:

solana-verify verify-from-repo \
  --url $RPC_URL \
  --program-id $PROGRAM_ID \
   --library-name $PROGRAM \
   --base-image "solanafoundation/solana-verifiable-build:$SOLANA_VERSION" \
  https://github.com/across-protocol/contracts

When prompted, don't yet upload the verification data to the blockchain as that should be done by the multisig. Proceed with creating the upload transaction and then import and sign/execute it in the Squads multisig:

solana-verify export-pda-tx \
  --url $RPC_URL \
  --program-id $PROGRAM_ID \
  --library-name $PROGRAM  \
  --base-image "solanafoundation/solana-verifiable-build:$SOLANA_VERSION" \
  --uploader $MULTISIG \
  https://github.com/across-protocol/contracts

Note that the initial upload transaction might fail if the multisig vault does not have enough SOL for PDA creation. In that case, transfer the required funds to the multisig vault before executing the upload transaction.

Finally, submit the verification to OtterSec API (only works on mainnet):

solana-verify remote submit-job \
  --url $RPC_URL \
  --program-id $PROGRAM_ID \
  --uploader $MULTISIG

Miscellaneous topics

Slither

Slither is a Solidity static analysis framework written in Python 3. It runs a suite of vulnerability detectors, prints visual information about contract details, and provides an API to easily write custom analyses. Slither enables developers to find vulnerabilities, enhance their code comprehension, and quickly prototype custom analyses.

Spire-Contracts has been analyzed using [email protected] and no major bugs was found. To rerun the analytics, run:

slither contracts/SpokePool.sol
\ --solc-remaps @=node_modules/@
\ --solc-args "--optimize --optimize-runs 1000000"
\ --filter-paths "node_modules"
\ --exclude naming-convention

You can replace SpokePool.sol with the specific contract you want to analyze.

ZK Sync Adapter

ZK EVM's typically require a special compiler to convert Solidity into code that can be run on the ZK VM.

There are special instructions for compiling and deploying contracts on zksync. The compile command will create artifacts-zk and cache-zk directories.

Compile

This step requires Docker Desktop to be running, as the solc docker image is fetched as a prerequisite.

yarn compile-zksync

License

All code in this repository is licensed under BUSL-1.1 unless specified differently in the file. Individual exceptions to this license can be made by Risk Labs, which holds the rights to this software and design. If you are interested in using the code or designs in a derivative work, feel free to reach out to [email protected].

版本与发布记录

@across-protocol/contracts 共发布 154 个版本,首次发布于 2021/12/08;过去 12 个月发布了 86 个版本。

版本发布日期距今
5.0.28latest2026/11/061 天前
6.0.0-beta.4beta2026/10/1523 天前
6.0.0-beta.32026/10/1325 天前
5.0.272026/09/171 个月前
6.0.0-beta.22026/09/121 个月前
5.0.262026/07/313 个月前

其他发布通道:alpha → 5.0.16-alpha.2,beta → 6.0.0-beta.4。

关于 @across-protocol/contracts 的常见问题

如何安装 @across-protocol/contracts?

在项目目录运行 npm install @across-protocol/contracts,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:buffer-layout(^1.2.2)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@across-protocol/contracts 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@across-protocol/contracts 支持 ESM 还是 CommonJS?

以 CommonJS 形式发布,可以直接 require();在 ES Module 项目中也可以用 import 引入(Node.js 会把 module.exports 作为默认导出)。

@across-protocol/contracts 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=22.18.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@across-protocol/contracts 可以商用吗?

@across-protocol/contracts 使用 AGPL-3.0-only 许可。最严格的 Copyleft:除分发外,通过网络向用户提供基于它的服务也需要开源对应源码。闭源 SaaS 使用前务必评估。以上为概括,不构成法律意见,请以许可原文为准。

@across-protocol/contracts 的下载量有多少?

根据 npm 官方下载统计,@across-protocol/contracts 在 2026/10/05 – 2026/11/03 这 30 天内被下载 20,474 次,日均约 682 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@across-protocol/contracts 还在维护吗?

最新版本 5.0.28 发布于 2026/11/06(1 天前);至今共发布 154 个版本,其中过去 12 个月发布了 86 个;首次发布于 2021/12/08。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。