主要代码见:
本文主要借助Element Finance的Aztec Connect Contract合约来说明。
在Element Finance中,有一些对aztec connect bridge合约有用的流程:
最容易支持的流程是从AMM购买token 以及 支持token赎回。
取决于存入的资产 以及 想要支持的粒度,有3种潜在的实现方式:
用户在zk.money中已有相应的source assets,或者愿意支付gas费来向zk.money存入资产。
Element支持的资产类型有:DAI/USDC/WBTC,以及,crv3crypto, steCRV等复合资产。
相应的用户流程为:
auxData
来选择正确的pool expiry。totalInputValue
个principal token。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
函数将执行以下操作:
block.coinbase
或msg.sender
支付fee。可计算为a gas multiplier and paid from the collateral.redemption。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;
}
假设用户在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
方案1的主要优点为:
方案2的主要缺点为:
withDrawPrincipal
的分摊受限于input batch size,而不是所有用户。仍然要求用户在Aztec中有source assets。但是整个流程分为了2部分:
1)购买Principal token。用户购买Element中的principal token,这些principal token会返回到Aztec L2层用户。
auxData
来选择正确的pool expiry。totalInputValue
个principal token。outputValueA
个principal token。2)赎回Principal token:此时L2层的Aztec中的用户具有principal token,在到期时,该客户可发起第二次DeFi bridge交互,来将其principal token兑换为基础抵押品。
withDrawPrincipal()
将principal token兑换为基础抵押品。outputValueA
。整个流程中可选择检查auxData
来判断用户是否设置了redeem或rollover flag。若设置了rollover flag,则抵押品将re-invested by purchasing new principal tokens in the new tranche。
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的缺点主要有:
在方案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