Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 15 additions & 23 deletions docs/examples/solidity/aave_bridge/AavePortal.sol
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,9 @@ contract AavePortal {

bool private _initialized;

function initialize(
address _registry,
address _underlying,
address _aToken,
address _aavePool,
bytes32 _l2Bridge
) external {
function initialize(address _registry, address _underlying, address _aToken, address _aavePool, bytes32 _l2Bridge)
external
{
require(!_initialized, "Already initialized");
_initialized = true;

Expand All @@ -55,6 +51,7 @@ contract AavePortal {
inbox = rollup.getInbox();
rollupVersion = rollup.getVersion();
}

// docs:end:portal_setup

// docs:start:portal_deposit_to_aave
Expand All @@ -65,6 +62,7 @@ contract AavePortal {
uint256 _amount,
bool _withCaller,
Epoch _epoch,
uint256 _numCheckpointsInEpoch,
uint256 _leafIndex,
bytes32[] calldata _path
) external {
Expand All @@ -74,31 +72,28 @@ contract AavePortal {
recipient: DataStructures.L1Actor(address(this), block.chainid),
content: Hash.sha256ToField(
abi.encodeWithSignature(
"withdraw(address,uint256,address)",
_recipient,
_amount,
_withCaller ? msg.sender : address(0)
"withdraw(address,uint256,address)", _recipient, _amount, _withCaller ? msg.sender : address(0)
)
)
});

// Consume the message from the outbox (verifies merkle proof)
outbox.consume(message, _epoch, _leafIndex, _path);
outbox.consume(message, _epoch, _numCheckpointsInEpoch, _leafIndex, _path);

// Deposit into Aave instead of sending tokens to the recipient.
// The portal must already hold the underlying tokens (pre-funded or bridged separately).
underlying.approve(address(aavePool), _amount);
aavePool.supply(address(underlying), _amount, address(this), 0);
}

// docs:end:portal_deposit_to_aave

// docs:start:portal_claim_public
/// @notice Withdraw from Aave and send an L1->L2 message to mint tokens publicly on L2
function claimFromAavePublic(
uint256 _aTokenAmount,
bytes32 _to,
bytes32 _secretHash
) external returns (bytes32, uint256) {
function claimFromAavePublic(uint256 _aTokenAmount, bytes32 _to, bytes32 _secretHash)
external
returns (bytes32, uint256)
{
// Withdraw from Aave (returns underlying + yield)
aToken.approve(address(aavePool), _aTokenAmount);
uint256 withdrawn = aavePool.withdraw(address(underlying), _aTokenAmount, address(this));
Expand All @@ -111,22 +106,19 @@ contract AavePortal {
(bytes32 key, uint256 index) = inbox.sendL2Message(actor, contentHash, _secretHash);
return (key, index);
}

// docs:end:portal_claim_public

// docs:start:portal_claim_private
/// @notice Withdraw from Aave and send an L1->L2 message to mint tokens privately on L2
function claimFromAavePrivate(
uint256 _aTokenAmount,
bytes32 _secretHash
) external returns (bytes32, uint256) {
function claimFromAavePrivate(uint256 _aTokenAmount, bytes32 _secretHash) external returns (bytes32, uint256) {
// Withdraw from Aave (returns underlying + yield)
aToken.approve(address(aavePool), _aTokenAmount);
uint256 withdrawn = aavePool.withdraw(address(underlying), _aTokenAmount, address(this));

// Send L1->L2 message for private minting
DataStructures.L2Actor memory actor = DataStructures.L2Actor(l2Bridge, rollupVersion);
bytes32 contentHash =
Hash.sha256ToField(abi.encodeWithSignature("mint_to_private(uint256)", withdrawn));
bytes32 contentHash = Hash.sha256ToField(abi.encodeWithSignature("mint_to_private(uint256)", withdrawn));

(bytes32 key, uint256 index) = inbox.sendL2Message(actor, contentHash, _secretHash);
return (key, index);
Expand Down
42 changes: 15 additions & 27 deletions docs/examples/solidity/example_swap/ExampleTokenPortal.sol
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,7 @@ contract ExampleTokenPortal {
uint256 public rollupVersion;

/// @dev No access control for simplicity. A production contract should restrict this to the deployer/owner.
function initialize(
address _registry,
address _underlying,
bytes32 _l2Bridge
) external {
function initialize(address _registry, address _underlying, bytes32 _l2Bridge) external {
registry = IRegistry(_registry);
underlying = IERC20(_underlying);
l2Bridge = _l2Bridge;
Expand All @@ -41,37 +37,32 @@ contract ExampleTokenPortal {
inbox = rollup.getInbox();
rollupVersion = rollup.getVersion();
}

// docs:end:example_token_portal

// docs:start:deposit_to_aztec_public
/// @notice Deposit tokens and send L1->L2 message for public minting on Aztec
function depositToAztecPublic(
bytes32 _to,
uint256 _amount,
bytes32 _secretHash
) external returns (bytes32, uint256) {
function depositToAztecPublic(bytes32 _to, uint256 _amount, bytes32 _secretHash)
external
returns (bytes32, uint256)
{
DataStructures.L2Actor memory actor = DataStructures.L2Actor(l2Bridge, rollupVersion);

bytes32 contentHash = Hash.sha256ToField(
abi.encodeWithSignature("mint_to_public(bytes32,uint256)", _to, _amount)
);
bytes32 contentHash =
Hash.sha256ToField(abi.encodeWithSignature("mint_to_public(bytes32,uint256)", _to, _amount));

underlying.safeTransferFrom(msg.sender, address(this), _amount);

return inbox.sendL2Message(actor, contentHash, _secretHash);
}

// docs:end:deposit_to_aztec_public

/// @notice Deposit tokens and send L1->L2 message for private minting on Aztec
function depositToAztecPrivate(
uint256 _amount,
bytes32 _secretHash
) external returns (bytes32, uint256) {
function depositToAztecPrivate(uint256 _amount, bytes32 _secretHash) external returns (bytes32, uint256) {
DataStructures.L2Actor memory actor = DataStructures.L2Actor(l2Bridge, rollupVersion);

bytes32 contentHash = Hash.sha256ToField(
abi.encodeWithSignature("mint_to_private(uint256)", _amount)
);
bytes32 contentHash = Hash.sha256ToField(abi.encodeWithSignature("mint_to_private(uint256)", _amount));

underlying.safeTransferFrom(msg.sender, address(this), _amount);

Expand All @@ -80,27 +71,24 @@ contract ExampleTokenPortal {

// docs:start:withdraw
/// @notice Withdraw tokens after consuming an L2->L1 message.
/// @param _numCheckpointsInEpoch The partial-proof depth (1-indexed) the witness was built against.
function withdraw(
address _recipient,
uint256 _amount,
Epoch _epoch,
uint256 _numCheckpointsInEpoch,
uint256 _leafIndex,
bytes32[] calldata _path
) external {
DataStructures.L2ToL1Msg memory message = DataStructures.L2ToL1Msg({
sender: DataStructures.L2Actor(l2Bridge, rollupVersion),
recipient: DataStructures.L1Actor(address(this), block.chainid),
content: Hash.sha256ToField(
abi.encodeWithSignature(
"withdraw(address,uint256,address)",
_recipient,
_amount,
msg.sender
)
abi.encodeWithSignature("withdraw(address,uint256,address)", _recipient, _amount, msg.sender)
)
});

outbox.consume(message, _epoch, _leafIndex, _path);
outbox.consume(message, _epoch, _numCheckpointsInEpoch, _leafIndex, _path);

underlying.safeTransfer(_recipient, _amount);
}
Expand Down
36 changes: 13 additions & 23 deletions docs/examples/solidity/example_swap/ExampleUniswapPortal.sol
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ contract ExampleUniswapPortal {
outbox = rollup.getOutbox();
rollupVersion = rollup.getVersion();
}

// docs:end:example_uniswap_portal

// docs:start:swap_public
Expand All @@ -49,19 +50,15 @@ contract ExampleUniswapPortal {
bytes32 _secretHashForL1ToL2Message,
// Outbox message metadata for the two L2->L1 messages
Epoch[2] calldata _epochs,
uint256[2] calldata _numCheckpointsInEpochs,
uint256[2] calldata _leafIndices,
bytes32[][2] calldata _paths
) external returns (bytes32, uint256) {
IERC20 outputAsset = ExampleTokenPortal(_outputTokenPortal).underlying();

// Message 1: Consume the token bridge exit message (withdraw input tokens)
ExampleTokenPortal(_inputTokenPortal).withdraw(
address(this),
_inAmount,
_epochs[0],
_leafIndices[0],
_paths[0]
);
ExampleTokenPortal(_inputTokenPortal)
.withdraw(address(this), _inAmount, _epochs[0], _numCheckpointsInEpochs[0], _leafIndices[0], _paths[0]);

// Message 2: Consume the uniswap swap intent message
bytes32 contentHash = Hash.sha256ToField(
Expand All @@ -84,6 +81,7 @@ contract ExampleUniswapPortal {
content: contentHash
}),
_epochs[1],
_numCheckpointsInEpochs[1],
_leafIndices[1],
_paths[1]
);
Expand All @@ -94,12 +92,10 @@ contract ExampleUniswapPortal {

// Approve output token portal and deposit back to Aztec
outputAsset.approve(_outputTokenPortal, amountOut);
return ExampleTokenPortal(_outputTokenPortal).depositToAztecPublic(
_aztecRecipient,
amountOut,
_secretHashForL1ToL2Message
);
return ExampleTokenPortal(_outputTokenPortal)
.depositToAztecPublic(_aztecRecipient, amountOut, _secretHashForL1ToL2Message);
}

// docs:end:swap_public

// docs:start:swap_private
Expand All @@ -113,19 +109,15 @@ contract ExampleUniswapPortal {
bytes32 _secretHashForL1ToL2Message,
// Outbox message metadata for the two L2->L1 messages
Epoch[2] calldata _epochs,
uint256[2] calldata _numCheckpointsInEpochs,
uint256[2] calldata _leafIndices,
bytes32[][2] calldata _paths
) external returns (bytes32, uint256) {
IERC20 outputAsset = ExampleTokenPortal(_outputTokenPortal).underlying();

// Message 1: Consume the token bridge exit message (withdraw input tokens)
ExampleTokenPortal(_inputTokenPortal).withdraw(
address(this),
_inAmount,
_epochs[0],
_leafIndices[0],
_paths[0]
);
ExampleTokenPortal(_inputTokenPortal)
.withdraw(address(this), _inAmount, _epochs[0], _numCheckpointsInEpochs[0], _leafIndices[0], _paths[0]);

// Message 2: Consume the uniswap swap intent message
bytes32 contentHash = Hash.sha256ToField(
Expand All @@ -147,6 +139,7 @@ contract ExampleUniswapPortal {
content: contentHash
}),
_epochs[1],
_numCheckpointsInEpochs[1],
_leafIndices[1],
_paths[1]
);
Expand All @@ -157,10 +150,7 @@ contract ExampleUniswapPortal {

// Approve output token portal and deposit back to Aztec privately
outputAsset.approve(_outputTokenPortal, amountOut);
return ExampleTokenPortal(_outputTokenPortal).depositToAztecPrivate(
amountOut,
_secretHashForL1ToL2Message
);
return ExampleTokenPortal(_outputTokenPortal).depositToAztecPrivate(amountOut, _secretHashForL1ToL2Message);
}
// docs:end:swap_private
}
4 changes: 3 additions & 1 deletion docs/examples/solidity/nft_bridge/NFTPortal.sol
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ contract NFTPortal {
inbox = rollup.getInbox();
rollupVersion = rollup.getVersion();
}

// docs:end:portal_setup

// docs:start:portal_deposit_and_withdraw
Expand All @@ -52,6 +53,7 @@ contract NFTPortal {
function withdraw(
uint256 tokenId,
Epoch epoch,
uint256 numCheckpointsInEpoch,
uint256 leafIndex,
bytes32[] calldata path
) external {
Expand All @@ -62,7 +64,7 @@ contract NFTPortal {
content: Hash.sha256ToField(abi.encodePacked(tokenId, msg.sender))
});

outbox.consume(message, epoch, leafIndex, path);
outbox.consume(message, epoch, numCheckpointsInEpoch, leafIndex, path);

// Unlock NFT
nftContract.transferFrom(address(this), msg.sender, tokenId);
Expand Down
Loading
Loading