Skip to content

Commit

Permalink
Merge a4d67ef into fd0e945
Browse files Browse the repository at this point in the history
  • Loading branch information
just-mitch authored Oct 1, 2024
2 parents fd0e945 + a4d67ef commit d802d44
Show file tree
Hide file tree
Showing 44 changed files with 923 additions and 395 deletions.
4 changes: 2 additions & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@
"*.macros": "cpp",
"*.tpp": "cpp"
},
"solidity.compileUsingRemoteVersion": "v0.8.18",
"solidity.compileUsingRemoteVersion": "v0.8.27",
"solidity.formatter": "forge",
"search.exclude": {
"**/.yarn": true,
Expand Down Expand Up @@ -171,5 +171,5 @@
},
"files.trimTrailingWhitespace": true,
"cmake.sourceDirectory": "${workspaceFolder}/barretenberg/cpp",
"typescript.tsserver.maxTsServerMemory": 4096,
"typescript.tsserver.maxTsServerMemory": 4096
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ This imports relevant files including the interfaces used by the Aztec rollup. A

Create a basic ERC20 contract that can mint tokens to anyone. We will use this to test.

Create a file `PortalERC20.sol` in the same folder and add:
Create a file `TestERC20.sol` in the same folder and add:

#include_code contract /l1-contracts/test/portals/PortalERC20.sol solidity
#include_code contract /l1-contracts/test/TestERC20.sol solidity

Replace the openzeppelin import with this:

Expand Down
47 changes: 12 additions & 35 deletions l1-contracts/.solhint.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
{
"extends": "solhint:recommended",
"rules": {
"compiler-version": [
"error",
">=0.8.27"
],
"compiler-version": ["error", ">=0.8.27"],
"no-inline-assembly": "off",
"gas-custom-errors": "off",
"func-visibility": [
Expand All @@ -14,12 +11,8 @@
}
],
"no-empty-blocks": "off",
"no-unused-vars": [
"error"
],
"state-visibility": [
"error"
],
"no-unused-vars": ["error"],
"state-visibility": ["error"],
"not-rely-on-time": "off",
"const-name-snakecase": [
"error",
Expand All @@ -39,29 +32,13 @@
"allowPrefix": true
}
],
"private-func-leading-underscore": [
"error"
],
"private-vars-no-leading-underscore": [
"error"
],
"func-param-name-leading-underscore": [
"error"
],
"func-param-name-mixedcase": [
"error"
],
"strict-override": [
"error"
],
"strict-import": [
"error"
],
"ordering": [
"error"
],
"comprehensive-interface": [
"error"
]
"private-func-leading-underscore": ["error"],
"private-vars-no-leading-underscore": ["error"],
"func-param-name-leading-underscore": ["error"],
"func-param-name-mixedcase": ["error"],
"strict-override": ["error"],
"strict-import": ["error"],
"ordering": ["error"],
"comprehensive-interface": ["error"]
}
}
}
146 changes: 146 additions & 0 deletions l1-contracts/src/core/ProofCommitmentEscrow.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2024 Aztec Labs.
pragma solidity >=0.8.27;

import {SafeERC20} from "@oz/token/ERC20/utils/SafeERC20.sol";
import {IERC20} from "@oz/token/ERC20/IERC20.sol";

import {IProofCommitmentEscrow} from "@aztec/core/interfaces/IProofCommitmentEscrow.sol";
import {Errors} from "@aztec/core/libraries/Errors.sol";
import {Constants} from "@aztec/core/libraries/ConstantsGen.sol";
import {Timestamp} from "@aztec/core/libraries/TimeMath.sol";

