From 835967a2758b548389ff1a41059ffbd60ac2e22b Mon Sep 17 00:00:00 2001 From: benesjan Date: Wed, 6 Jul 2022 13:28:02 +0200 Subject: [PATCH] style: formatted everything --- .circleci/config.yml | 10 ++-- .eslintrc.js | 18 +++--- .gitignore | 6 +- .prettierignore | 8 +++ .solhint.json | 4 +- CODE_OF_CONDUCT.md | 29 +++++---- README.md | 21 ++++--- ensure_versions.js | 20 +++---- hardhat.config.ts | 18 +++--- package.json | 4 +- src/client/aztec/provider/index.ts | 2 +- src/client/aztec/provider/web3_provider.ts | 4 +- .../element/element-bridge-data.test.ts | 60 +++++++++---------- src/client/element/element-bridge-data.ts | 18 +++--- src/client/example/example-bridge-data.ts | 4 +- src/specs/TEMPLATE.md | 39 ++++++------ src/specs/lido/readme.md | 28 ++++++--- src/specs/mstable/spec.md | 1 - 18 files changed, 159 insertions(+), 135 deletions(-) create mode 100644 .prettierignore diff --git a/.circleci/config.yml b/.circleci/config.yml index 39fbacc55..fdcb4ed96 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,15 +1,15 @@ -version: '2.1' +version: "2.1" orbs: node: circleci/node@5.0.0 jobs: build-and-test: docker: - - image: 'cimg/base:stable-20.04' + - image: "cimg/base:stable-20.04" steps: - checkout - node/install: install-yarn: true - node-version: '16.13' + node-version: "16.13" - run: name: Setup Foundry shell: /bin/bash @@ -53,12 +53,12 @@ jobs: yarn build publish: docker: - - image: 'cimg/base:stable-20.04' + - image: "cimg/base:stable-20.04" steps: - checkout - node/install: install-yarn: true - node-version: '16.13' + node-version: "16.13" - run: name: Authenticate with registry command: echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > .npmrc diff --git a/.eslintrc.js b/.eslintrc.js index 394e50354..c20b20eb1 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,18 +1,18 @@ module.exports = { root: true, - parser: '@typescript-eslint/parser', - plugins: ['@typescript-eslint'], - extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'prettier/@typescript-eslint'], + parser: "@typescript-eslint/parser", + plugins: ["@typescript-eslint"], + extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended", "prettier/@typescript-eslint"], env: { node: true, }, rules: { - '@typescript-eslint/explicit-module-boundary-types': 'off', - '@typescript-eslint/no-non-null-assertion': 'off', - '@typescript-eslint/no-explicit-any': 'off', - '@typescript-eslint/no-empty-function': 'off', - 'no-constant-condition': 'off', + "@typescript-eslint/explicit-module-boundary-types": "off", + "@typescript-eslint/no-non-null-assertion": "off", + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/no-empty-function": "off", + "no-constant-condition": "off", camelcase: 2, }, - ignorePatterns: ['node_modules', 'dest*', 'dist', '*.js', '.eslintrc'], + ignorePatterns: ["node_modules", "dest*", "dist", "*.js", ".eslintrc"], }; diff --git a/.gitignore b/.gitignore index 754ca8925..7d9c7dc0b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,7 @@ -cache +cache/ out/ -node_modules +node_modules/ artifacts/ yarn-error.log -contracts client-dest/ -types/ typechain-types/ diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 000000000..91c4320dc --- /dev/null +++ b/.prettierignore @@ -0,0 +1,8 @@ +cache/ +out/ +node_modules/ +artifacts/ +yarn-error.log +client-dest/ +lib/ +typechain-types/ diff --git a/.solhint.json b/.solhint.json index 63d94c191..263e65d69 100644 --- a/.solhint.json +++ b/.solhint.json @@ -5,8 +5,8 @@ "func-visibility": ["warn", { "ignoreConstructors": true }], "no-empty-blocks": "off", "not-rely-on-time": "off", - "const-name-snakecase": ["warn", { "treatImmutableVarAsConstant": true}], - "var-name-mixedcase": ["warn", { "treatImmutableVarAsConstant": true}], + "const-name-snakecase": ["warn", { "treatImmutableVarAsConstant": true }], + "var-name-mixedcase": ["warn", { "treatImmutableVarAsConstant": true }], "error-name-mixedcase": ["warn"], "private-func-leading-underscore": ["warn"], "private-vars-no-leading-underscore": ["warn"], diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 45d257b29..88c4db8da 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -1,4 +1,3 @@ - # Contributor Covenant Code of Conduct ## Our Pledge @@ -18,23 +17,23 @@ diverse, inclusive, and healthy community. Examples of behavior that contributes to a positive environment for our community include: -* Demonstrating empathy and kindness toward other people -* Being respectful of differing opinions, viewpoints, and experiences -* Giving and gracefully accepting constructive feedback -* Accepting responsibility and apologizing to those affected by our mistakes, +- Demonstrating empathy and kindness toward other people +- Being respectful of differing opinions, viewpoints, and experiences +- Giving and gracefully accepting constructive feedback +- Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience -* Focusing on what is best not just for us as individuals, but for the overall +- Focusing on what is best not just for us as individuals, but for the overall community Examples of unacceptable behavior include: -* The use of sexualized language or imagery, and sexual attention or advances of +- The use of sexualized language or imagery, and sexual attention or advances of any kind -* Trolling, insulting or derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or email address, +- Trolling, insulting or derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or email address, without their explicit permission -* Other conduct which could reasonably be considered inappropriate in a +- Other conduct which could reasonably be considered inappropriate in a professional setting ## Enforcement Responsibilities @@ -120,14 +119,14 @@ version 2.1, available at [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. Community Impact Guidelines were inspired by -[Mozilla's code of conduct enforcement ladder][Mozilla CoC]. +[Mozilla's code of conduct enforcement ladder][mozilla coc]. For answers to common questions about this code of conduct, see the FAQ at -[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at +[https://www.contributor-covenant.org/faq][faq]. Translations are available at [https://www.contributor-covenant.org/translations][translations]. [homepage]: https://www.contributor-covenant.org [v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html -[Mozilla CoC]: https://github.com/mozilla/diversity -[FAQ]: https://www.contributor-covenant.org/faq +[mozilla coc]: https://github.com/mozilla/diversity +[faq]: https://www.contributor-covenant.org/faq [translations]: https://www.contributor-covenant.org/translations diff --git a/README.md b/README.md index d98a63daf..6e7294d17 100644 --- a/README.md +++ b/README.md @@ -21,12 +21,12 @@ Developing a bridge is simple and permissionless. It is done entirely in Solidit ## Deployed Bridge Info -| Bridge | Id | InputAssetA (AssetId) | InputAssetB (AssetId) | OutputAssetA (AssetId) | OutputAssetB (AssetId) | auxData | async | Description | -|---|---|---|---|---|---|---|---|---| -| [Element](https://etherscan.io/address/0xaeD181779A8AAbD8Ce996949853FEA442C2CDB47) | 1 | DAI (1) | Not used | DAI (1) | Not used | The tranche expiry value for the interaction. | Yes | Smart contract responsible for depositing, managing and redeeming Defi interactions with the Element protocol | -| [LidoBridge](https://etherscan.io/address/0x381abF150B53cc699f0dBBBEF3C5c0D1fA4B3Efd) | 2 | ETH (0) or wstETH (2) | Not used | wstETH (2) or ETH (0) | Not used | Not used | No | Deposit Eth and get wstETH from Lido, or deposit wstETH and get ETH from a Curve swap. | -| [AceOfZkBridge](https://etherscan.io/address/0x0eb7F9464060289fE4FDDFDe2258f518c6347a70) | 4 | [Ace of ZK NFT](https://opensea.io/assets/ethereum/0xe56b526e532804054411a470c49715c531cfd485/16) | Not used | Not used | Not used | | No | A bridge to send the Ace of ZK to the rollup processor contract. | -| [CurveStEthBridge](https://etherscan.io/address/0x0031130c56162e00A7e9C01eE4147b11cbac8776) | 5 | ETH (0) or wstETH (2) | Not used | wsthETH (2) or ETH (0) - will be opposite of `inputAssetA` | Not used | Not used | No | A DeFiBridge for trading between Eth and wstEth using curve and the stEth wrapper. | +| Bridge | Id | InputAssetA (AssetId) | InputAssetB (AssetId) | OutputAssetA (AssetId) | OutputAssetB (AssetId) | auxData | async | Description | +| ------------------------------------------------------------------------------------------- | --- | ------------------------------------------------------------------------------------------------- | --------------------- | ---------------------------------------------------------- | ---------------------- | --------------------------------------------- | ----- | ------------------------------------------------------------------------------------------------------------- | +| [Element](https://etherscan.io/address/0xaeD181779A8AAbD8Ce996949853FEA442C2CDB47) | 1 | DAI (1) | Not used | DAI (1) | Not used | The tranche expiry value for the interaction. | Yes | Smart contract responsible for depositing, managing and redeeming Defi interactions with the Element protocol | +| [LidoBridge](https://etherscan.io/address/0x381abF150B53cc699f0dBBBEF3C5c0D1fA4B3Efd) | 2 | ETH (0) or wstETH (2) | Not used | wstETH (2) or ETH (0) | Not used | Not used | No | Deposit Eth and get wstETH from Lido, or deposit wstETH and get ETH from a Curve swap. | +| [AceOfZkBridge](https://etherscan.io/address/0x0eb7F9464060289fE4FDDFDe2258f518c6347a70) | 4 | [Ace of ZK NFT](https://opensea.io/assets/ethereum/0xe56b526e532804054411a470c49715c531cfd485/16) | Not used | Not used | Not used | | No | A bridge to send the Ace of ZK to the rollup processor contract. | +| [CurveStEthBridge](https://etherscan.io/address/0x0031130c56162e00A7e9C01eE4147b11cbac8776) | 5 | ETH (0) or wstETH (2) | Not used | wsthETH (2) or ETH (0) - will be opposite of `inputAssetA` | Not used | Not used | No | A DeFiBridge for trading between Eth and wstEth using curve and the stEth wrapper. | ## Getting started @@ -271,7 +271,14 @@ interface IDefiBridge { Types.AztecAsset calldata outputAssetB, uint256 interactionNonce, uint64 auxData - ) external payable returns (uint256 outputValueA, uint256 outputValueB, bool interactionComplete); + ) + external + payable + returns ( + uint256 outputValueA, + uint256 outputValueB, + bool interactionComplete + ); } ``` diff --git a/ensure_versions.js b/ensure_versions.js index a3032f24f..0c244c874 100644 --- a/ensure_versions.js +++ b/ensure_versions.js @@ -1,15 +1,13 @@ -const path = require('path'); -const { readFileSync, writeFileSync } = require('fs'); +const path = require("path"); +const { readFileSync, writeFileSync } = require("fs"); // https://github.com/Uniswap/uniswap-v2-periphery/pull/53 -const safeMathFilename = path.resolve(__dirname, './node_modules/@uniswap/v2-periphery/contracts/libraries/SafeMath.sol'); +const safeMathFilename = path.resolve( + __dirname, + "./node_modules/@uniswap/v2-periphery/contracts/libraries/SafeMath.sol", +); try { - const content = readFileSync(safeMathFilename, 'utf-8'); - writeFileSync( - safeMathFilename, - content.replace('pragma solidity =0.6.6;', 'pragma solidity >=0.6.6;'), - 'utf-8', - ); -} catch (e) { -} + const content = readFileSync(safeMathFilename, "utf-8"); + writeFileSync(safeMathFilename, content.replace("pragma solidity =0.6.6;", "pragma solidity >=0.6.6;"), "utf-8"); +} catch (e) {} diff --git a/hardhat.config.ts b/hardhat.config.ts index 7433bf5a9..744721182 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -1,37 +1,37 @@ -import { HardhatUserConfig, subtask } from 'hardhat/config'; -import '@typechain/hardhat'; +import { HardhatUserConfig, subtask } from "hardhat/config"; +import "@typechain/hardhat"; -const { TASK_COMPILE_SOLIDITY_GET_SOURCE_PATHS } = require('hardhat/builtin-tasks/task-names'); +const { TASK_COMPILE_SOLIDITY_GET_SOURCE_PATHS } = require("hardhat/builtin-tasks/task-names"); subtask(TASK_COMPILE_SOLIDITY_GET_SOURCE_PATHS).setAction(async (_, __, runSuper) => { const paths = await runSuper(); // Do not generate types for files in the src/test folder unless they are in interface subfolder. // (Types of all the interfaces are needed in end to end tests.) - return paths.filter((p: any) => !p.includes('src/test/') || p.includes('interface')); + return paths.filter((p: any) => !p.includes("src/test/") || p.includes("interface")); }); const config: HardhatUserConfig = { solidity: { - version: '0.8.10', + version: "0.8.10", settings: { optimizer: { enabled: true, runs: 200 }, }, }, typechain: { - target: 'ethers-v5', + target: "ethers-v5", }, networks: { ganache: { - url: `http://${process.env.GANACHE_HOST || 'localhost'}:8545`, + url: `http://${process.env.GANACHE_HOST || "localhost"}:8545`, }, hardhat: { blockGasLimit: 15000000, }, }, paths: { - sources: 'src/', - artifacts: './artifacts', + sources: "src/", + artifacts: "./artifacts", }, }; diff --git a/package.json b/package.json index 86aee1682..703e18179 100644 --- a/package.json +++ b/package.json @@ -20,8 +20,8 @@ "build": "yarn clean && yarn compile:typechain && yarn compile:client-dest", "lint": "yarn formatting && yarn solhint", "lint:check": "yarn formatting:check && yarn solhint:check", - "formatting": "yarn formatting:check --write", - "formatting:check": "prettier --check \"src/**/*.sol\"", + "formatting": "yarn prettier --write .", + "formatting:check": "prettier --check .", "solhint": "yarn solhint:check --fix", "solhint:check": "solhint --config ./.solhint.json \"src/**/*.sol\"" }, diff --git a/src/client/aztec/provider/index.ts b/src/client/aztec/provider/index.ts index 7d5fc85d2..c6b9f8601 100644 --- a/src/client/aztec/provider/index.ts +++ b/src/client/aztec/provider/index.ts @@ -1 +1 @@ -export * from './web3_provider'; +export * from "./web3_provider"; diff --git a/src/client/aztec/provider/web3_provider.ts b/src/client/aztec/provider/web3_provider.ts index 8d6b1512e..5dedf53d1 100644 --- a/src/client/aztec/provider/web3_provider.ts +++ b/src/client/aztec/provider/web3_provider.ts @@ -1,4 +1,4 @@ -import { Web3Provider } from '@ethersproject/providers'; -import { EthereumProvider } from '@aztec/barretenberg/blockchain'; +import { Web3Provider } from "@ethersproject/providers"; +import { EthereumProvider } from "@aztec/barretenberg/blockchain"; export const createWeb3Provider = (ethereumProvider: EthereumProvider) => new Web3Provider(ethereumProvider); diff --git a/src/client/element/element-bridge-data.test.ts b/src/client/element/element-bridge-data.test.ts index 1c47ea777..f0ed8a3ff 100644 --- a/src/client/element/element-bridge-data.test.ts +++ b/src/client/element/element-bridge-data.test.ts @@ -1,6 +1,6 @@ -import { ChainProperties, ElementBridgeData } from './element-bridge-data'; -import { BigNumber } from 'ethers'; -import { randomBytes } from 'crypto'; +import { ChainProperties, ElementBridgeData } from "./element-bridge-data"; +import { BigNumber } from "ethers"; +import { randomBytes } from "crypto"; import { RollupProcessor, ElementBridge, @@ -8,12 +8,12 @@ import { ElementBridge__factory, RollupProcessor__factory, IVault__factory, -} from '../../../typechain-types'; -import { BridgeId } from '@aztec/barretenberg/bridge_id'; -import { AztecAssetType } from '../bridge-data'; -import { EthAddress } from '@aztec/barretenberg/address'; +} from "../../../typechain-types"; +import { BridgeId } from "@aztec/barretenberg/bridge_id"; +import { AztecAssetType } from "../bridge-data"; +import { EthAddress } from "@aztec/barretenberg/address"; -jest.mock('../aztec/provider', () => ({ +jest.mock("../aztec/provider", () => ({ createWeb3Provider: jest.fn(), })); @@ -21,7 +21,7 @@ type Mockify = { [P in keyof T]: jest.Mock; }; -const randomAddress = () => `0x${randomBytes(20).toString('hex')}`; +const randomAddress = () => `0x${randomBytes(20).toString("hex")}`; const tranche1DeploymentBlockNumber = 45n; const tranche2DeploymentBlockNumber = 87n; @@ -43,7 +43,7 @@ interface Interaction { const interactions: { [key: number]: Interaction } = {}; -describe('element bridge data', () => { +describe("element bridge data", () => { let rollupContract: Mockify; let elementBridge: Mockify; let balancerContract: Mockify; @@ -138,12 +138,12 @@ describe('element bridge data', () => { return ElementBridgeData.create({} as any, EthAddress.ZERO, EthAddress.ZERO, EthAddress.ZERO, chainProperties); // can pass in dummy values here as the above factories do all of the work }; - it('should return the correct amount of interest', async () => { + it("should return the correct amount of interest", async () => { const elementBridgeData = createElementBridgeData(); interactions[56] = { quantityPT: BigNumber.from(outputValue), expiry: BigNumber.from(expiration1), - trancheAddress: '', + trancheAddress: "", finalised: false, failed: false, } as Interaction; @@ -160,7 +160,7 @@ describe('element bridge data', () => { expect(Number(daiValue.assetId)).toStrictEqual(bridge1.inputAssetIdA); }); - it('should return the correct amount of interest for multiple interactions', async () => { + it("should return the correct amount of interest for multiple interactions", async () => { const elementBridgeData = createElementBridgeData(); const testInteraction = async (nonce: number) => { const defiEvent = getDefiEvent(nonce)!; @@ -168,7 +168,7 @@ describe('element bridge data', () => { interactions[nonce] = { quantityPT: BigNumber.from(10n * 10n ** 18n), expiry: BigNumber.from(bridgeId.auxData), - trancheAddress: '', + trancheAddress: "", finalised: false, failed: false, } as Interaction; @@ -196,19 +196,19 @@ describe('element bridge data', () => { await testInteraction(190); }); - it('requesting the present value of an unknown interaction should return empty values', async () => { + it("requesting the present value of an unknown interaction should return empty values", async () => { const elementBridgeData = createElementBridgeData(); const values = await elementBridgeData.getInteractionPresentValue(57n, 0n); expect(values).toStrictEqual([]); }); - it('should return the correct expiration of the tranche', async () => { + it("should return the correct expiration of the tranche", async () => { const endDate = Math.floor(Date.now() / 1000) + 86400 * 60; elementBridge = { interactions: jest.fn().mockImplementation(async () => { return { quantityPT: BigNumber.from(1), - trancheAddress: '', + trancheAddress: "", expiry: BigNumber.from(endDate), finalised: false, failed: false, @@ -226,16 +226,16 @@ describe('element bridge data', () => { expect(expiration).toBe(BigInt(endDate)); }); - it('should return the correct yield of the tranche', async () => { + it("should return the correct yield of the tranche", async () => { const now = Math.floor(Date.now() / 1000); const expiry = BigInt(now + 86400 * 30); - const trancheAddress = '0x90ca5cef5b29342b229fb8ae2db5d8f4f894d652'; - const poolId = '0x90ca5cef5b29342b229fb8ae2db5d8f4f894d6520002000000000000000000b5'; + const trancheAddress = "0x90ca5cef5b29342b229fb8ae2db5d8f4f894d652"; + const poolId = "0x90ca5cef5b29342b229fb8ae2db5d8f4f894d6520002000000000000000000b5"; const interest = BigInt(1e16); const inputValue = BigInt(10e18), elementBridge = { - hashAssetAndExpiry: jest.fn().mockResolvedValue('0xa'), - pools: jest.fn().mockResolvedValue([trancheAddress, '', poolId]), + hashAssetAndExpiry: jest.fn().mockResolvedValue("0xa"), + pools: jest.fn().mockResolvedValue([trancheAddress, "", poolId]), provider: { getBlockNumber: jest.fn().mockResolvedValue(200), getBlock: jest.fn().mockResolvedValue({ timestamp: +now.toString(), number: 200 }), @@ -257,7 +257,7 @@ describe('element bridge data', () => { const output = await elementBridgeData.getExpectedYield( { assetType: AztecAssetType.ERC20, - erc20Address: 'test', + erc20Address: "test", id: 1n, }, { @@ -267,7 +267,7 @@ describe('element bridge data', () => { }, { assetType: AztecAssetType.ERC20, - erc20Address: 'test', + erc20Address: "test", id: 1n, }, { @@ -289,14 +289,14 @@ describe('element bridge data', () => { expect(output[0]).toBe(percent); }); - it('should return the correct market size for a given tranche', async () => { + it("should return the correct market size for a given tranche", async () => { const expiry = BigInt(Date.now() + 86400 * 30); const tokenAddress = randomAddress(); - const poolId = '0x90ca5cef5b29342b229fb8ae2db5d8f4f894d6520002000000000000000000b5'; + const poolId = "0x90ca5cef5b29342b229fb8ae2db5d8f4f894d6520002000000000000000000b5"; const tokenBalance = 10e18, elementBridge = { - hashAssetAndExpiry: jest.fn().mockResolvedValue('0xa'), - pools: jest.fn().mockResolvedValue([tokenAddress, '', poolId]), + hashAssetAndExpiry: jest.fn().mockResolvedValue("0xa"), + pools: jest.fn().mockResolvedValue([tokenAddress, "", poolId]), provider: { getBlockNumber: jest.fn().mockResolvedValue(200), getBlock: jest.fn().mockResolvedValue({ timestamp: +now.toString(), number: 200 }), @@ -316,7 +316,7 @@ describe('element bridge data', () => { const marketSize = await elementBridgeData.getMarketSize( { assetType: AztecAssetType.ERC20, - erc20Address: 'test', + erc20Address: "test", id: 1n, }, { @@ -326,7 +326,7 @@ describe('element bridge data', () => { }, { assetType: AztecAssetType.ERC20, - erc20Address: 'test', + erc20Address: "test", id: 1n, }, { diff --git a/src/client/element/element-bridge-data.ts b/src/client/element/element-bridge-data.ts index 31696567a..1bec939ec 100644 --- a/src/client/element/element-bridge-data.ts +++ b/src/client/element/element-bridge-data.ts @@ -1,4 +1,4 @@ -import { AssetValue, BridgeDataFieldGetters, AuxDataConfig, AztecAsset, SolidityType } from '../bridge-data'; +import { AssetValue, BridgeDataFieldGetters, AuxDataConfig, AztecAsset, SolidityType } from "../bridge-data"; import { ElementBridge, IVault, @@ -6,12 +6,12 @@ import { ElementBridge__factory, IVault__factory, RollupProcessor__factory, -} from '../../../typechain-types'; -import { AsyncDefiBridgeProcessedEvent } from '../../../typechain-types/RollupProcessor'; -import { EthereumProvider } from '@aztec/barretenberg/blockchain'; -import { createWeb3Provider } from '../aztec/provider'; -import { EthAddress } from '@aztec/barretenberg/address'; -import { BridgeId } from '@aztec/barretenberg/bridge_id'; +} from "../../../typechain-types"; +import { AsyncDefiBridgeProcessedEvent } from "../../../typechain-types/RollupProcessor"; +import { EthereumProvider } from "@aztec/barretenberg/blockchain"; +import { createWeb3Provider } from "../aztec/provider"; +import { EthAddress } from "@aztec/barretenberg/address"; +import { BridgeId } from "@aztec/barretenberg/bridge_id"; export type BatchSwapStep = { poolId: string; @@ -254,7 +254,7 @@ export class ElementBridgeData implements BridgeDataFieldGetters { start: 0, length: 64, solidityType: SolidityType.uint64, - description: 'Unix Timestamp of the tranch expiry', + description: "Unix Timestamp of the tranch expiry", }, ]; @@ -295,7 +295,7 @@ export class ElementBridgeData implements BridgeDataFieldGetters { assetInIndex: 0, assetOutIndex: 1, amount: precision.toString(), - userData: '0x', + userData: "0x", }; const deltas = await this.balancerContract.queryBatchSwap( diff --git a/src/client/example/example-bridge-data.ts b/src/client/example/example-bridge-data.ts index b0287d932..d6960b087 100644 --- a/src/client/example/example-bridge-data.ts +++ b/src/client/example/example-bridge-data.ts @@ -1,4 +1,4 @@ -import { AssetValue, AuxDataConfig, AztecAsset, BridgeDataFieldGetters, SolidityType } from '../bridge-data'; +import { AssetValue, AuxDataConfig, AztecAsset, BridgeDataFieldGetters, SolidityType } from "../bridge-data"; export class ExampleBridgeData implements BridgeDataFieldGetters { constructor() {} @@ -30,7 +30,7 @@ export class ExampleBridgeData implements BridgeDataFieldGetters { start: 0, length: 64, solidityType: SolidityType.uint64, - description: 'Not Used', + description: "Not Used", }, ]; diff --git a/src/specs/TEMPLATE.md b/src/specs/TEMPLATE.md index 5725cf45d..d19b0ed49 100644 --- a/src/specs/TEMPLATE.md +++ b/src/specs/TEMPLATE.md @@ -1,34 +1,37 @@ # Aztec Connect Bridges Specification Template -*Help the Aztec community make Aztec Connect easier to build on and interact with by documenting your work. -This spec template is meant to help you provide all of the information that a developer needs to work with your bridge. -Complete specifications will be linked in the official Aztec docs at https://docs.aztec.network.* +_Help the Aztec community make Aztec Connect easier to build on and interact with by documenting your work. +This spec template is meant to help you provide all of the information that a developer needs to work with your bridge. +Complete specifications will be linked in the official Aztec docs at https://docs.aztec.network._ You can view an example spec [here](#add-link). 1. What does this bridge do? Why did you build it? 2. What protocol(s) does the bridge interact with? - - Include links to website, github, etherscan, etc - - Include a small description of the protocol(s) + + - Include links to website, github, etherscan, etc + - Include a small description of the protocol(s) 3. What is the flow of the bridge? - - What actions does this bridge make possible? - - Are all bridge interactions synchronous, or is the a asynchronous flow? - - For each interaction define: - - All input tokens, including [AztecType](https://github.com/AztecProtocol/aztec-connect-bridges/blob/master/src/aztec/libraries/AztecTypes.sol) info - - All output tokens, including [AztecType](https://github.com/AztecProtocol/aztec-connect-bridges/blob/master/src/aztec/libraries/AztecTypes.sol) info - - All relevant bridge ids (may fill in after deployment) - - use of auxData - - gas usage - - cases that that would make the interaction revert (low liquidity etc) - - Please include any diagrams that would be helpful to understand asset flow. -4. Please list any edge cases that may restrict the usefulness of the bridge or that the bridge prevents explicit. + - What actions does this bridge make possible? + - Are all bridge interactions synchronous, or is the a asynchronous flow? + - For each interaction define: + - All input tokens, including [AztecType](https://github.com/AztecProtocol/aztec-connect-bridges/blob/master/src/aztec/libraries/AztecTypes.sol) info + - All output tokens, including [AztecType](https://github.com/AztecProtocol/aztec-connect-bridges/blob/master/src/aztec/libraries/AztecTypes.sol) info + - All relevant bridge ids (may fill in after deployment) + - use of auxData + - gas usage + - cases that that would make the interaction revert (low liquidity etc) + - Please include any diagrams that would be helpful to understand asset flow. + +4. Please list any edge cases that may restrict the usefulness of the bridge or that the bridge prevents explicit. -5. How can the accounting of the bridge be impacted by interactions performed by other parties than the bridge? Example, if borrowing, how does it handle liquidations etc. +5. How can the accounting of the bridge be impacted by interactions performed by other parties than the bridge? Example, if borrowing, how does it handle liquidations etc. 6. What functions are available in [/src/client](./client)? - - How should they be used? + + - How should they be used? 7. Is this contract upgradable? If so, what are the restrictions on upgradability? diff --git a/src/specs/lido/readme.md b/src/specs/lido/readme.md index ca269d86e..ba9e622a1 100644 --- a/src/specs/lido/readme.md +++ b/src/specs/lido/readme.md @@ -1,65 +1,77 @@ # Spec for Lido Bridge ## What does the bridge do? Why build it? -The bridge deposits into Lido to receive `stEth` a staked eth derivative that earns a yield from staking rewards at the beaconchain. We build it to allow users to earn yield on their eth. + +The bridge deposits into Lido to receive `stEth` a staked eth derivative that earns a yield from staking rewards at the beaconchain. We build it to allow users to earn yield on their eth. ## What protocol(s) does the bridge interact with ? The bridge interacts with two protocols, namely Lido and Curve. -[Lido](https://lido.fi/) is a project that build liquid staking derivatives. They allow users to deposit stakeable assets (Eth, Sol etc) and in return get a representation of the staked asset which will grow with staking rewards. We will only be working with `stEth` (staked ether), so we will be using that for explanations going on. +[Lido](https://lido.fi/) is a project that build liquid staking derivatives. They allow users to deposit stakeable assets (Eth, Sol etc) and in return get a representation of the staked asset which will grow with staking rewards. We will only be working with `stEth` (staked ether), so we will be using that for explanations going on. `stEth` is a rebasing ERC20 token, and a users balance of it will grow/shrink based on accrued staking rewards or slashing events. After the Merge and the hardfork making it possible to withdraw staked ether from the beacon chain, `stEth` can be burned to redeem an equal amount of `eth`. Until then, `stEth` cannot be redeemed at lido directly, but can instead be traded at a secondary market, such as [curve.fi](https://curve.fi/steth). [Curve](https://curve.fi/) is a AMM that specializes in pools with low internal volatility (stableswap). It is at the time of writing, the most liquid market for trading between `stEth` and `eth`. ## What is the flow of the bridge? -There are two flows of Lido Bridge, namely deposits and withdraws. + +There are two flows of Lido Bridge, namely deposits and withdraws. ![Lido flows](./LidoBridge.svg) -### Deposit +### Deposit + If the bridge receives `eth` as the input token it will deposit it into the Lido contract along a referall address. In return, the bridge will receive `stEth` which it will wrap to `wstEth` before return the tuple `(wstEthAmount, 0, false)` and the rollup pulls the `wstEth` tokens. The gas cost E2E for a deposit is ~175K, this is including the transfers to/from the Rollup Processor. **Edge cases**: + - There is a limit on the size of deposits, so a very large whale might not be able to enter - The limit is subject to change, so it might influence smaller users over time - If Lido don't return sufficient `stEth` for the given `eth` deposit, the transaction will revert. ### Withdrawal -If the bridge receives `wstEth` as the input token, it will unwrap them to `stEth` before going to curve, where it will swap it (NOTICE: it accepts any slippage). It will then transfer the eth received to the `ROLLUP_PROCESSOR` for the given `interactionNonce`. + +If the bridge receives `wstEth` as the input token, it will unwrap them to `stEth` before going to curve, where it will swap it (NOTICE: it accepts any slippage). It will then transfer the eth received to the `ROLLUP_PROCESSOR` for the given `interactionNonce`. The gas cost E2E for a withdraw is ~250K, this is including the transfers to/from the Rollup Processor. **Edge cases** -- If the balance of the bridge is less than the value returned by `exchange` on curve, the transaction will revet. E.g., if curve transfers fewer tokens than it tell us in the returnvalue. + +- If the balance of the bridge is less than the value returned by `exchange` on curve, the transaction will revet. E.g., if curve transfers fewer tokens than it tell us in the returnvalue. ### General Properties for both deposit and withdrawal + - The bridge is synchronous, and will always return `isAsync = false`. - The bridge does not use an `auxData` -- *Note*: Because `stEth` is rebasing, we wrap/unwrap it to `wstEth` (wrapped staked ether). This is to ensure that values are as expected when exiting from or transferring within the Rollup. +- _Note_: Because `stEth` is rebasing, we wrap/unwrap it to `wstEth` (wrapped staked ether). This is to ensure that values are as expected when exiting from or transferring within the Rollup. - The Bridge perform token pre-approvals in the constructor to allow the `ROLLUP_PROCESSOR`, `WRAPPED_STETH` and `CURVE_POOL` to pull tokens from it. This is to reduce gas-overhead when performing the actions. It is safe to do, as the bridge is not holding funds itself. ## Can tokens balances be impacted by external parties, if yes, how? + As we are using the wrapped variation of `stEth` it will not directly be impacted by rewards or slashing. However, the amount of `stEth` it can be unwrapped to might deviate from the expected if there has been a slashing event. ## Is the contract upgradeable? + No, the bridge is immutable without any admin role. ## Does the bridge maintain state? + No, the bridge don't maintain a state. However, it keep an insignificant amount of token (dust) in the bridge to reduce gas-costs of future transactions. By having dust, we don't need to do a `sstore` from `0` to `non-zero`. ## Is the contract upgradeable? + No, the bridge is immutable without any admin role. ## Does the bridge maintain state? + No, the bridge don't maintain a state. However, it keep an insignificant amount of token (dust) in the bridge to reduce gas-costs of future transactions. By having dust, we don't need to do a `sstore` from `0` to `non-zero`. ## What about withdrawing after the merge and hardfork? -When Lido can support withdraws directly, a new bridge can be made that performs this interaction. Because the bridge don't hold the tokens, the user is free to take his shielded L2 `wstEth` and go to any other bridge to use them to his liking. +When Lido can support withdraws directly, a new bridge can be made that performs this interaction. Because the bridge don't hold the tokens, the user is free to take his shielded L2 `wstEth` and go to any other bridge to use them to his liking. diff --git a/src/specs/mstable/spec.md b/src/specs/mstable/spec.md index 349d429a9..481a2c07e 100644 --- a/src/specs/mstable/spec.md +++ b/src/specs/mstable/spec.md @@ -9,4 +9,3 @@ The bridge can only be accessed with any bridging functionality through the `con If the bridge's `convert` method is supplied DAI on Ethereum, it will return the caller with the best priced amount of imUSD via mStable smart contracts. If the bridge's `convert` method is is supplied imUSD on Ethereum, it will return the caller with the best priced amount of DAI via mStable smart contracts. -