Skip to content

Commit

Permalink
Merge branch 'master' into feat/FbV2-version-encoding
Browse files Browse the repository at this point in the history
  • Loading branch information
ChiTimesChi committed Oct 16, 2024
2 parents ec0ba1a + 47dc48e commit 3555d77
Show file tree
Hide file tree
Showing 53 changed files with 2,236 additions and 153 deletions.
16 changes: 16 additions & 0 deletions docs/bridge/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,22 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.

## [0.4.4](https://github.com/synapsecns/sanguine/compare/@synapsecns/bridge-docs@0.4.3...@synapsecns/bridge-docs@0.4.4) (2024-10-15)

**Note:** Version bump only for package @synapsecns/bridge-docs





## [0.4.3](https://github.com/synapsecns/sanguine/compare/@synapsecns/bridge-docs@0.4.2...@synapsecns/bridge-docs@0.4.3) (2024-10-15)

**Note:** Version bump only for package @synapsecns/bridge-docs





## [0.4.2](https://github.com/synapsecns/sanguine/compare/@synapsecns/bridge-docs@0.4.1...@synapsecns/bridge-docs@0.4.2) (2024-10-12)


Expand Down
112 changes: 57 additions & 55 deletions docs/bridge/docs/02-Bridge/01-SDK.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,25 @@ The Synapse Bridge SDK is built on top of the [Synapse Router](/docs/Routers/Syn

### Use cases

* Integrate your front-end application with the Synapse Bridge.
* Provide bridge liquidity.
* Perform cross-chain arbitrage.
* Integrate the Synapse Javascript SDK with your non-Javascript application.
- Integrate your front-end application with the Synapse Bridge.
- Provide bridge liquidity.
- Perform cross-chain arbitrage.
- Integrate the Synapse Javascript SDK with your non-Javascript application.

## Install

:::note requires Node v16+

The SDK has only been fully tested on Node 16+ or greater. Earlier versions are not guaranteed to work.
The SDK has only been fully tested on Node 16+ or greater. Earlier versions are not guaranteed to work.

:::

Requires either the `npx` or `yarn` package manager.
Requires either the `npm` or `yarn` package manager.

| Options
|-
| `npx install @synapsecns/sdk-router`
| `yarn install @synapsecns/sdk-router`
| `npm install @synapsecns/sdk-router`
| `yarn add @synapsecns/sdk-router`

## Configure Ethers

Expand Down Expand Up @@ -60,8 +60,9 @@ const Synapse = new SynapseSDK(chainIds, providers)
:::tip Ethers v6

Use of Ethers v6 requires the `@ethersproject/providers` dependency to be installed via `npm` or `yarn`:
* `npm install @ethersproject/providers@^5.7.2`
* `yarn add @ethersproject/providers@^5.7.2`

- `npm install @ethersproject/providers@^5.7.2`
- `yarn add @ethersproject/providers@^5.7.2`

:::

Expand Down Expand Up @@ -90,11 +91,11 @@ const Synapse = new SynapseSDK(chainIds, providers)

`originQuery` and `destQuery`, returned by `bridgeQuote()` and required for `bridge()`, are [`Query`](https://synapserouter.gitbook.io/untitled/) objects, which contain:

* `swapAdapter`: (string): 0x address of the swap adapter.
* `tokenOut`: (string): 0x address of the outputted token on that chain.
* `minAmountOut`: (Ethers BigNumber): The min amount of value exiting the transaction.
* `deadline`: (Ethers BigNumber): The deadline for the potential transaction.
* `rawParams`: (string): 0x params for the potential transaction.
- `swapAdapter`: (string): 0x address of the swap adapter.
- `tokenOut`: (string): 0x address of the outputted token on that chain.
- `minAmountOut`: (Ethers BigNumber): The min amount of value exiting the transaction.
- `deadline`: (Ethers BigNumber): The deadline for the potential transaction.
- `rawParams`: (string): 0x params for the potential transaction.

:::

Expand All @@ -106,45 +107,45 @@ Get all relevant information regarding a possible transaction.

`bridgeQuote()` requires the following arguments:

* `fromChain` (number): Origin chain id.
* `toChain` (number): Destination chain id.
* `fromToken` (string): 0x token address on the origin chain.
* `toToken` (string): 0x token address on the destination chain.
* `amount` (Ethers BigNumber): The amount (with the correct amount of decimals specified by the token on the origin chain)
* `object` (three seperate args):
* `deadline` (Ethers BigNumber): Deadline for the transaction to be initiated on the origin chain, in seconds (optional)
* `originUserAddress` (string): Address of the user on the origin chain, optional, mandatory if a smart contract is going to initiate the bridge operation
* `excludedModules` (array): (optional) List of bridge modules to exclude from the result
- `fromChain` (number): Origin chain id.
- `toChain` (number): Destination chain id.
- `fromToken` (string): 0x token address on the origin chain.
- `toToken` (string): 0x token address on the destination chain.
- `amount` (Ethers BigNumber): The amount (with the correct amount of decimals specified by the token on the origin chain)
- An `object` with three separate args:
- `deadline` (Ethers BigNumber): Deadline for the transaction to be initiated on the origin chain, in seconds (optional)
- `originUserAddress` (string): Address of the user on the origin chain, optional, mandatory if a smart contract is going to initiate the bridge operation
- `excludedModules` (array): (optional) List of bridge modules to exclude from the result

#### Return value

`bridgeQuote` returns the following information

* `feeAmount` (Ethers BigNumber): The calculated amount of fee to be taken.
* `bridgeFee` (number): The percentage of fee to be taken.
* `maxAmountOut` (Ethers BigNumber): The maximum output amount resulting from the bridge transaction.
* `originQuery` (`Query`): The query to be executed on the origin chain.
* `destQuery` (`Query`): The query to be executed on the destination chain.
- `feeAmount` (Ethers BigNumber): The calculated amount of fee to be taken.
- `bridgeFee` (number): The percentage of fee to be taken.
- `maxAmountOut` (Ethers BigNumber): The maximum output amount resulting from the bridge transaction.
- `originQuery` (`Query`): The query to be executed on the origin chain.
- `destQuery` (`Query`): The query to be executed on the destination chain.

### `bridge()`

Use `bridgeQuote` to request a Bridge transaction

#### Parameters

* `toAddress` (number): The 0x wallet address on the destination chain.
* `routerAddress` (string): The 0x contract address on the origin chain of the bridge router contract.
* `fromChain` (number): The origin chain id.
* `toChain` (number): The destination chain id.
* `fromToken` (string): The 0x token address on the origin chain.
* `amount` (Ethers BigNumber): The amount (with the correct amount of decimals specified by the token on the origin chain)
* `originQuery` (`Query`): The query to be executed on the origin chain.
* `destQuery` (`Query`): The query to be executed on the destination chain.
- `toAddress` (number): The 0x wallet address on the destination chain.
- `routerAddress` (string): The 0x contract address on the origin chain of the bridge router contract.
- `fromChain` (number): The origin chain id.
- `toChain` (number): The destination chain id.
- `fromToken` (string): The 0x token address on the origin chain.
- `amount` (Ethers BigNumber): The amount (with the correct amount of decimals specified by the token on the origin chain)
- `originQuery` (`Query`): The query to be executed on the origin chain.
- `destQuery` (`Query`): The query to be executed on the destination chain.

#### Return value

* `to` (string): 0x wallet address on the destination chain.
* `data` (string): Output data in 0x hex format
- `to` (string): 0x wallet address on the destination chain.
- `data` (string): Output data in 0x hex format

### `allBridgeQuotes()`

Expand All @@ -165,7 +166,7 @@ const quotes = await Synapse.bridgeQuote(
43114, // Destination Chain
'0xff970a61a04b1ca14834a43f5de4533ebddb5cc8', // Origin Token Address
'0xa7d7079b0fead91f3e65f86e8915cb59c1a4c664', // Destination Token Address
BigNumber.from('20000000') // Amount in
BigNumber.from('20000000') // Amount in
{
// Deadline for the transaction to be initiated on the origin chain, in seconds (optional)
deadline: 1234567890,
Expand All @@ -183,37 +184,38 @@ const quotes = await Synapse.bridgeQuote(

```js
await Synapse.bridge(
'0x0AF91FA049A7e1894F480bFE5bBa20142C6c29a9', // To Address
bridgeQuote.routerAddress, // address of the contract to route the txn
42161, // Origin Chain
43114, // Destination Chain
'0xff970a61a04b1ca14834a43f5de4533ebddb5cc8', // Origin Token Address
BigNumber.from('20000000'), // Amount
quote.originQuery, // Origin query from bridgeQuote()
quote.destQuery // Destination query from bridgeQuote()
'0x0AF91FA049A7e1894F480bFE5bBa20142C6c29a9', // To Address
bridgeQuote.routerAddress, // address of the contract to route the txn
42161, // Origin Chain
43114, // Destination Chain
'0xff970a61a04b1ca14834a43f5de4533ebddb5cc8', // Origin Token Address
BigNumber.from('20000000'), // Amount
quote.originQuery, // Origin query from bridgeQuote()
quote.destQuery // Destination query from bridgeQuote()
)
```

## Version 0.10.0 breaking changes

### Options object

* `deadline`, `excludeCCTP` (now `excludedModules`), and `originUserAddress` parameters are now found in an (optional) options object at the end of the arguments list for `bridgeQuote()`, and `allBridgeQuotes()`.
* `excludedModules` excludes one or more modules with an array of the module names. Supported names are `SynapseBridge`, `SynapseCCTP`, and `SynapseRFQ`.
* `originUserAddress` is required as part of the options object to initiate a bridge transaction on behalf of a user.
- `deadline`, `excludeCCTP` (now `excludedModules`), and `originUserAddress` parameters are now found in an (optional) options object at the end of the arguments list for `bridgeQuote()`, and `allBridgeQuotes()`.
- `excludedModules` excludes one or more modules with an array of the module names. Supported names are `SynapseBridge`, `SynapseCCTP`, and `SynapseRFQ`.
- `originUserAddress` is required as part of the options object to initiate a bridge transaction on behalf of a user.

### Examples

```js
bridgeQuote(...arguments, {
deadline: 1234567890,
excludedModules: ["SynapseCCTP"],
originUserAddress: "0x1234...",
excludedModules: ['SynapseCCTP'],
originUserAddress: '0x1234...',
})

allBridgeQuotes({
deadline: 1234567890,
excludedModules: ["SynapseCCTP"],
originUserAddress: "0x1234...",
excludedModules: ['SynapseCCTP'],
originUserAddress: '0x1234...',
})
```

Expand Down
4 changes: 4 additions & 0 deletions docs/bridge/docs/04-Routers/RFQ/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,7 @@ In a successful dispute, the relayer loses their claimable funds. This design is
## Unfulfilled requests

If a request is not fulfilled, users can reclaim their funds by using the [`claim`](https://vercel-rfq-docs.vercel.app/contracts/FastBridge.sol/contract.FastBridge.html#claim) function once the optimistic window has passed.

## Load Tester

The [`rfq-loadtest`](https://github.com/synapsecns/sanguine/tree/master/packages/rfq-loadtest) tool can be used to rapidly send ETH bridges for the purpose of load testing.
2 changes: 1 addition & 1 deletion docs/bridge/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@synapsecns/bridge-docs",
"version": "0.4.2",
"version": "0.4.4",
"private": true,
"scripts": {
"docusaurus": "docusaurus",
Expand Down
16 changes: 16 additions & 0 deletions packages/contracts-rfq/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,22 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.

## [0.8.3](https://github.com/synapsecns/sanguine/compare/@synapsecns/contracts-rfq@0.8.2...@synapsecns/contracts-rfq@0.8.3) (2024-10-16)

**Note:** Version bump only for package @synapsecns/contracts-rfq





## [0.8.2](https://github.com/synapsecns/sanguine/compare/@synapsecns/contracts-rfq@0.8.1...@synapsecns/contracts-rfq@0.8.2) (2024-10-15)

**Note:** Version bump only for package @synapsecns/contracts-rfq





## [0.8.1](https://github.com/synapsecns/sanguine/compare/@synapsecns/contracts-rfq@0.8.0...@synapsecns/contracts-rfq@0.8.1) (2024-10-14)

**Note:** Version bump only for package @synapsecns/contracts-rfq
Expand Down
24 changes: 18 additions & 6 deletions packages/contracts-rfq/contracts/FastBridgeV2.sol
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,15 @@ contract FastBridgeV2 is Admin, IFastBridgeV2, IFastBridgeV2Errors {
revert DisputePeriodPassed();
}

address disputedRelayer = bridgeTxDetails[transactionId].proofRelayer;

// @dev relayer gets slashed effectively if dest relay has gone thru
bridgeTxDetails[transactionId].status = BridgeStatus.REQUESTED;
bridgeTxDetails[transactionId].proofRelayer = address(0);
bridgeTxDetails[transactionId].proofBlockTimestamp = 0;
bridgeTxDetails[transactionId].proofBlockNumber = 0;

emit BridgeProofDisputed(transactionId, msg.sender);
emit BridgeProofDisputed(transactionId, disputedRelayer);
}

/// @inheritdoc IFastBridge
Expand All @@ -114,7 +116,11 @@ contract FastBridgeV2 is Admin, IFastBridgeV2, IFastBridgeV2Errors {
address to = request.originSender();
address token = request.originToken();
uint256 amount = request.originAmount() + request.originFeeAmount();
token.universalTransfer(to, amount);
if (token == UniversalTokenLib.ETH_ADDRESS) {
Address.sendValue(payable(to), amount);
} else {
IERC20(token).safeTransfer(to, amount);
}

emit BridgeDepositRefunded(transactionId, to, token, amount);
}

Check notice

Code scanning / Slither

Reentrancy vulnerabilities Low

Check notice

Code scanning / Slither

Block timestamp Low

FastBridgeV2.refund(bytes) uses timestamp for comparisons
Dangerous comparisons:
- block.timestamp <= deadline
Expand Down Expand Up @@ -172,8 +178,10 @@ contract FastBridgeV2 is Admin, IFastBridgeV2, IFastBridgeV2Errors {

// track amount of origin token owed to protocol
uint256 originFeeAmount;
if (protocolFeeRate > 0) originFeeAmount = (originAmount * protocolFeeRate) / FEE_BPS;
originAmount -= originFeeAmount; // remove from amount used in request as not relevant for relayers
if (protocolFeeRate > 0) {
originFeeAmount = (originAmount * protocolFeeRate) / FEE_BPS;
originAmount -= originFeeAmount; // remove from amount used in request as not relevant for relayers
}

// set status to requested
bytes memory request = BridgeTransactionV2Lib.encodeV2(
Expand Down Expand Up @@ -307,8 +315,12 @@ contract FastBridgeV2 is Admin, IFastBridgeV2, IFastBridgeV2Errors {
uint256 originFeeAmount = request.originFeeAmount();
if (originFeeAmount > 0) protocolFees[token] += originFeeAmount;

// transfer origin collateral less fee to specified address
token.universalTransfer(to, amount);
// transfer origin collateral to specified address (protocol fee was pre-deducted at deposit)
if (token == UniversalTokenLib.ETH_ADDRESS) {
Address.sendValue(payable(to), amount);
} else {
IERC20(token).safeTransfer(to, amount);
}

emit BridgeDepositClaimed(transactionId, bridgeTxDetails[transactionId].proofRelayer, to, token, amount);
}

Check notice

Code scanning / Slither

Reentrancy vulnerabilities Low

Check notice

Code scanning / Slither

Block timestamp Low

Expand Down
2 changes: 1 addition & 1 deletion packages/contracts-rfq/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@synapsecns/contracts-rfq",
"license": "MIT",
"version": "0.8.1",
"version": "0.8.3",
"description": "FastBridge contracts.",
"private": true,
"files": [
Expand Down
3 changes: 3 additions & 0 deletions packages/contracts-rfq/script/FastBridge.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import {Script} from "forge-std/Script.sol";
contract DeployFastBridge is Script {
FastBridge public bridge;

/// @notice We include an empty "test" function so that this contract does not appear in the coverage report.
function testDeployFastBridge() external {}

/// e.g. forge script contracts/script/FastBridge.s.sol --sig "run(address, address[])" 0xa0Ee7A142d267C1f36714E4a8F75612F20a79720 "[0x23618e81E3f5cdF7f54C3d65f7FBc0aBf5B21E8f]"
function run(address owner, address[] memory relayers) external {
vm.startBroadcast();
Expand Down
3 changes: 3 additions & 0 deletions packages/contracts-rfq/test/FastBridgeMock.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ contract FastBridgeMock is IFastBridge, Admin {
/// @dev to prevent replays
uint256 public nonce;

/// @notice We include an empty "test" function so that this contract does not appear in the coverage report.
function testFastBridgeMock() external {}

function getBridgeTransaction(bytes memory request) public pure returns (BridgeTransaction memory) {
return abi.decode(request, (BridgeTransaction));
}
Expand Down
5 changes: 4 additions & 1 deletion packages/contracts-rfq/test/FastBridgeV2.Dst.Base.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@ import {BridgeTransactionV2Lib} from "../contracts/libs/BridgeTransactionV2.sol"

import {FastBridgeV2, FastBridgeV2Test, IFastBridgeV2} from "./FastBridgeV2.t.sol";

// solhint-disable func-name-mixedcase, ordering
// solhint-disable func-name-mixedcase, no-empty-blocks
contract FastBridgeV2DstBaseTest is FastBridgeV2Test {
uint256 public constant LEFTOVER_BALANCE = 1 ether;

/// @notice We include an empty "test" function so that this contract does not appear in the coverage report.
function testFastBridgeV2DstBaseTest() external {}

function setUp() public virtual override {
vm.chainId(DST_CHAIN_ID);
super.setUp();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,17 @@ pragma solidity ^0.8.20;
import {FastBridgeV2GasBenchmarkDstTest} from "./FastBridgeV2.GasBench.Dst.t.sol";
import {RecipientMock} from "./mocks/RecipientMock.sol";

// solhint-disable func-name-mixedcase, ordering
// solhint-disable func-name-mixedcase, no-empty-blocks
contract FastBridgeV2GasBenchmarkDstArbitraryCallTest is FastBridgeV2GasBenchmarkDstTest {
// To get an idea about how much overhead the arbitrary call adds to the relaying process, we use a mock
// recipient that has the hook function implemented as a no-op.
// The mocked callParams are chosen to be similar to the real use cases:
// - user address
// - some kind of ID to decide what to do with the tokens next

/// @notice We include an empty "test" function so that this contract does not appear in the coverage report.
function testFastBridgeV2GasBenchmarkDstArbitraryCallTest() external {}

function setUp() public virtual override {
// In the inherited tests userB is always used as the recipient of the tokens.
userB = address(new RecipientMock());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@ pragma solidity ^0.8.20;

import {FastBridgeV2GasBenchmarkDstTest} from "./FastBridgeV2.GasBench.Dst.t.sol";

// solhint-disable func-name-mixedcase, ordering
// solhint-disable func-name-mixedcase, no-empty-blocks
contract FastBridgeV2GasBenchmarkDstExclusivityTest is FastBridgeV2GasBenchmarkDstTest {
uint256 public constant EXCLUSIVITY_PERIOD = 60 seconds;

/// @notice We include an empty "test" function so that this contract does not appear in the coverage report.
function testFastBridgeV2GasBenchmarkDstExclusivityTest() external {}

function setUp() public virtual override {
super.setUp();
skip({time: EXCLUSIVITY_PERIOD / 2});
Expand Down
Loading

0 comments on commit 3555d77

Please sign in to comment.