contract ProofCommitmentEscrow is IProofCommitmentEscrow {
using SafeERC20 for IERC20;

struct WithdrawRequest {
uint256 amount;
Timestamp executableAt;
}

address public immutable ROLLUP;
uint256 public constant WITHDRAW_DELAY =
Constants.ETHEREUM_SLOT_DURATION * Constants.AZTEC_EPOCH_DURATION * 3;
mapping(address => uint256) public deposits;
mapping(address => WithdrawRequest) public withdrawRequests;
IERC20 public immutable token;

modifier onlyRollup() {
require(msg.sender == ROLLUP, Errors.ProofCommitmentEscrow__NotOwner(msg.sender));
_;
}

constructor(IERC20 _token, address _owner) {
token = _token;
ROLLUP = _owner;
}

/**
* @notice Deposit tokens into the escrow
*
* @dev The caller must have approved the token transfer
*
* @param _amount The amount of tokens to deposit
*/
function deposit(uint256 _amount) external override {
token.safeTransferFrom(msg.sender, address(this), _amount);

deposits[msg.sender] += _amount;

emit Deposit(msg.sender, _amount);
}

/**
* @notice Start a withdrawal request
*
* @dev The caller must have sufficient balance
* The withdrawal request will be executable after a delay
* Subsequent calls to this function will overwrite the previous request
*
* @param _amount - The amount of tokens to withdraw
*/
function startWithdraw(uint256 _amount) external override {
require(
deposits[msg.sender] >= _amount,
Errors.ProofCommitmentEscrow__InsufficientBalance(deposits[msg.sender], _amount)
);

withdrawRequests[msg.sender] = WithdrawRequest({
amount: _amount,
executableAt: Timestamp.wrap(block.timestamp + WITHDRAW_DELAY)
});

emit StartWithdraw(msg.sender, _amount, withdrawRequests[msg.sender].executableAt);
}

/**
* @notice Execute a mature withdrawal request
*/
function executeWithdraw() external override {
WithdrawRequest memory request = withdrawRequests[msg.sender];
require(
request.executableAt <= Timestamp.wrap(block.timestamp),
Errors.ProofCommitmentEscrow__WithdrawRequestNotReady(block.timestamp, request.executableAt)
);

delete withdrawRequests[msg.sender];
deposits[msg.sender] -= request.amount;
token.safeTransfer(msg.sender, request.amount);

emit ExecuteWithdraw(msg.sender, request.amount);
}

/**
* @notice Stake an amount of previously deposited tokens
*
* @dev Only callable by the owner
* The prover must have sufficient balance
* The prover's balance will be reduced by the bond amount
*/
function stakeBond(address _prover, uint256 _amount) external override onlyRollup {
deposits[_prover] -= _amount;

emit StakeBond(_prover, _amount);
}

/**
* @notice Unstake the bonded tokens, returning them to the prover
*
* @dev Only callable by the owner
*/
function unstakeBond(address _prover, uint256 _amount) external override onlyRollup {
deposits[_prover] += _amount;

emit UnstakeBond(_prover, _amount);
}

/**
* @notice Get the minimum balance of a prover at a given timestamp.
*
* @dev Returns 0 if the timestamp is beyond the WITHDRAW_DELAY from the current block timestamp
*
* @param _timestamp The timestamp at which to check the balance
* @param _prover The address of the prover
*
* @return The balance of the prover at the given timestamp, compensating for withdrawal requests that have matured by that time
*/
function minBalanceAtTime(Timestamp _timestamp, address _prover)
external
view
override
returns (uint256)
{
// If the timestamp is beyond the WITHDRAW_DELAY, the minimum possible balance is 0;
// the prover could issue a withdraw request in this block for the full amount,
// and execute it exactly WITHDRAW_DELAY later.
if (_timestamp >= Timestamp.wrap(block.timestamp + WITHDRAW_DELAY)) {
return 0;
}

uint256 balance = deposits[_prover];
if (withdrawRequests[_prover].executableAt <= _timestamp) {
balance -= withdrawRequests[_prover].amount;
}
return balance;
}
}
28 changes: 21 additions & 7 deletions l1-contracts/src/core/Rollup.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2023 Aztec Labs.
// Copyright 2024 Aztec Labs.
pragma solidity >=0.8.27;

import {EIP712} from "@oz/utils/cryptography/EIP712.sol";
import {ECDSA} from "@oz/utils/cryptography/ECDSA.sol";

import {IProofCommitmentEscrow} from "@aztec/core/interfaces/IProofCommitmentEscrow.sol";
import {IInbox} from "@aztec/core/interfaces/messagebridge/IInbox.sol";
import {IOutbox} from "@aztec/core/interfaces/messagebridge/IOutbox.sol";
Expand All @@ -11,6 +14,7 @@ import {IVerifier} from "@aztec/core/interfaces/IVerifier.sol";

import {Constants} from "@aztec/core/libraries/ConstantsGen.sol";
import {DataStructures} from "@aztec/core/libraries/DataStructures.sol";
import {EpochProofQuoteLib} from "@aztec/core/libraries/EpochProofQuoteLib.sol";
import {Errors} from "@aztec/core/libraries/Errors.sol";
import {HeaderLib} from "@aztec/core/libraries/HeaderLib.sol";
import {TxsDecoder} from "@aztec/core/libraries/TxsDecoder.sol";
Expand All @@ -32,9 +36,8 @@ import {Timestamp, Slot, Epoch, SlotLib, EpochLib} from "@aztec/core/libraries/T
* @notice Rollup contract that is concerned about readability and velocity of development
* not giving a damn about gas costs.
*/
contract Rollup is Leonidas, IRollup, ITestRollup {
contract Rollup is EIP712("Aztec Rollup", "1"), Leonidas, IRollup, ITestRollup {
using SafeCast for uint256;

using SlotLib for Slot;
using EpochLib for Epoch;

Expand Down Expand Up @@ -105,6 +108,15 @@ contract Rollup is Leonidas, IRollup, ITestRollup {
setupEpoch();
}

function quoteToDigest(EpochProofQuoteLib.EpochProofQuote memory quote)
public
view
override(IRollup)
returns (bytes32)
{
return _hashTypedDataV4(EpochProofQuoteLib.hash(quote));
}

/**
* @notice Prune the pending chain up to the last proven block
*
Expand Down Expand Up @@ -169,7 +181,7 @@ contract Rollup is Leonidas, IRollup, ITestRollup {
bytes32[] memory _txHashes,
SignatureLib.Signature[] memory _signatures,
bytes calldata _body,
DataStructures.SignedEpochProofQuote calldata _quote
EpochProofQuoteLib.SignedEpochProofQuote calldata _quote
) external override(IRollup) {
propose(_header, _archive, _blockHash, _txHashes, _signatures, _body);
claimEpochProofRight(_quote);
Expand Down Expand Up @@ -324,7 +336,7 @@ contract Rollup is Leonidas, IRollup, ITestRollup {
return TxsDecoder.decode(_body);
}

function claimEpochProofRight(DataStructures.SignedEpochProofQuote calldata _quote)
function claimEpochProofRight(EpochProofQuoteLib.SignedEpochProofQuote calldata _quote)
public
override(IRollup)
{
Expand All @@ -336,7 +348,7 @@ contract Rollup is Leonidas, IRollup, ITestRollup {
// We don't currently unstake,
// but we will as part of https://github.com/AztecProtocol/aztec-packages/issues/8652.
// Blocked on submitting epoch proofs to this contract.
PROOF_COMMITMENT_ESCROW.stakeBond(_quote.quote.bondAmount, _quote.quote.prover);
PROOF_COMMITMENT_ESCROW.stakeBond(_quote.quote.prover, _quote.quote.bondAmount);

proofClaim = DataStructures.EpochProofClaim({
epochToProve: epochToProve,
Expand Down Expand Up @@ -559,11 +571,13 @@ contract Rollup is Leonidas, IRollup, ITestRollup {
return publicInputs;
}

function validateEpochProofRightClaim(DataStructures.SignedEpochProofQuote calldata _quote)
function validateEpochProofRightClaim(EpochProofQuoteLib.SignedEpochProofQuote calldata _quote)
public
view
override(IRollup)
{
SignatureLib.verify(_quote.signature, _quote.quote.prover, quoteToDigest(_quote.quote));

Slot currentSlot = getCurrentSlot();
address currentProposer = getCurrentProposer();
Epoch epochToProve = getEpochToProve();
Expand Down
16 changes: 13 additions & 3 deletions l1-contracts/src/core/interfaces/IProofCommitmentEscrow.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,19 @@
// Copyright 2024 Aztec Labs.
pragma solidity >=0.8.27;

import {Timestamp} from "@aztec/core/libraries/TimeMath.sol";

interface IProofCommitmentEscrow {
event Deposit(address indexed depositor, uint256 amount);
event StartWithdraw(address indexed withdrawer, uint256 amount, Timestamp executableAt);
event ExecuteWithdraw(address indexed withdrawer, uint256 amount);
event StakeBond(address indexed prover, uint256 amount);
event UnstakeBond(address indexed prover, uint256 amount);

function deposit(uint256 _amount) external;
function withdraw(uint256 _amount) external;
function stakeBond(uint256 _bondAmount, address _prover) external;
function unstakeBond(uint256 _bondAmount, address _prover) external;
function startWithdraw(uint256 _amount) external;
function executeWithdraw() external;
function stakeBond(address _prover, uint256 _amount) external;
function unstakeBond(address _prover, uint256 _amount) external;
function minBalanceAtTime(Timestamp _timestamp, address _prover) external view returns (uint256);
}
Loading

0 comments on commit d802d44

Please sign in to comment.