Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(governance): Improve scripts to inspect and execute bridge txs #13419

Merged
merged 15 commits into from Apr 3, 2024
46 changes: 46 additions & 0 deletions governance/README.md
Expand Up @@ -234,3 +234,49 @@ Edit directly the amounts and prices in the script
```
yarn run scripts/uniswap/addLiquidity.js
```

## Cross-Chain DAO Proposals

To maintain the integrity of the protocol accross various chains, we use a pattern of DAO proposals that allows execution on multiple chains. Messaging is sent accross the [Connext bridge](https://connext.network) to all supported chains.

### Prepare a cross-chain proposal

#### Write a cross-chain DAO proposal

Read the explanations and follow the template in [`./proposals/006-cross-bridge-proposal.js`](./proposals/006-cross-bridge-proposal.js) to submit a cross-chain proposal to the DAO.

#### Test a cross-chain DAO proposal

To make sure all calls can be executed properly, you can use Tenderly forks to test execution of calls on each destination chains.

### After proposal execution

#### Pay bridge fees

Each transaction contained in the proposal is sent separately to the bridge. For each tx, the bridge fee needs to be paid on origin chain (mainnet) for the txs to proceed. To pay all fees for the bridge, use the following script:

```
# update the txId accordingly
yarn hardhat run scripts/bridge/payFee.js --network mainnet
```

#### Check status of the calls

You can check the status of all calls on various chains manually with the [Connext explorer](https://connextscan.io/) or directly parse calls from the execution tx using the following script:

```
# update the txId accordingly
yarn hardhat run scripts/bridge/status.js --network mainnet
```

NB: This will create a temporary JSON file named `xcalled.json.tmp` with the info and statuses of all tx.

### Execute all tx on destination chains

Once all calls have crossed the bridges they stay in cooldown in multisigs. Once cooldown ends, they can be executed. To execute the calls, use the following command _for each network_:

```
yarn hardhat run scripts/bridge/execTx.js --network optimism
```

NB: The tmp file with all txs statuses is required, so you need to first run the "Check status" step above
51 changes: 51 additions & 0 deletions governance/helpers/bridge/abis/IConnext.js
@@ -0,0 +1,51 @@
module.exports = [
{
inputs: [
{
internalType: 'uint32',
name: '_destination',
type: 'uint32',
},
{
internalType: 'address',
name: '_to',
type: 'address',
},
{
internalType: 'address',
name: '_asset',
type: 'address',
},
{
internalType: 'address',
name: '_delegate',
type: 'address',
},
{
internalType: 'uint256',
name: '_amount',
type: 'uint256',
},
{
internalType: 'uint256',
name: '_slippage',
type: 'uint256',
},
{
internalType: 'bytes',
name: '_callData',
type: 'bytes',
},
],
name: 'xcall',
outputs: [
{
internalType: 'bytes32',
name: '',
type: 'bytes32',
},
],
stateMutability: 'payable',
type: 'function',
},
]
124 changes: 124 additions & 0 deletions governance/helpers/bridge/abis/IXCalled.js
@@ -0,0 +1,124 @@
module.exports = [
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: 'bytes32',
name: 'transferId',
type: 'bytes32',
},
{
indexed: true,
internalType: 'uint256',
name: 'nonce',
type: 'uint256',
},
{
indexed: true,
internalType: 'bytes32',
name: 'messageHash',
type: 'bytes32',
},
{
components: [
{
internalType: 'uint32',
name: 'originDomain',
type: 'uint32',
},
{
internalType: 'uint32',
name: 'destinationDomain',
type: 'uint32',
},
{
internalType: 'uint32',
name: 'canonicalDomain',
type: 'uint32',
},
{
internalType: 'address',
name: 'to',
type: 'address',
},
{
internalType: 'address',
name: 'delegate',
type: 'address',
},
{
internalType: 'bool',
name: 'receiveLocal',
type: 'bool',
},
{
internalType: 'bytes',
name: 'callData',
type: 'bytes',
},
{
internalType: 'uint256',
name: 'slippage',
type: 'uint256',
},
{
internalType: 'address',
name: 'originSender',
type: 'address',
},
{
internalType: 'uint256',
name: 'bridgedAmt',
type: 'uint256',
},
{
internalType: 'uint256',
name: 'normalizedIn',
type: 'uint256',
},
{
internalType: 'uint256',
name: 'nonce',
type: 'uint256',
},
{
internalType: 'bytes32',
name: 'canonicalId',
type: 'bytes32',
},
],
indexed: false,
internalType: 'struct TransferInfo',
name: 'params',
type: 'tuple',
},
{
indexed: false,
internalType: 'address',
name: 'asset',
type: 'address',
},
{
indexed: false,
internalType: 'uint256',
name: 'amount',
type: 'uint256',
},
{
indexed: false,
internalType: 'address',
name: 'local',
type: 'address',
},
{
indexed: false,
internalType: 'bytes',
name: 'messageBody',
type: 'bytes',
},
],
name: 'XCalled',
type: 'event',
},
]