Aztec connect bridge代码解析

1. 引言

主要代码见:

  • https://github.com/AztecProtocol/aztec-connect-bridges(Solidity)
  • https://github.com/AztecProtocol/defi-bridge-hackathon(JavaScript)

本文主要借助Element Finance的Aztec Connect Contract合约来说明。

1.1 关键词解释

  • Principal Token:表示lender存入defi中的抵押品。
  • Yield Token:表示lender因存放抵押品而产生的可变利息。

2. aztec connect bridge集成方案

在Element Finance中,有一些对aztec connect bridge合约有用的流程:

  • 1)从AMM中以一定折扣购买principal tokens,按期持有并赎回。
  • 2)批量赎回。
  • 3)Auto rollover of mints。自动累加mints。

最容易支持的流程是从AMM购买token 以及 支持token赎回。
取决于存入的资产 以及 想要支持的粒度,有3种潜在的实现方式:

  • 1)Direct Async Bridge Flow:用户在zk.money中已有相应的source assets,或者愿意支付gas费来向zk.money存入资产。

2.1 方案1——Direct Async Bridge Flow

用户在zk.money中已有相应的source assets,或者愿意支付gas费来向zk.money存入资产。

Element支持的资产类型有:DAI/USDC/WBTC,以及,crv3crypto, steCRV等复合资产。

相应的用户流程为:

  • 1)用户在aztec L2层,选择所支持资产的shielded balance,发起一笔DeFi deposit交易。
  • 2)aztec L2层 与 以太坊L1层 之间的rollup provider,会将L2层的交易打包,以每 n n n笔一组。
  • 3)rollup provider会将打包后的交易提交到以太坊L1层的Aztec Rollup合约。
  • 4)以太坊L1层的Aztec Rollup合约会调用部署在L1层的相应的Element的bridge合约。该bridge合约会受到来自于Aztec Rollup合约的aggregated transaction,在bridge合约内:
    • 4.1)若对input asset有多个Element池,则DBC应使用auxData来选择正确的pool expiry。
    • 4.2)将以given input asset ERC20 tokens,从Element AMM中购买totalInputValue个principal token。
    • 4.3)记录购买交互操作中的interaction nonce值 和 所购买的principal token数量。
    • 4.4)记录interaction nonce值 和 相应的到期日,使得该异步交易可在后续日期finalised。
    • 4.5)给L1层的Aztec Rollup合约返回isAsync=true

bridge合约中应有一个public函数,可返回a list of bridges that can be finalised。

对于返回的每个bridge的interactionNonce值,可创建一笔以太坊交易,调用Aztec Rollup合约中的RollupContract.processAsyncDefiInteraction(uint256 interactionNonce)来最终finalise on the bridge contract。

// Aztec Rollup合约
function processAsyncDeFiInteraction(uint256 interactionNonce) external {
        // call canFinalise on the bridge
        // call finalise on the bridge
        DefiInteraction storage interaction = defiInteractions[
            interactionNonce
        ];
        require(
            interaction.bridgeAddress != address(0),
            "Rollup Contract: UNKNOWN_NONCE"
        );

        (uint256 outputValueA, uint256 outputValueB, bool interactionComplete) = IDefiBridge(
            interaction.bridgeAddress
        ).finalise(
                interaction.inputAssetA,
                interaction.inputAssetB,
                interaction.outputAssetA,
                interaction.outputAssetB,
                interaction.interactionNonce,
                uint64(interaction.auxInputData)
            );
            .......
}

在Element bridge合约中,其finalise函数将执行以下操作:

  • 1)将principal token兑换为基础抵押品。
  • 2)向提供此服务的block.coinbasemsg.sender支付fee。可计算为a gas multiplier and paid from the collateral.redemption。
  • 3)返回 基础抵押品 + 利息 到aztec rollup合约中,返回outputAssetA的正确值。
