Skip to content

Instantly share code, notes, and snippets.

@TradMod
Last active June 3, 2025 19:01
Show Gist options
  • Save TradMod/e3947b23969b8eff56c6d3c92dbbd63a to your computer and use it in GitHub Desktop.
Save TradMod/e3947b23969b8eff56c6d3c92dbbd63a to your computer and use it in GitHub Desktop.
Across Research
  • Across Docs
  • Across Audits
  • Across Integration protocols audits
  • Across Codebase
  • Write & Report PR

Across is an Intent based bridging protocol. Users input the intent while bridging not path. Relayers off-chain execute and fill that intent with enough liquidity.

  • Users simply place the cross-chain order. Rather than detailing the exact execution path, the user defines the desired outcome. Intent-based InterOp hence.
  • Relayers (3rd parties) compete each other to fulfill the order
  • On settlement layer order gets executed, verification and then relayers get paid back upon successful completion of the intent

Across' cross chain intents architecture can be distilled into a 3-layered system: a request for quote mechanism to house users' intents, enabling a competitive network of relayers to bid, claim and fill those orders, and lastly a settlement layer to verify intent fulfillment and repay relayers.

Weird Stuff: Handling of ETH and WETH: (check if this is mentioned in any integration audits)

Across will sometimes send a user ETH and sometimes send a user WETH. If the input asset is ETH, and the recipient is an EOA, the EOA will receive ETH If the input asset is ETH, and the recipient is a contract, the contract will receive WETH (not ETH) If the input asset is WETH, and the recipient is an EOA, the EOA will receive ETH (not WETH) If the input asset is WETH, and the recipient is a contract, the contract will receive WETH

  • Isn't this can be problematic with the apps who are integrating across.

WTH that means? No refunds on L2s? Where the refund goes then? It just goes?

If a deposit wasn't filled, the lifecycle of the deposit can be tracked using the status API and refunds are issued once a deposit expires. Note: refunds are only issued on mainnet deposits.

  • Can the migrations from v2 to v3 or others can cause issues in integrated protocols? NOTE: To be discovered

the tradeoff of using the multicall handler contract is that the complexity is encountered when crafting the message, which must be a correctly-encoded Instructions object. Once the message is formed correctly, you don't need to write any more code.

  • Relayers can behave malicious!?

Message Constraints. Handler contracts only use the funds that are sent to it. That means that the message is assumed to only have authority over those funds and, critically, no outside funds. This is important because relayers can send invalid relays. They will not be repaid if they attempt this, but if an invalid message could unlock other funds, then a relayer could spoof messages maliciously.

Reverting Transactions If the message specifies a transaction that could revert when handled on the destination, it is recommended to set a fallbackRecipient If a fallbackRecipient is set to some non-zero address and any instruction reverts, the tokens that are received in the fill as outputAmount will be sent to the fallbackRecipient on the destinationChainId If no fallback is set, and any instructions fail, the fill on destination will fail and cannot occur. In this case the deposit will expire when the destination SpokePool timestamp exceeds the deposit fillDeadline timestamp, the depositor will be refunded on the originChainId. Ensure that the depositor address on the origin SpokePool is capable of receiving refunds.

  • msgs are spoofable

Avoid making unvalidated assumptions about the message data supplied to handleV3AcrossMessage(). Across does not guarantee message integrity, only that a relayer who spoofs a message will not be repaid by Across. If integrity is required, integrators should consider including a depositor signature in the message for additional verification. Message data should otherwise be treated as spoofable and untrusted for use beyond directing the funds passed along with it.

If the (custom) recipient contract's handleV3AcrossMessage function reverts when message , tokenSent, amount, and relayer are passed to it, then the fill on destination will fail and cannot occur. In this case the deposit will expire when the destination SpokePool timestamp exceeds the deposit fillDeadline timestamp, the depositor will be refunded on the originChainId. Ensure that the depositor address on the origin SpokePool is capable of receiving refunds.

  • Which type of repayments? -> The relayers get repaid after the cross-chain settlements fills, in across there is no liquidity, there are relayers who compete to fill orders and lend their money to the users

