Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(token portal standard): Create a token portal standard #2351

Merged
merged 6 commits into from
Sep 19, 2023

Conversation

rahul-kothari
Copy link
Contributor

@rahul-kothari rahul-kothari commented Sep 17, 2023

Part of #2167 - creates the tokenPortal Standard + updates cross chain tests (and cross chain harness file)
Doc is TBD

  • moved address types to aztec-nr
  • Created Replace NonNativeToken everywhere + update token portal #2291 - where I will purge NonNativeToken
  • In a future PR, I will update uniswap portal too. For now I have skipped the uniswap test (to keep this PR small-ish) as it uses crosschainHarness which is integral to the other cross-chain e2e tests
  • I have created a separate public/private flow for depositing to Portal (and therefore separate flow for cancelling such L1->L2 messages)

@rahul-kothari rahul-kothari changed the title Rk/token portal standard feat(token portal standard): Create a token portal standard Sep 17, 2023

// Consumes a L1->L2 message and calls the token contract to mint the appropriate amount publicly
#[aztec(public)]
fn deposit_public(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The naming with deposit and withdraw can make it quite hard to figure out the direction. Like, am I depositing into L1 from this contract, or am I depositing into L2 using a prior deposit.

Think it would make sense to make it a bit more clear that this is the second part of a deposit as well.

Withdraw might become withdrawToL1 or exitToL1 or the like, and deposits becoming a claim of funds?

) -> Field {
let storage = Storage::init(Context::public(&mut context));

let content_hash = get_mint_content_hash(amount, context.msg_sender(), canceller.address);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There should be two different content_hashes, one for public and one for private. Say you do:

bytes32 content = sha256ToField(
    abi.encodeWithSelector(
        "mint_public(bytes32,uint256,address)", 
        to, 
        amount, 
        canceller
);

And then a separate

bytes32 content = sha256ToField(
    abi.encodeWithSelector(
        "mint_private(uint256,bytes32,address)", 
        amount,
        secretHash, 
        canceller
);

With these two, you will be unambigious on what you are calling. Also, it is easier for you to let someone else perform the deposit action on L2 on your behalf without, in private use the to that was part of the content, and for public use the secretHash for the secretHash that is used when minting the asset.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that this require two flows on the L1 contract as well.

For withdrawals, you can get away with just having one content hash function, as you cannot consume it in private or public when on L1, so no need for both options.


// This way, user hashes their secret in private and only sends the hash in public
// meaning only user can `redeem_shield` at a later time with their secret.
#[aztec(public)]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be fine to add a comment in here that you are doing this as a public call because you need to read from public storage.

fn withdraw_private(
token: AztecAddress,
amount: Field,
recipient: EthereumAddress, // ethereum address to withdraw to
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good use of the types, makes it easier to spot if things make sense instead of Fields all over the place.

nonce: Field,
) -> Field {
// Burn tokens
Token::at(token.address).burn(&mut context, context.msg_sender(), amount, nonce);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could potentially be used to perform a re-entry before you are altering any of your local state. Should be moved to the bottom of the function to not allow it to influence much.

Note that, yes this is doing a public call, but it is not super clear from here, so better just follow checks-effects-interactions

hash_bytes[i + 68] = canceller_bytes[i];
}

// Function selector: 0xeeb73071 keccak256('mint(uint256,bytes32,address)')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remember to alter these with the changes higher up.

@@ -30,11 +30,12 @@ contract Token {
types::type_serialisation::field_serialisation::{
FieldSerialisationMethods, FIELD_SERIALISED_LEN,
},
types::address::{AztecAddress},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice 👍

}

impl EthereumAddress {
fn new(address: Field) -> Self {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be pedantic, we should probably constrain this to throw an error when using >160 bits. Can be constrained similarly to the SafeU120 just with more bits

@rahul-kothari rahul-kothari force-pushed the rk/token_portal_standard branch 4 times, most recently from 8ff0425 to 8bab903 Compare September 18, 2023 16:43
Copy link
Contributor

@LHerskind LHerskind left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some nits but looks pretty nice 👍

l1-contracts/test/portals/TokenPortal.sol Outdated Show resolved Hide resolved
l1-contracts/test/portals/TokenPortal.t.sol Show resolved Hide resolved
l1-contracts/test/portals/TokenPortal.t.sol Show resolved Hide resolved
l1-contracts/test/portals/TokenPortal.t.sol Outdated Show resolved Hide resolved
yarn-project/aztec-nr/aztec/src/types/address.nr Outdated Show resolved Hide resolved
l1-contracts/test/portals/TokenPortal.sol Outdated Show resolved Hide resolved
l1-contracts/test/portals/TokenPortal.sol Outdated Show resolved Hide resolved
#[aztec(private)]
fn exit_to_l1_private(
recipient: EthereumAddress, // ethereum address to withdraw to
token: AztecAddress,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The token here is only really used for validation in here while the rest are passed into the hash. So I would prefer that we had that closer to the end, such that the tree values put into the hash are in a row, but practically don't matter. Should probably get a style-guide going for this kind of thing.

Copy link
Contributor

@LHerskind LHerskind left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm ok with this as is. Had a minor comment on style, but probably better for us to do a style guide for that as well 🤷

@rahul-kothari rahul-kothari merged commit 426a3ea into master Sep 19, 2023
2 checks passed
@rahul-kothari rahul-kothari deleted the rk/token_portal_standard branch September 19, 2023 14:17
PhilWindle pushed a commit that referenced this pull request Sep 20, 2023
🤖 I have created a release *beep* *boop*
---


<details><summary>aztec-packages: 0.7.10</summary>

##
[0.7.10](aztec-packages-v0.7.9...aztec-packages-v0.7.10)
(2023-09-20)


### Features

* Aztec-cli unbox "really empty box"
([#2388](#2388))
([b57182d](b57182d))
* **docs:** Document noir macros
([#2016](#2016))
([1f1a17f](1f1a17f))
* **docs:** Include aztec rpc interface typedoc output in docs
([#2255](#2255))
([62c9e9b](62c9e9b))
* **token portal standard:** Create a token portal standard
([#2351](#2351))
([426a3ea](426a3ea))


### Bug Fixes

* **build:** Fix build system post deployment tests
([#2420](#2420))
([d509dc3](d509dc3))
* CLI encoding for arrays and structs
([#2407](#2407))
([85283bd](85283bd))
* Correct sandbox addresses in up-quick-start test
([#2412](#2412))
([974d859](974d859))
* **docs:** Revert include aztec rpc interface typedoc output in docs
([#2255](#2255))
([f852432](f852432))
* Handle falsy bigints in json-rpc
([#2403](#2403))
([d100650](d100650)),
closes
[#2402](#2402)
* **nargo_check.sh:** UNIX standard grep
([#2396](#2396))
([02e788a](02e788a))


### Miscellaneous

* **docs:** Note getter options
([#2411](#2411))
([8a95d8c](8a95d8c))
* Update docs url in config
([#2386](#2386))
([e44066d](e44066d))
</details>

<details><summary>barretenberg.js: 0.7.10</summary>

##
[0.7.10](barretenberg.js-v0.7.9...barretenberg.js-v0.7.10)
(2023-09-20)


### Miscellaneous

* **barretenberg.js:** Synchronize aztec-packages versions
</details>

<details><summary>barretenberg: 0.7.10</summary>

##
[0.7.10](barretenberg-v0.7.9...barretenberg-v0.7.10)
(2023-09-20)


### Miscellaneous

* **barretenberg:** Synchronize aztec-packages versions
</details>

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

2 participants