// Element Bridge合约
// serves as the 'off ramp' for the transaction
  // converts the principal tokens back to the underlying asset
  function finalise(
    AztecTypes.AztecAsset calldata,
    AztecTypes.AztecAsset calldata,
    AztecTypes.AztecAsset calldata outputAssetA,
    AztecTypes.AztecAsset calldata,
    uint256 interactionNonce,
    uint64
  ) external payable returns (uint256 outputValueA, uint256 outputValueB, bool interactionComplete) {

    require(msg.sender == rollupProcessor, "ElementBridge: INVALID_CALLER");
    // retrieve the interaction and verify it's ready for finalising
    Interaction storage interaction = interactions[interactionNonce];
    require(interaction.expiry != 0, "ElementBridge: UNKNOWN_NONCE");
    require(
      interaction.expiry <= block.timestamp,
      "ElementBridge: BRIDGE_NOT_READY"
    );
    require(!interaction.finalised, "ElementBridge: ALREADY_FINALISED");

    // convert the tokens back to underlying using the tranche
    console.log("Withdrawing %s principal tokens", interaction.quantityPT);
    console.log("Total supply %s", ITranche(interaction.trancheAddress).totalSupply());
    outputValueA = ITranche(interaction.trancheAddress).withdrawPrincipal(
      interaction.quantityPT,
      address(this)
    );
    // approve the transfer of funds back to the rollup contract
    ERC20(outputAssetA.erc20Address).approve(rollupProcessor, outputValueA);

    // interaction is completed. clean up the expiry heap
    interaction.finalised = true;
    popInteraction(interaction, interactionNonce);
    console.log("Successfully finalised interaction: ", interactionNonce);
    interactionComplete = true;
  }

2.1.1 方案1——gas cost分析

假设用户在Aztec中有source assets,不同的batch size的gas cost为:

Item Gas User Share
JoinSplit for chaining 7500 1
DeFi Bridge Deposit 7500 1
Element AMM Buy Interaction 18000 1/n
Element withDrawPrincipal() 150000-750000 1/n
DeFi claim proof 7500 1

整个enter和exit cost为:
主网:330000~930000

Batch Size 10: gas = 55,500 - 111,500 ~6 - 10x
Batch Size 50: gas = 29,100 - 41,500 ~10 - 20x
Batch Size 100: gas = 25,800 - 31,800 ~12 - 40x

2.1.2 方案1——优缺点分析

方案1的主要优点为:

  • 1)非常简单
  • 2)仅需要一笔Aztec交易,entry和Exit的gas cost可分摊。
  • 3)资产和利息将自动返回到Aztec L2层的用户账号中。

方案2的主要缺点为:

  • 1)用户无法交易,需按期锁定,用户失去了选择权。
  • 2)withDrawPrincipal的分摊受限于input batch size,而不是所有用户。
  • 3)协调batching entry比batching exit更难。因此,实际设置时,batch size会设置为10而不是100,节约的gas仅为约3~9倍。

2.2 方案2——Non-async Flow

仍然要求用户在Aztec中有source assets。但是整个流程分为了2部分:

  • 1)购买Principal token。用户购买Element中的principal token,这些principal token会返回到Aztec L2层用户。

    • 1.1)选择所支持的资产,用户在L2层从其shielded balance中发起一笔DeFi deposit交易。
    • 1.2)rollup provider会将多笔交易打包在一起。
    • 1.3)rollup provider将打包的交易提交到L1层的Aztec Rollup合约。
    • 1.4)L1层的Aztec Rollup合约会调用相应的Element bridge合约。
    • 1.5)L1层的Element bridge合约会从Aztec Rollup合约中收到an aggregated transaction。Element bridge合约会做如下操作:
      • 4.1)若对input asset有多个Element池,则DBC应使用auxData来选择正确的pool expiry。
      • 4.2)将以given input asset ERC20 tokens,从Element AMM中购买totalInputValue个principal token。
      • 4.3)将给L1层的Aztec Rollup合约transfer outputValueA个principal token。
  • 2)赎回Principal token:此时L2层的Aztec中的用户具有principal token,在到期时,该客户可发起第二次DeFi bridge交互,来将其principal token兑换为基础抵押品。

    • 2.1)在L2层,用户将其principal token的shielded balance发起一笔DeFi deposit 交易。
    • 2.2)rollup provider将多笔交易打包。
    • 2.3)rollup provider将打包后的交易提交给L1层的Aztec Rollup合约。
    • 2.4)L1层的Aztec Rollup合约会调用相应的Element bridge合约。
    • 2.5)L1层的Element bridge合约会收到来自于Aztec Rollup合约的aggregated transaction。Element bridge合约会做如下操作:
      • 2.5.1)通过withDrawPrincipal()将principal token兑换为基础抵押品。
      • 2.5.2)将收到的抵押品token transfer给L1层的Aztec Rollup合约,数量为outputValueA

整个流程中可选择检查auxData来判断用户是否设置了redeem或rollover flag。若设置了rollover flag,则抵押品将re-invested by purchasing new principal tokens in the new tranche。

2.2.1 方案2的gas cost分析

Entry cost为:

Item Gas User Share
DeFi Bridge Deposit 7500 1
Element AMM Buy Interaction 180000 1/n
DeFi claim proof 7500 1

mainnet:180000

Batch Size 10: gas = 33,000 ~5x
Batch Size 50: gas = 18,600 ~10x
Batch Size 100: gas = 16,800 ~10x

Exit cost:
相比于方案1,到期时所有用户发起赎回的batch size要更高。

Item Gas User Share
Optional Deposit of Element PY tokens 6500 1?
DeFi Bridge Deposit 75000 1
Element withDrawCollateral 150000~750000 1/n
DeFi claim proof 7500 1

Main-net: 150,000 - 750,000

Batch Size 10: gas = 30,000 - 90,000 (5x - 8x)
Batch Size 50: gas = 18,000 - 30,000 (9x - 20x)
Batch Size 100: gas = 16,000 - 22,500 (9x - 30x)

With L1 Deposit For users that didn’t enter on Aztec.

Batch Size 10: gas = 90,000 - 150,000 (1.5x - 5x)
Batch Size 50: gas = 78,000 - 90,000 (2x - 10x)
Batch Size 100: gas = 76,500 - 82,500 (2x - 10x)

2.2.2 方案2优缺点分析

方案2的优点主要有:

  • 1)All users should be able to redeem together with 30x gas savings.
  • 2)Users who bought a fixed rate on L1 can use the bridge to redeem with ~2-10x gas savings.
  • 3)Users can trade in and out of fixed rates - no lockin
  • 4)Rollover support is possible

方案2的缺点主要有:

  • 1)More complex to build
  • 2)Redemptions are not automatic
  • 3)Requires 2x Aztec transactions
  • 4)How do we pay fees in element principal tokens…
    • 4.1)This is an issue, these tokens only have value if claimed on Element and this costs 150-750k gas.
    • 4.2)The bridge can pay, but makes it hard to quote a fee to the user + falafel would have to assess based on the size of the defi tx how much it gets.

2.3 方案3

在方案1或方案2的基础上增加。不再要求用户在L2 Aztec中有source assets。
在方案3中,用户仅需要有zkETH。

参考资料

[1] Private DeFi with the Aztec Connect Bridge
[2] 2021年11月 ZK HACK #5 - Introduction to Aztec Connect
[3] 2021年4月 Zk-zk-Rollup & zk.money with Zac and Joe from Aztec
[4] Element Finance Aztec Connect Contract
[5] Element Finance团队2021年12月博客 Fixed Rates for Everyone: L2 Scaling is Coming to Element

你可能感兴趣的:(区块链,区块链,跨链,零知识证明)