Relayer Cross chain Management: With Across’ settlement architecture, repayment is made on the relayer’s chain of choice, reducing overhead and complexity of managing cross chain positions. This lowers costs for relayers, enabling better pricing and execution for end-users. It is enabled by Across’ Hub and Spoke model, where passive LPs extend loans to relayers for taking on time-value risk as funds are rebalanced through canonical bridges by the protocol.

Across' quoting currently has fixed fees and relayer competition is strictly based on a speed.

  • While integrating across it is important that the msgSender's address so refunds don't get lost (if there is no refund address param in across like LZ, it looks like there isn't, there is depositor btw)

In cases where a slow fill can't or does not happen and a relayer does not fill the intent, the intent expires. Like a slow fill, this expiry must be optimistically verified, which takes a few hours. Once this verification is done, the user is then refunded their money on the origin chain.

  • Interesting!

Canonical assets refer to the original or "native" form of a token on its home blockchain. In the context of interoperability, tokens can either be "canonical" or "representative." -> Canonical bridge: Canonical bridge contracts, which already underpin the security of an L2 chain that inherits its security from mainnet Ethereum in the most trust minimized way, is responsible for verifying messages to mint tokens. These are considered "canonical" tokens given they do not increase trust assumptions vs. simply using the L2 chain. Similar "trustless" verification mechanisms may exist from Ethereum to other Alt L1s. -> 3rd party message bridge: A 3rd party bridge, which can have any number of trust models, is responsible for verifying messages to mint tokens. These are considered "representative" tokens given they do increase trust assumptions, as users now have to trust a 3rd party to never allow a faulty message (and if they do, it could result in an infinite mint and unbacked token on the secondary chain). -> Across' intent-based bridge introduces a new architecture in interoperability that doesn't suffer from the security hurdles of 3rd party message bridges, and is empirically faster and cheaper than canonical bridges. Across achieves this by inserting a 3rd party relayer to quickly fulfill users' bridging requests using their own inventory of canonical assets, and a settlement layer that sits on top of canonical bridges to slowly verify and repay relayers. In other words, Across' intent-bridge decouples the urgent need of fast-filling users from the eventual need of verification. Users and developers don't need to make the trust vs. convenience trade-off in canonical vs. representative assets: intent systems like Across offer the best of both worlds.

  • This is weird then how it is handled? - looks like they use Circle's CCTP bridge for that

Using deposit will not allow the caller to specify a different outputToken than inputToken. This means that following the CCTP upgrade, deposit callers will not be able to set inputToken = USDC and outputToken = Bridged USDC.

  • what if a contract cannot handle ERC20s/WETH?

Note on receiving ETH: EOA recipients will always receive ETH while contracts will always receive WETH, regardless of whether ETH or WETH is deposited.

  • Making sure the correct outputAmount is important otherwise tokens can be locked temporarily

Note on inputAmount limits: If the inputAmount is set too high, it can take a while for the deposit to be filled depending on available relayer liquidity. If the outputAmount is set too high, it can be unprofitable to relay. Query the suggested max and min limits here. The contracts will not revert if the outputAmount is set outside of the recommended range, so it is highly recommended to set outputAmount within the suggested limits to avoid locking up funds for an unexpected length of time. The recommended outputAmount will be equal to inputAmount * ( 1 - relayerFeePct - lpFeePct).

Potential Not Fix Across Issues:

If the message is not empty, the recipient contract must implement handleV3AcrossMessage() or the fill will revert. https://github.com/across-protocol/contracts/blob/0fee0264009e662a17e2cd8c22c4c493f12b8a03/contracts/SpokePool.sol#L488

  • Across doesn't send the origin sender address making the msgs spoofable if not handled correctly

The Across protocol doesn't provide origin sender information in bridged messages. 5.2.2. https://github.com/meliopolis/chainhopper-protocol/blob/main/docs/Spearbit-audit.pdf

  • Across cannot handle Fee-on-Transfer Tokens well

5.2.7 https://github.com/meliopolis/chainhopper-protocol/blob/main/docs/Spearbit-audit.pdf

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment