From a96894656f92b76ffe8d5f872772b8ab5f15dca9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anna=20Jab=C5=82onowska?= Date: Wed, 5 Jun 2024 15:53:34 +0200 Subject: [PATCH 01/13] Add from_bytes32 and to_bytes32 functions --- ethereum/circuits/lib/src/uint256.nr | 26 +++++++++++++++++++++++ ethereum/circuits/lib/src/uint256_test.nr | 14 ++++++++++++ 2 files changed, 40 insertions(+) diff --git a/ethereum/circuits/lib/src/uint256.nr b/ethereum/circuits/lib/src/uint256.nr index 1a2bb2155..1335452b0 100644 --- a/ethereum/circuits/lib/src/uint256.nr +++ b/ethereum/circuits/lib/src/uint256.nr @@ -1,4 +1,6 @@ use dep::std::ops::Add; +use crate::misc::types::Bytes32; +use crate::misc::arrays::memcpy_up_to_length; global uint128_overflow_value = 340282366920938463463374607431768211456; // 2^128 @@ -19,6 +21,30 @@ impl U256 { fn one() -> Self { Self { high: U128::from_integer(0), low: U128::from_integer(1) } } + + fn from_bytes32(bytes: Bytes32) -> Self { + let mut high_bytes = [0; 16]; + memcpy_up_to_length(&mut high_bytes, bytes, 16, 16); + let high = U128::from_le_bytes(high_bytes); + + let mut low_bytes = [0; 16]; + memcpy_up_to_length(&mut low_bytes, bytes, 0, 16); + let low = U128::from_le_bytes(low_bytes); + + U256::new(high, low) + } + + fn to_bytes32(self) -> Bytes32 { + let mut bytes = [0; 32]; + memcpy_up_to_length(&mut bytes, self.low.to_le_bytes(), 0, 16); + + let high_bytes = self.high.to_le_bytes(); + for i in 0..16 { + bytes[i + 16] = high_bytes[i]; + } + + bytes + } } impl Eq for U256 { diff --git a/ethereum/circuits/lib/src/uint256_test.nr b/ethereum/circuits/lib/src/uint256_test.nr index 175ff768a..ef4798082 100644 --- a/ethereum/circuits/lib/src/uint256_test.nr +++ b/ethereum/circuits/lib/src/uint256_test.nr @@ -30,6 +30,20 @@ fn zero_and_one() { assert_eq(one.low, U128::one()); } +#[test] +fn from_bytes32() { + let mut bytes = [0x00; 32]; + bytes[31] = 0x10; + assert_eq(U256::from_bytes32(bytes), big_number); +} + +#[test] +fn to_bytes32() { + let mut bytes = [0x00; 32]; + bytes[31] = 0x10; + assert_eq(big_number.to_bytes32(), bytes); +} + #[test] fn eq() { assert_eq(big_number, big_number); From e65aa8a304625991f57a2ca1efa4320a6994d1ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anna=20Jab=C5=82onowska?= Date: Wed, 5 Jun 2024 16:11:19 +0200 Subject: [PATCH 02/13] Implement from & into between Bytes32 and U256 --- ethereum/circuits/lib/src/uint256.nr | 12 ++++++++++++ ethereum/circuits/lib/src/uint256_test.nr | 4 ++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/ethereum/circuits/lib/src/uint256.nr b/ethereum/circuits/lib/src/uint256.nr index 1335452b0..c99e0656c 100644 --- a/ethereum/circuits/lib/src/uint256.nr +++ b/ethereum/circuits/lib/src/uint256.nr @@ -47,6 +47,18 @@ impl U256 { } } +impl From for U256 { + fn from(bytes: Bytes32) -> Self { + U256::from_bytes32(bytes) + } +} + +impl Into for U256 { + fn into(self) -> Bytes32 { + self.to_bytes32() + } +} + impl Eq for U256 { fn eq(self, other: U256) -> bool { (self.high == other.high) & (self.low == other.low) diff --git a/ethereum/circuits/lib/src/uint256_test.nr b/ethereum/circuits/lib/src/uint256_test.nr index ef4798082..b7b05d285 100644 --- a/ethereum/circuits/lib/src/uint256_test.nr +++ b/ethereum/circuits/lib/src/uint256_test.nr @@ -34,14 +34,14 @@ fn zero_and_one() { fn from_bytes32() { let mut bytes = [0x00; 32]; bytes[31] = 0x10; - assert_eq(U256::from_bytes32(bytes), big_number); + assert_eq(U256::from(bytes), big_number); } #[test] fn to_bytes32() { let mut bytes = [0x00; 32]; bytes[31] = 0x10; - assert_eq(big_number.to_bytes32(), bytes); + assert_eq(U256::into(big_number), bytes); } #[test] From cc030dbdeb81c0f48aa6b9140b0cb0f160da7112 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anna=20Jab=C5=82onowska?= Date: Wed, 5 Jun 2024 16:52:12 +0200 Subject: [PATCH 03/13] Migrate mapping to U256 --- vlayer/ethereum/circuits/lib/src/nft_list.nr | 6 ++--- vlayer/ethereum/circuits/lib/src/slot.nr | 7 ++--- vlayer/ethereum/circuits/lib/src/slot_test.nr | 26 ++++++++++++------- vlayer/ethereum/circuits/lib/src/token.nr | 10 ++++--- 4 files changed, 30 insertions(+), 19 deletions(-) diff --git a/vlayer/ethereum/circuits/lib/src/nft_list.nr b/vlayer/ethereum/circuits/lib/src/nft_list.nr index dcee23f57..6a2a15435 100644 --- a/vlayer/ethereum/circuits/lib/src/nft_list.nr +++ b/vlayer/ethereum/circuits/lib/src/nft_list.nr @@ -3,7 +3,7 @@ mod mainnet { use crate::chain_id; use crate::slot::{struct_slot, dynamic_array_with_precalculated_slot, mapping}; use dep::std::field::bytes32_to_field; - use dep::ethereum::misc::{types::Bytes32, bytes32::field_to_bytes32}; + use dep::ethereum::{misc::{types::Bytes32, bytes32::field_to_bytes32}, uint256::U256}; pub fn BORED_APE_YACHT_CLUB() -> ERC721Token { ERC721Token { @@ -32,10 +32,10 @@ mod mainnet { ], token_id_to_slot: |token_id| { let CRYPTO_PUNK_MAX_TOKEN_ID: u64 = 9999; - let CRYPTO_PUNK_TOKEN_OWNERS_INNER_ENTRIES_SLOT = field_to_bytes32(10); + let CRYPTO_PUNK_TOKEN_OWNERS_INNER_ENTRIES_SLOT = U256::from(field_to_bytes32(10)); assert(bytes32_to_field(token_id) as u64 <= CRYPTO_PUNK_MAX_TOKEN_ID, "Token ID is too high"); - mapping(CRYPTO_PUNK_TOKEN_OWNERS_INNER_ENTRIES_SLOT, token_id) + U256::into(mapping(CRYPTO_PUNK_TOKEN_OWNERS_INNER_ENTRIES_SLOT, token_id)) }, chain_id: chain_id::MAINNET } diff --git a/vlayer/ethereum/circuits/lib/src/slot.nr b/vlayer/ethereum/circuits/lib/src/slot.nr index 7d5358b97..cdd2cbd96 100644 --- a/vlayer/ethereum/circuits/lib/src/slot.nr +++ b/vlayer/ethereum/circuits/lib/src/slot.nr @@ -3,14 +3,15 @@ use dep::ethereum::misc::{ bytes::add_bigint }; use dep::std::hash::keccak256; +use dep::ethereum::uint256::U256; global STORAGE_KEY_HASH_INPUT_LENGTH = 64; -pub(crate) fn mapping(slot: Bytes32, key: Bytes32) -> Bytes32 { +pub(crate) fn mapping(slot: U256, key: Bytes32) -> U256 { let mut vector: BoundedVec = BoundedVec::new(); vector.extend_from_array(key); - vector.extend_from_array(slot); - keccak256(vector.storage(), STORAGE_KEY_HASH_INPUT_LENGTH) + vector.extend_from_array(U256::into(slot)); + U256::from(keccak256(vector.storage(), STORAGE_KEY_HASH_INPUT_LENGTH)) } pub(crate) fn dynamic_array(slot: Bytes32, size: Field, index: Field) -> Bytes32 { diff --git a/vlayer/ethereum/circuits/lib/src/slot_test.nr b/vlayer/ethereum/circuits/lib/src/slot_test.nr index 078cd93fc..ff352b754 100644 --- a/vlayer/ethereum/circuits/lib/src/slot_test.nr +++ b/vlayer/ethereum/circuits/lib/src/slot_test.nr @@ -1,7 +1,7 @@ mod mapping { use crate::slot::mapping; - use dep::ethereum::misc::bytes32::address_to_bytes32; - use dep::ethereum::misc::bytes32::field_to_bytes32; + use dep::ethereum::misc::bytes32::{address_to_bytes32, field_to_bytes32}; + use dep::ethereum::uint256::U256; #[test] fn adress_mapping() { @@ -10,9 +10,11 @@ mod mapping { 0x55, 0xfe, 0x00, 0x2a, 0xef, 0xf0, 0x2f, 0x77, 0x36, 0x4d, 0xe3, 0x39, 0xa1, 0x29, 0x29, 0x23, 0xa1, 0x58, 0x44, 0xb8 ]; assert_eq( - [ + U256::from( + [ 0x57, 0xd1, 0x8a, 0xf7, 0x93, 0xd7, 0x30, 0x0c, 0x4b, 0xa4, 0x6d, 0x19, 0x2e, 0xc7, 0xaa, 0x09, 0x50, 0x70, 0xdd, 0xe6, 0xc5, 0x2c, 0x68, 0x7c, 0x6d, 0x0d, 0x92, 0xfb, 0x85, 0x32, 0xb3, 0x05 - ], mapping(slot, address_to_bytes32(address)) + ] + ), mapping(U256::from(slot), address_to_bytes32(address)) ); } @@ -27,10 +29,12 @@ mod mapping { ]; assert_eq( - [ + U256::from( + [ 0x51, 0x5a, 0xd6, 0x04, 0x70, 0x94, 0xbd, 0x71, 0x0c, 0x10, 0x72, 0xcd, 0xa4, 0x7b, 0xc6, 0xcf, 0x43, 0x9c, 0x55, 0xdc, 0xf0, 0xb0, 0xd6, 0x0e, 0x8a, 0x9b, 0xe5, 0x57, 0xf1, 0x86, 0x81, 0x1c - ], mapping( - mapping(slot, address_to_bytes32(owner)), + ] + ), mapping( + mapping(U256::from(slot), address_to_bytes32(owner)), address_to_bytes32(spender) ) ); @@ -40,10 +44,12 @@ mod mapping { fn uint_mapping() { let slot = field_to_bytes32(10); let uint = 0; - let expected_slot = [ + let expected_slot = U256::from( + [ 0x13, 0xda, 0x86, 0x00, 0x8b, 0xa1, 0xc6, 0x92, 0x2d, 0xae, 0xe3, 0xe0, 0x7d, 0xb9, 0x53, 0x05, 0xef, 0x49, 0xeb, 0xce, 0xd9, 0xf5, 0x46, 0x7a, 0x0b, 0x86, 0x13, 0xfc, 0xc6, 0xb3, 0x43, 0xe3 - ]; - assert_eq(mapping(slot, field_to_bytes32(uint)), expected_slot); + ] + ); + assert_eq(mapping(U256::from(slot), field_to_bytes32(uint)), expected_slot); } } diff --git a/vlayer/ethereum/circuits/lib/src/token.nr b/vlayer/ethereum/circuits/lib/src/token.nr index 1ec167327..be9960374 100644 --- a/vlayer/ethereum/circuits/lib/src/token.nr +++ b/vlayer/ethereum/circuits/lib/src/token.nr @@ -4,6 +4,7 @@ use dep::ethereum::{ }; use dep::std::field::bytes32_to_field; use crate::slot::mapping; +use dep::ethereum::uint256::U256; global TOKEN_BALANCE_INDEX = 0; @@ -15,8 +16,11 @@ struct ERC20Token { } impl ERC20Token { - fn calculate_balance_storage_key(self, wallet_address: Address) -> Bytes32 { - mapping(self.balances_slot, address_to_bytes32(wallet_address)) + fn calculate_balance_storage_key(self, wallet_address: Address) -> U256 { + mapping( + U256::from(self.balances_slot), + address_to_bytes32(wallet_address) + ) } } @@ -27,7 +31,7 @@ trait ERC20 { impl ERC20 for ERC20Token { fn get_balance(self, wallet_address: Address, block_number: u64) -> U128 { let storage_key = self.calculate_balance_storage_key(wallet_address); - let account = get_account_with_storage(self.chain_id, block_number, self.address, storage_key); + let account = get_account_with_storage(self.chain_id, block_number, self.address, U256::into(storage_key)); let balance = account.values[TOKEN_BALANCE_INDEX]; U128::from_integer(bytes32_to_field(balance)) From 56f0e3ccf48d7c2f9f4f7749f4b406b4bac77864 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anna=20Jab=C5=82onowska?= Date: Wed, 5 Jun 2024 17:28:43 +0200 Subject: [PATCH 04/13] Migrate dynamic_array, dynamic_array_with_precalculated_slot & struct_slot --- vlayer/ethereum/circuits/lib/src/nft_list.nr | 14 ++--- vlayer/ethereum/circuits/lib/src/slot.nr | 12 ++--- vlayer/ethereum/circuits/lib/src/slot_test.nr | 53 +++++++++++-------- 3 files changed, 45 insertions(+), 34 deletions(-) diff --git a/vlayer/ethereum/circuits/lib/src/nft_list.nr b/vlayer/ethereum/circuits/lib/src/nft_list.nr index 6a2a15435..78868197f 100644 --- a/vlayer/ethereum/circuits/lib/src/nft_list.nr +++ b/vlayer/ethereum/circuits/lib/src/nft_list.nr @@ -12,14 +12,14 @@ mod mainnet { ], token_id_to_slot: |token_id| { let BORED_APE_YACHT_CLUB_MAX_TOKEN_ID: u64 = 9999; - let BORED_APE_YACHT_CLUB_TOKEN_OWNERS_INNER_ENTRIES_SLOT = [ + let BORED_APE_YACHT_CLUB_TOKEN_OWNERS_INNER_ENTRIES_SLOT = U256::from([ 0x40, 0x57, 0x87, 0xfa, 0x12, 0xa8, 0x23, 0xe0, 0xf2, 0xb7, 0x63, 0x1c, 0xc4, 0x1b, 0x3b, 0xa8, 0x82, 0x8b, 0x33, 0x21, 0xca, 0x81, 0x11, 0x11, 0xfa, 0x75, 0xcd, 0x3a, 0xa3, 0xbb, 0x5a, 0xce - ]; + ]); let VALUE_INDEX = 1; assert(bytes32_to_field(token_id) as u64 <= BORED_APE_YACHT_CLUB_MAX_TOKEN_ID, "Token ID is too high"); let owner_slot = dynamic_array_with_precalculated_slot(BORED_APE_YACHT_CLUB_TOKEN_OWNERS_INNER_ENTRIES_SLOT, 2, bytes32_to_field(token_id)); - struct_slot(owner_slot, VALUE_INDEX) + U256::into(struct_slot(owner_slot, VALUE_INDEX)) }, chain_id: chain_id::MAINNET } @@ -47,7 +47,7 @@ mod sepolia { use crate::chain_id; use crate::slot::{struct_slot, dynamic_array_with_precalculated_slot}; use dep::std::field::bytes32_to_field; - use dep::ethereum::misc::{types::Bytes32, bytes32::field_to_bytes32}; + use dep::ethereum::{misc::{types::Bytes32, bytes32::field_to_bytes32}, uint256::U256}; // free mint: https://sepolia.etherscan.io/address/0x80d97726548fedae6ad7cf8df4f2b514fd24afba#readContract fn FAKE_BORED_APE_YACHT_CLUB() -> ERC721Token { @@ -57,14 +57,14 @@ mod sepolia { ], token_id_to_slot: |token_id| { let BORED_APE_YACHT_CLUB_MAX_TOKEN_ID: u64 = 9999; - let BORED_APE_YACHT_CLUB_TOKEN_OWNERS_INNER_ENTRIES_SLOT = [ + let BORED_APE_YACHT_CLUB_TOKEN_OWNERS_INNER_ENTRIES_SLOT = U256::from([ 0x40, 0x57, 0x87, 0xfa, 0x12, 0xa8, 0x23, 0xe0, 0xf2, 0xb7, 0x63, 0x1c, 0xc4, 0x1b, 0x3b, 0xa8, 0x82, 0x8b, 0x33, 0x21, 0xca, 0x81, 0x11, 0x11, 0xfa, 0x75, 0xcd, 0x3a, 0xa3, 0xbb, 0x5a, 0xce - ]; + ]); let VALUE_INDEX = 1; assert(bytes32_to_field(token_id) as u64 <= BORED_APE_YACHT_CLUB_MAX_TOKEN_ID, "Token ID is too high"); let owner_slot = dynamic_array_with_precalculated_slot(BORED_APE_YACHT_CLUB_TOKEN_OWNERS_INNER_ENTRIES_SLOT, 2, bytes32_to_field(token_id)); - struct_slot(owner_slot, VALUE_INDEX) + U256::into(struct_slot(owner_slot, VALUE_INDEX)) }, chain_id: chain_id::SEPOLIA } diff --git a/vlayer/ethereum/circuits/lib/src/slot.nr b/vlayer/ethereum/circuits/lib/src/slot.nr index cdd2cbd96..31bdc6261 100644 --- a/vlayer/ethereum/circuits/lib/src/slot.nr +++ b/vlayer/ethereum/circuits/lib/src/slot.nr @@ -14,15 +14,15 @@ pub(crate) fn mapping(slot: U256, key: Bytes32) -> U256 { U256::from(keccak256(vector.storage(), STORAGE_KEY_HASH_INPUT_LENGTH)) } -pub(crate) fn dynamic_array(slot: Bytes32, size: Field, index: Field) -> Bytes32 { - let start = keccak256(slot, 32); +pub(crate) fn dynamic_array(slot: U256, size: Field, index: Field) -> U256 { + let start: U256 = U256::from(keccak256(U256::into(slot), 32)); dynamic_array_with_precalculated_slot(start, size, index) } -pub(crate) fn dynamic_array_with_precalculated_slot(slot: Bytes32, size: Field, index: Field) -> Bytes32 { - add_bigint(slot, field_to_bytes32(size * index)) +pub(crate) fn dynamic_array_with_precalculated_slot(slot: U256, size: Field, index: Field) -> U256 { + slot + U256::from(field_to_bytes32(size * index)) } -pub(crate) fn struct_slot(slot: Bytes32, offset: Field) -> Bytes32 { - add_bigint(slot, field_to_bytes32(offset)) +pub(crate) fn struct_slot(slot: U256, offset: Field) -> U256 { + slot + U256::from(field_to_bytes32(offset)) } diff --git a/vlayer/ethereum/circuits/lib/src/slot_test.nr b/vlayer/ethereum/circuits/lib/src/slot_test.nr index ff352b754..85918b511 100644 --- a/vlayer/ethereum/circuits/lib/src/slot_test.nr +++ b/vlayer/ethereum/circuits/lib/src/slot_test.nr @@ -56,28 +56,33 @@ mod mapping { mod dynamic_array { use crate::slot::dynamic_array; use dep::ethereum::misc::{bytes32_test::MAX_FIELD_VALUE, bytes32::field_to_bytes32}; + use dep::ethereum::uint256::U256; #[test] fn index_zero() { - let slot = field_to_bytes32(2); - let expected_slot = [ + let slot = U256::from(field_to_bytes32(2)); + let expected_slot = U256::from( + [ 0x40, 0x57, 0x87, 0xfa, 0x12, 0xa8, 0x23, 0xe0, 0xf2, 0xb7, 0x63, 0x1c, 0xc4, 0x1b, 0x3b, 0xa8, 0x82, 0x8b, 0x33, 0x21, 0xca, 0x81, 0x11, 0x11, 0xfa, 0x75, 0xcd, 0x3a, 0xa3, 0xbb, 0x5a, 0xce - ]; + ] + ); assert_eq(expected_slot, dynamic_array(slot, 2, 0)); } #[test] fn index_positive() { - let slot = field_to_bytes32(2); - let expected_slot = [ + let slot = U256::from(field_to_bytes32(2)); + let expected_slot = U256::from( + [ 0x40, 0x57, 0x87, 0xfa, 0x12, 0xa8, 0x23, 0xe0, 0xf2, 0xb7, 0x63, 0x1c, 0xc4, 0x1b, 0x3b, 0xa8, 0x82, 0x8b, 0x33, 0x21, 0xca, 0x81, 0x11, 0x11, 0xfa, 0x75, 0xcd, 0x3a, 0xa3, 0xbb, 0x5a, 0xdc - ]; + ] + ); assert_eq(expected_slot, dynamic_array(slot, 2, 7)); } - #[test(should_fail_with="Addition overflow")] + #[test(should_fail_with="attempt to add with overflow")] fn fail_overflow() { - let slot = field_to_bytes32(6); + let slot = U256::from(field_to_bytes32(6)); let _ = dynamic_array(slot, 2, MAX_FIELD_VALUE); } } @@ -85,32 +90,35 @@ mod dynamic_array { mod dynamic_array_with_precalculated_slot { use crate::slot::dynamic_array_with_precalculated_slot; use dep::ethereum::misc::{bytes32_test::MAX_FIELD_VALUE, bytes32::field_to_bytes32}; + use dep::ethereum::uint256::U256; #[test] fn index_zero() { - let slot = field_to_bytes32(2); + let slot = U256::from(field_to_bytes32(2)); assert_eq(slot, dynamic_array_with_precalculated_slot(slot, 2, 0)); } #[test] fn index_positive() { - let slot = field_to_bytes32(2); - let expected_slot = field_to_bytes32(2 + 2 * 7); + let slot = U256::from(field_to_bytes32(2)); + let expected_slot = U256::from(field_to_bytes32(2 + 2 * 7)); assert_eq(expected_slot, dynamic_array_with_precalculated_slot(slot, 2, 7)); } #[test] fn big_index() { - let slot = [0x09; 32]; - let expected_slot = [ + let slot = U256::from([0x09; 32]); + let expected_slot = U256::from( + [ 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x0b, 0x5d, 0x14, 0xed, 9 - ]; + ] + ); assert_eq(expected_slot, dynamic_array_with_precalculated_slot(slot, 10, 1_000_000_000)); } - #[test(should_fail_with="Addition overflow")] + #[test(should_fail_with="attempt to add with overflow")] fn fail_overflow() { - let slot = [0xfe; 32]; + let slot = U256::from([0xfe; 32]); let _ = dynamic_array_with_precalculated_slot(slot, 2, MAX_FIELD_VALUE); } } @@ -118,19 +126,22 @@ mod dynamic_array_with_precalculated_slot { mod struct_slot { use crate::slot::struct_slot; use dep::ethereum::misc::bytes32::field_to_bytes32; + use dep::ethereum::uint256::U256; #[test] fn success() { - let slot = field_to_bytes32(2); - let expected_slot = [ + let slot = U256::from(field_to_bytes32(2)); + let expected_slot = U256::from( + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2 - ]; + ] + ); assert_eq(expected_slot, struct_slot(slot, 256)); } - #[test(should_fail_with="Addition overflow")] + #[test(should_fail_with="attempt to add with overflow")] fn overflow() { - let slot = [0xff; 32]; + let slot = U256::from([0xff; 32]); let _ = struct_slot(slot, 256); } } From e55b7191d670739e0ccffb5e1b10f1f16d701c8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anna=20Jab=C5=82onowska?= Date: Thu, 6 Jun 2024 13:46:18 +0200 Subject: [PATCH 05/13] Implement from_field --- ethereum/circuits/lib/src/uint256.nr | 5 +++++ vlayer/ethereum/circuits/lib/src/nft_list.nr | 2 +- vlayer/ethereum/circuits/lib/src/slot.nr | 4 ++-- vlayer/ethereum/circuits/lib/src/slot_test.nr | 14 +++++++------- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/ethereum/circuits/lib/src/uint256.nr b/ethereum/circuits/lib/src/uint256.nr index c99e0656c..7c1bbac26 100644 --- a/ethereum/circuits/lib/src/uint256.nr +++ b/ethereum/circuits/lib/src/uint256.nr @@ -1,5 +1,6 @@ use dep::std::ops::Add; use crate::misc::types::Bytes32; +use crate::misc::bytes32::field_to_bytes32; use crate::misc::arrays::memcpy_up_to_length; global uint128_overflow_value = 340282366920938463463374607431768211456; // 2^128 @@ -34,6 +35,10 @@ impl U256 { U256::new(high, low) } + fn from_field(field: Field) -> Self { + U256::from_bytes32(field_to_bytes32(field)) + } + fn to_bytes32(self) -> Bytes32 { let mut bytes = [0; 32]; memcpy_up_to_length(&mut bytes, self.low.to_le_bytes(), 0, 16); diff --git a/vlayer/ethereum/circuits/lib/src/nft_list.nr b/vlayer/ethereum/circuits/lib/src/nft_list.nr index 78868197f..f4b6f48b6 100644 --- a/vlayer/ethereum/circuits/lib/src/nft_list.nr +++ b/vlayer/ethereum/circuits/lib/src/nft_list.nr @@ -32,7 +32,7 @@ mod mainnet { ], token_id_to_slot: |token_id| { let CRYPTO_PUNK_MAX_TOKEN_ID: u64 = 9999; - let CRYPTO_PUNK_TOKEN_OWNERS_INNER_ENTRIES_SLOT = U256::from(field_to_bytes32(10)); + let CRYPTO_PUNK_TOKEN_OWNERS_INNER_ENTRIES_SLOT = U256::from_field(10); assert(bytes32_to_field(token_id) as u64 <= CRYPTO_PUNK_MAX_TOKEN_ID, "Token ID is too high"); U256::into(mapping(CRYPTO_PUNK_TOKEN_OWNERS_INNER_ENTRIES_SLOT, token_id)) diff --git a/vlayer/ethereum/circuits/lib/src/slot.nr b/vlayer/ethereum/circuits/lib/src/slot.nr index 31bdc6261..1b8cb1739 100644 --- a/vlayer/ethereum/circuits/lib/src/slot.nr +++ b/vlayer/ethereum/circuits/lib/src/slot.nr @@ -20,9 +20,9 @@ pub(crate) fn dynamic_array(slot: U256, size: Field, index: Field) -> U256 { } pub(crate) fn dynamic_array_with_precalculated_slot(slot: U256, size: Field, index: Field) -> U256 { - slot + U256::from(field_to_bytes32(size * index)) + slot + U256::from_field(size * index) } pub(crate) fn struct_slot(slot: U256, offset: Field) -> U256 { - slot + U256::from(field_to_bytes32(offset)) + slot + U256::from_field(offset) } diff --git a/vlayer/ethereum/circuits/lib/src/slot_test.nr b/vlayer/ethereum/circuits/lib/src/slot_test.nr index 85918b511..79ecc1196 100644 --- a/vlayer/ethereum/circuits/lib/src/slot_test.nr +++ b/vlayer/ethereum/circuits/lib/src/slot_test.nr @@ -60,7 +60,7 @@ mod dynamic_array { #[test] fn index_zero() { - let slot = U256::from(field_to_bytes32(2)); + let slot = U256::from_field(2); let expected_slot = U256::from( [ 0x40, 0x57, 0x87, 0xfa, 0x12, 0xa8, 0x23, 0xe0, 0xf2, 0xb7, 0x63, 0x1c, 0xc4, 0x1b, 0x3b, 0xa8, 0x82, 0x8b, 0x33, 0x21, 0xca, 0x81, 0x11, 0x11, 0xfa, 0x75, 0xcd, 0x3a, 0xa3, 0xbb, 0x5a, 0xce @@ -71,7 +71,7 @@ mod dynamic_array { #[test] fn index_positive() { - let slot = U256::from(field_to_bytes32(2)); + let slot = U256::from_field(2); let expected_slot = U256::from( [ 0x40, 0x57, 0x87, 0xfa, 0x12, 0xa8, 0x23, 0xe0, 0xf2, 0xb7, 0x63, 0x1c, 0xc4, 0x1b, 0x3b, 0xa8, 0x82, 0x8b, 0x33, 0x21, 0xca, 0x81, 0x11, 0x11, 0xfa, 0x75, 0xcd, 0x3a, 0xa3, 0xbb, 0x5a, 0xdc @@ -82,7 +82,7 @@ mod dynamic_array { #[test(should_fail_with="attempt to add with overflow")] fn fail_overflow() { - let slot = U256::from(field_to_bytes32(6)); + let slot = U256::from_field(6); let _ = dynamic_array(slot, 2, MAX_FIELD_VALUE); } } @@ -94,14 +94,14 @@ mod dynamic_array_with_precalculated_slot { #[test] fn index_zero() { - let slot = U256::from(field_to_bytes32(2)); + let slot = U256::from_field(2); assert_eq(slot, dynamic_array_with_precalculated_slot(slot, 2, 0)); } #[test] fn index_positive() { - let slot = U256::from(field_to_bytes32(2)); - let expected_slot = U256::from(field_to_bytes32(2 + 2 * 7)); + let slot = U256::from_field(2); + let expected_slot = U256::from_field(2 + 2 * 7); assert_eq(expected_slot, dynamic_array_with_precalculated_slot(slot, 2, 7)); } @@ -130,7 +130,7 @@ mod struct_slot { #[test] fn success() { - let slot = U256::from(field_to_bytes32(2)); + let slot = U256::from_field(2); let expected_slot = U256::from( [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2 From 312c1d40f89b2de5f206bf1a114277c15a816078 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anna=20Jab=C5=82onowska?= Date: Thu, 6 Jun 2024 14:14:56 +0200 Subject: [PATCH 06/13] Migrate ERC20Token's slots to U256 --- vlayer/ethereum/circuits/lib/src/token.nr | 9 ++-- .../circuits/lib/src/token_int_test.nr | 9 ++-- .../ethereum/circuits/lib/src/token_list.nr | 50 ++++++++++--------- 3 files changed, 32 insertions(+), 36 deletions(-) diff --git a/vlayer/ethereum/circuits/lib/src/token.nr b/vlayer/ethereum/circuits/lib/src/token.nr index be9960374..ced531e62 100644 --- a/vlayer/ethereum/circuits/lib/src/token.nr +++ b/vlayer/ethereum/circuits/lib/src/token.nr @@ -10,17 +10,14 @@ global TOKEN_BALANCE_INDEX = 0; struct ERC20Token { address: Address, - balances_slot: Bytes32, - allowances_slot: Bytes32, + balances_slot: U256, + allowances_slot: U256, chain_id: Field } impl ERC20Token { fn calculate_balance_storage_key(self, wallet_address: Address) -> U256 { - mapping( - U256::from(self.balances_slot), - address_to_bytes32(wallet_address) - ) + mapping(self.balances_slot, address_to_bytes32(wallet_address)) } } diff --git a/vlayer/ethereum/circuits/lib/src/token_int_test.nr b/vlayer/ethereum/circuits/lib/src/token_int_test.nr index 00a6d8ca7..402fc12b9 100644 --- a/vlayer/ethereum/circuits/lib/src/token_int_test.nr +++ b/vlayer/ethereum/circuits/lib/src/token_int_test.nr @@ -8,6 +8,7 @@ mod test_ERC20Token { paris::usdc_circle::state_proof::proof_input_serialized as state_proof_input_serialized, paris::usdc_circle::storage_proof::proofs_serialized }; + use dep::ethereum::uint256::U256; use crate::chain_id::MAINNET; #[test] @@ -19,12 +20,8 @@ mod test_ERC20Token { address: [ 0xa0, 0xb8, 0x69, 0x91, 0xc6, 0x21, 0x8b, 0x36, 0xc1, 0xd1, 0x9d, 0x4a, 0x2e, 0x9e, 0xb0, 0xce, 0x36, 0x06, 0xeb, 0x48 ], - balances_slot: [ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9 - ], - allowances_slot: [ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10 - ], + balances_slot: U256::from_field(9), + allowances_slot: U256::from_field(10), chain_id: MAINNET }; diff --git a/vlayer/ethereum/circuits/lib/src/token_list.nr b/vlayer/ethereum/circuits/lib/src/token_list.nr index 83d961808..43dae842a 100644 --- a/vlayer/ethereum/circuits/lib/src/token_list.nr +++ b/vlayer/ethereum/circuits/lib/src/token_list.nr @@ -1,81 +1,82 @@ mod mainnet { use crate::token::ERC20Token; use crate::chain_id; + use dep::ethereum::uint256::U256; global USDC = ERC20Token { address: [0xa0, 0xb8, 0x69, 0x91, 0xc6, 0x21, 0x8b, 0x36, 0xc1, 0xd1, 0x9d, 0x4a, 0x2e, 0x9e, 0xb0, 0xce, 0x36, 0x06, 0xeb, 0x48], - balances_slot: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9], - allowances_slot: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10], + balances_slot: U256::from_field(9), + allowances_slot: U256::from_field(10), chain_id: chain_id::MAINNET }; global TETHER_USD = ERC20Token { address: [0xda, 0xc1, 0x7f, 0x95, 0x8d, 0x2e, 0xe5, 0x23, 0xa2, 0x20, 0x62, 0x06, 0x99, 0x45, 0x97, 0xc1, 0x3d, 0x83, 0x1e, 0xc7], - balances_slot: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2], - allowances_slot: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5], + balances_slot: U256::from_field(2), + allowances_slot: U256::from_field(5), chain_id: chain_id::MAINNET }; global UNISWAP = ERC20Token { address: [0x1f, 0x98, 0x40, 0xa8, 0x5d, 0x5a, 0xf5, 0xbf, 0x1d, 0x17, 0x62, 0xf9, 0x25, 0xbd, 0xad, 0xdc, 0x42, 0x01, 0xf9, 0x84], - balances_slot: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4], - allowances_slot: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3], + balances_slot: U256::from_field(4), + allowances_slot: U256::from_field(3), chain_id: chain_id::MAINNET }; global WBTC = ERC20Token { address: [0x22, 0x60, 0xfa, 0xc5, 0xe5, 0x54, 0x2a, 0x77, 0x3a, 0xa4, 0x4f, 0xbc, 0xfe, 0xdf, 0x7c, 0x19, 0x3b, 0xc2, 0xc5, 0x99], - balances_slot: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - allowances_slot: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2], + balances_slot: U256::from_field(0), + allowances_slot: U256::from_field(2), chain_id: chain_id::MAINNET }; global EZETH = ERC20Token { address: [0xbf, 0x54, 0x95, 0xef, 0xe5, 0xdb, 0x9c, 0xe0, 0x0f, 0x80, 0x36, 0x4c, 0x8b, 0x42, 0x35, 0x67, 0xe5, 0x8d, 0x21, 0x10], - balances_slot: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33], - allowances_slot: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34], + balances_slot: U256::from_field(33), + allowances_slot: U256::from_field(34), chain_id: chain_id::MAINNET }; global WEETH = ERC20Token { address: [0xcd, 0x5f, 0xe2, 0x3c, 0x85, 0x82, 0x0f, 0x7b, 0x72, 0xd0, 0x92, 0x6f, 0xc9, 0xb0, 0x5b, 0x43, 0xe3, 0x59, 0xb7, 0xee], - balances_slot: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65], - allowances_slot: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66], + balances_slot: U256::from_field(65), + allowances_slot: U256::from_field(66), chain_id: chain_id::MAINNET }; global DAI = ERC20Token { address: [0x6b, 0x17, 0x54, 0x74, 0xe8, 0x90, 0x94, 0xc4, 0x4d, 0xa9, 0x8b, 0x95, 0x4e, 0xed, 0xea, 0xc4, 0x95, 0x27, 0x1d, 0x0f], - balances_slot: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2], - allowances_slot: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3], + balances_slot: U256::from_field(2), + allowances_slot: U256::from_field(3), chain_id: chain_id::MAINNET }; global WSTETH = ERC20Token { address: [0x7f, 0x39, 0xc5, 0x81, 0xf5, 0x95, 0xb5, 0x3c, 0x5c, 0xb1, 0x9b, 0xd0, 0xb3, 0xf8, 0xda, 0x6c, 0x93, 0x5e, 0x2c, 0xa0], - balances_slot: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - allowances_slot: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], + balances_slot: U256::from_field(0), + allowances_slot: U256::from_field(1), chain_id: chain_id::MAINNET }; global USDe = ERC20Token { address: [0x4c, 0x9e, 0xdd, 0x58, 0x52, 0xcd, 0x90, 0x5f, 0x08, 0x6c, 0x75, 0x9e, 0x83, 0x83, 0xe0, 0x9b, 0xff, 0x1e, 0x68, 0xb3], - balances_slot: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2], - allowances_slot: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3], + balances_slot: U256::from_field(2), + allowances_slot: U256::from_field(3), chain_id: chain_id::MAINNET }; global PEPE = ERC20Token { address: [0x69, 0x82, 0x50, 0x81, 0x45, 0x45, 0x4c, 0xe3, 0x25, 0xdd, 0xbe, 0x47, 0xa2, 0x5d, 0x4e, 0xc3, 0xd2, 0x31, 0x19, 0x33], - balances_slot: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], - allowances_slot: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2], + balances_slot: U256::from_field(1), + allowances_slot: U256::from_field(2), chain_id: chain_id::MAINNET }; global MKR = ERC20Token { address: [0x9f, 0x8f, 0x72, 0xaa, 0x93, 0x04, 0xc8, 0xb5, 0x93, 0xd5, 0x55, 0xf1, 0x2e, 0xf6, 0x58, 0x9c, 0xc3, 0xa5, 0x79, 0xa2], - balances_slot: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], - allowances_slot: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2], + balances_slot: U256::from_field(1), + allowances_slot: U256::from_field(2), chain_id: chain_id::MAINNET }; } @@ -83,12 +84,13 @@ mod mainnet { mod sepolia { use crate::token::ERC20Token; use crate::chain_id; + use dep::ethereum::uint256::U256; // free mint: https://sepolia.etherscan.io/token/0x4f657a53e27e83ee7d3df8452abfd57d658765d6 global FakePEPE = ERC20Token { address: [0x4f, 0x65, 0x7a, 0x53, 0xe2, 0x7e, 0x83, 0xee, 0x7d, 0x3d, 0xf8, 0x45, 0x2a, 0xbf, 0xd5, 0x7d, 0x65, 0x87, 0x65, 0xd6], - balances_slot: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], - allowances_slot: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2], + balances_slot: U256::from_field(1), + allowances_slot: U256::from_field(2), chain_id: chain_id::SEPOLIA }; } From 38962c95df234fc077f10e9f73f36914aafcd716 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anna=20Jab=C5=82onowska?= Date: Thu, 6 Jun 2024 14:15:56 +0200 Subject: [PATCH 07/13] Initialize slots in slot_test as U256 --- vlayer/ethereum/circuits/lib/src/slot_test.nr | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/vlayer/ethereum/circuits/lib/src/slot_test.nr b/vlayer/ethereum/circuits/lib/src/slot_test.nr index 79ecc1196..0dc338e51 100644 --- a/vlayer/ethereum/circuits/lib/src/slot_test.nr +++ b/vlayer/ethereum/circuits/lib/src/slot_test.nr @@ -5,7 +5,7 @@ mod mapping { #[test] fn adress_mapping() { - let slot = field_to_bytes32(9); + let slot = U256::from_field(9); let address = [ 0x55, 0xfe, 0x00, 0x2a, 0xef, 0xf0, 0x2f, 0x77, 0x36, 0x4d, 0xe3, 0x39, 0xa1, 0x29, 0x29, 0x23, 0xa1, 0x58, 0x44, 0xb8 ]; @@ -14,13 +14,13 @@ mod mapping { [ 0x57, 0xd1, 0x8a, 0xf7, 0x93, 0xd7, 0x30, 0x0c, 0x4b, 0xa4, 0x6d, 0x19, 0x2e, 0xc7, 0xaa, 0x09, 0x50, 0x70, 0xdd, 0xe6, 0xc5, 0x2c, 0x68, 0x7c, 0x6d, 0x0d, 0x92, 0xfb, 0x85, 0x32, 0xb3, 0x05 ] - ), mapping(U256::from(slot), address_to_bytes32(address)) + ), mapping(slot, address_to_bytes32(address)) ); } #[test] fn mapping_of_mapping() { - let slot = field_to_bytes32(1); + let slot = U256::from_field(1); let owner = [ 0x5d, 0x82, 0x72, 0x63, 0x05, 0x2a, 0x88, 0x64, 0x23, 0xdc, 0xb1, 0x75, 0xef, 0x9b, 0x74, 0x91, 0xcc, 0x92, 0xed, 0x24 ]; @@ -34,7 +34,7 @@ mod mapping { 0x51, 0x5a, 0xd6, 0x04, 0x70, 0x94, 0xbd, 0x71, 0x0c, 0x10, 0x72, 0xcd, 0xa4, 0x7b, 0xc6, 0xcf, 0x43, 0x9c, 0x55, 0xdc, 0xf0, 0xb0, 0xd6, 0x0e, 0x8a, 0x9b, 0xe5, 0x57, 0xf1, 0x86, 0x81, 0x1c ] ), mapping( - mapping(U256::from(slot), address_to_bytes32(owner)), + mapping(slot, address_to_bytes32(owner)), address_to_bytes32(spender) ) ); @@ -42,14 +42,14 @@ mod mapping { #[test] fn uint_mapping() { - let slot = field_to_bytes32(10); + let slot = U256::from_field(10); let uint = 0; let expected_slot = U256::from( [ 0x13, 0xda, 0x86, 0x00, 0x8b, 0xa1, 0xc6, 0x92, 0x2d, 0xae, 0xe3, 0xe0, 0x7d, 0xb9, 0x53, 0x05, 0xef, 0x49, 0xeb, 0xce, 0xd9, 0xf5, 0x46, 0x7a, 0x0b, 0x86, 0x13, 0xfc, 0xc6, 0xb3, 0x43, 0xe3 ] ); - assert_eq(mapping(U256::from(slot), field_to_bytes32(uint)), expected_slot); + assert_eq(mapping(slot, field_to_bytes32(uint)), expected_slot); } } From b9412e50453005084e66b3af77ecee6360a6b50d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anna=20Jab=C5=82onowska?= Date: Thu, 6 Jun 2024 14:28:03 +0200 Subject: [PATCH 08/13] Migrate ERC721Token to U256 --- vlayer/ethereum/circuits/lib/src/nft.nr | 7 ++++--- vlayer/ethereum/circuits/lib/src/nft_list.nr | 6 +++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/vlayer/ethereum/circuits/lib/src/nft.nr b/vlayer/ethereum/circuits/lib/src/nft.nr index 9b50b6de6..f0ec12d5c 100644 --- a/vlayer/ethereum/circuits/lib/src/nft.nr +++ b/vlayer/ethereum/circuits/lib/src/nft.nr @@ -1,11 +1,12 @@ use dep::ethereum::{ account_with_storage::get_account_with_storage, - misc::types::{Address, Bytes32, ADDRESS_LENGTH, BYTES32_LENGTH}, misc::arrays::subarray_inferred_len + misc::{types::{Address, Bytes32, ADDRESS_LENGTH, BYTES32_LENGTH}, arrays::subarray_inferred_len}, + uint256::U256 }; struct ERC721Token { address: Address, - token_id_to_slot: fn (Bytes32) -> Bytes32, + token_id_to_slot: fn (Bytes32) -> U256, chain_id: Field } @@ -16,7 +17,7 @@ trait ERC721 { impl ERC721 for ERC721Token { fn get_owner(self, token_id: Bytes32, block_number: u64) -> Address { let storage_key = (self.token_id_to_slot)(token_id); - let account = get_account_with_storage(self.chain_id, block_number, self.address, storage_key); + let account = get_account_with_storage(self.chain_id, block_number, self.address, U256::into(storage_key)); subarray_inferred_len(account.values[0], BYTES32_LENGTH - ADDRESS_LENGTH) } } diff --git a/vlayer/ethereum/circuits/lib/src/nft_list.nr b/vlayer/ethereum/circuits/lib/src/nft_list.nr index f4b6f48b6..9f5540580 100644 --- a/vlayer/ethereum/circuits/lib/src/nft_list.nr +++ b/vlayer/ethereum/circuits/lib/src/nft_list.nr @@ -19,7 +19,7 @@ mod mainnet { assert(bytes32_to_field(token_id) as u64 <= BORED_APE_YACHT_CLUB_MAX_TOKEN_ID, "Token ID is too high"); let owner_slot = dynamic_array_with_precalculated_slot(BORED_APE_YACHT_CLUB_TOKEN_OWNERS_INNER_ENTRIES_SLOT, 2, bytes32_to_field(token_id)); - U256::into(struct_slot(owner_slot, VALUE_INDEX)) + struct_slot(owner_slot, VALUE_INDEX) }, chain_id: chain_id::MAINNET } @@ -35,7 +35,7 @@ mod mainnet { let CRYPTO_PUNK_TOKEN_OWNERS_INNER_ENTRIES_SLOT = U256::from_field(10); assert(bytes32_to_field(token_id) as u64 <= CRYPTO_PUNK_MAX_TOKEN_ID, "Token ID is too high"); - U256::into(mapping(CRYPTO_PUNK_TOKEN_OWNERS_INNER_ENTRIES_SLOT, token_id)) + mapping(CRYPTO_PUNK_TOKEN_OWNERS_INNER_ENTRIES_SLOT, token_id) }, chain_id: chain_id::MAINNET } @@ -64,7 +64,7 @@ mod sepolia { assert(bytes32_to_field(token_id) as u64 <= BORED_APE_YACHT_CLUB_MAX_TOKEN_ID, "Token ID is too high"); let owner_slot = dynamic_array_with_precalculated_slot(BORED_APE_YACHT_CLUB_TOKEN_OWNERS_INNER_ENTRIES_SLOT, 2, bytes32_to_field(token_id)); - U256::into(struct_slot(owner_slot, VALUE_INDEX)) + struct_slot(owner_slot, VALUE_INDEX) }, chain_id: chain_id::SEPOLIA } From 13d5e932889d5f09c45a401cd7cf940b8a91340e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anna=20Jab=C5=82onowska?= Date: Fri, 7 Jun 2024 10:36:56 +0200 Subject: [PATCH 09/13] Inline from_bytes32 & into_bytes32 --- ethereum/circuits/lib/src/uint256.nr | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/ethereum/circuits/lib/src/uint256.nr b/ethereum/circuits/lib/src/uint256.nr index 7c1bbac26..b9c030bbb 100644 --- a/ethereum/circuits/lib/src/uint256.nr +++ b/ethereum/circuits/lib/src/uint256.nr @@ -23,7 +23,13 @@ impl U256 { Self { high: U128::from_integer(0), low: U128::from_integer(1) } } - fn from_bytes32(bytes: Bytes32) -> Self { + fn from_field(field: Field) -> Self { + U256::from(field_to_bytes32(field)) + } +} + +impl From for U256 { + fn from(bytes: Bytes32) -> Self { let mut high_bytes = [0; 16]; memcpy_up_to_length(&mut high_bytes, bytes, 16, 16); let high = U128::from_le_bytes(high_bytes); @@ -34,12 +40,10 @@ impl U256 { U256::new(high, low) } +} - fn from_field(field: Field) -> Self { - U256::from_bytes32(field_to_bytes32(field)) - } - - fn to_bytes32(self) -> Bytes32 { +impl Into for U256 { + fn into(self) -> Bytes32 { let mut bytes = [0; 32]; memcpy_up_to_length(&mut bytes, self.low.to_le_bytes(), 0, 16); @@ -52,18 +56,6 @@ impl U256 { } } -impl From for U256 { - fn from(bytes: Bytes32) -> Self { - U256::from_bytes32(bytes) - } -} - -impl Into for U256 { - fn into(self) -> Bytes32 { - self.to_bytes32() - } -} - impl Eq for U256 { fn eq(self, other: U256) -> bool { (self.high == other.high) & (self.low == other.low) From 91a2d781b1b7f066c5495c5e5683439573810489 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anna=20Jab=C5=82onowska?= Date: Fri, 7 Jun 2024 10:37:13 +0200 Subject: [PATCH 10/13] Add tests for from trait --- ethereum/circuits/lib/src/uint256_test.nr | 97 ++++++++++++++++------- 1 file changed, 70 insertions(+), 27 deletions(-) diff --git a/ethereum/circuits/lib/src/uint256_test.nr b/ethereum/circuits/lib/src/uint256_test.nr index b7b05d285..c3f17ce2a 100644 --- a/ethereum/circuits/lib/src/uint256_test.nr +++ b/ethereum/circuits/lib/src/uint256_test.nr @@ -30,18 +30,52 @@ fn zero_and_one() { assert_eq(one.low, U128::one()); } -#[test] -fn from_bytes32() { - let mut bytes = [0x00; 32]; - bytes[31] = 0x10; - assert_eq(U256::from(bytes), big_number); -} - -#[test] -fn to_bytes32() { - let mut bytes = [0x00; 32]; - bytes[31] = 0x10; - assert_eq(U256::into(big_number), bytes); +mod trait_from { + use crate::uint256::U256; + global high = U128::from_integer(0x10000000000000000000000000000000); + global low = U128::zero(); + global limit = U128::from_integer(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); + + global big_number = U256 { high, low }; + global limit_u256 = U256 {high: limit, low:limit}; + + #[test] + fn from_bytes32_zero() { + let mut bytes = [0x00; 32]; + assert_eq(U256::from(bytes), U256::zero()); + } + + #[test] + fn from_bytes32() { + let mut bytes = [0x00; 32]; + bytes[31] = 0x10; + assert_eq(U256::from(bytes), big_number); + } + + #[test] + fn from_bytes32_limit() { + let mut bytes = [0xff; 32]; + assert_eq(U256::from(bytes), limit_u256); + } + + #[test] + fn into_bytes32_zero() { + let mut bytes = [0x00; 32]; + assert_eq(U256::into(U256::zero()), bytes); + } + + #[test] + fn into_bytes32() { + let mut bytes = [0x00; 32]; + bytes[31] = 0x10; + assert_eq(U256::into(big_number), bytes); + } + + #[test] + fn into_bytes32_limit() { + let mut bytes = [0xff; 32]; + assert_eq(U256::into(limit_u256), bytes); + } } #[test] @@ -61,23 +95,32 @@ fn not_eq() { assert(big_number != big_number3); } -#[test] -fn sum() { - let sum = big_number + big_number; +mod trait_add { + use crate::uint256::U256; + global high = U128::from_integer(0x10000000000000000000000000000000); + global low = U128::zero(); + global limit = U128::from_integer(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); - assert_eq(sum, U256 { high: U128::from_integer(0x20000000000000000000000000000000), low }); -} + global big_number = U256 { high, low }; + global limit_u256 = U256 {high: limit, low:limit}; -#[test] -fn sum_with_carry() { - let big_number = U256 { high, low: limit }; - let sum = big_number + U256::one(); + #[test] + fn sum() { + let sum = big_number + big_number; - assert_eq(sum, U256 { high: U128::from_integer(0x10000000000000000000000000000001), low }); -} + assert_eq(sum, U256 { high: U128::from_integer(0x20000000000000000000000000000000), low }); + } + + #[test] + fn sum_with_carry() { + let big_number = U256 { high, low: limit }; + let sum = big_number + U256::one(); + + assert_eq(sum, U256 { high: U128::from_integer(0x10000000000000000000000000000001), low }); + } -#[test(should_fail_with="attempt to add with overflow")] -fn sum_overflow() { - let limit_number = U256 { high: limit, low: limit }; - let _ = limit_number + U256::one(); + #[test(should_fail_with="attempt to add with overflow")] + fn sum_overflow() { + let _ = limit_u256 + U256::one(); + } } From 6bf0102a3c2584cfde53596ec7811177af26db7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anna=20Jab=C5=82onowska?= Date: Fri, 7 Jun 2024 11:22:48 +0200 Subject: [PATCH 11/13] Remove unnecessary muts --- ethereum/circuits/lib/src/uint256_test.nr | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ethereum/circuits/lib/src/uint256_test.nr b/ethereum/circuits/lib/src/uint256_test.nr index c3f17ce2a..6f413759c 100644 --- a/ethereum/circuits/lib/src/uint256_test.nr +++ b/ethereum/circuits/lib/src/uint256_test.nr @@ -41,7 +41,7 @@ mod trait_from { #[test] fn from_bytes32_zero() { - let mut bytes = [0x00; 32]; + let bytes = [0x00; 32]; assert_eq(U256::from(bytes), U256::zero()); } @@ -54,13 +54,13 @@ mod trait_from { #[test] fn from_bytes32_limit() { - let mut bytes = [0xff; 32]; + let bytes = [0xff; 32]; assert_eq(U256::from(bytes), limit_u256); } #[test] fn into_bytes32_zero() { - let mut bytes = [0x00; 32]; + let bytes = [0x00; 32]; assert_eq(U256::into(U256::zero()), bytes); } @@ -73,7 +73,7 @@ mod trait_from { #[test] fn into_bytes32_limit() { - let mut bytes = [0xff; 32]; + let bytes = [0xff; 32]; assert_eq(U256::into(limit_u256), bytes); } } From 655665e97cc374c5a2e00a11272de59b8038406d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anna=20Jab=C5=82onowska?= Date: Fri, 7 Jun 2024 11:28:01 +0200 Subject: [PATCH 12/13] Split from/into tests to two mods --- ethereum/circuits/lib/src/uint256_test.nr | 24 ++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/ethereum/circuits/lib/src/uint256_test.nr b/ethereum/circuits/lib/src/uint256_test.nr index 6f413759c..32c47e547 100644 --- a/ethereum/circuits/lib/src/uint256_test.nr +++ b/ethereum/circuits/lib/src/uint256_test.nr @@ -30,7 +30,7 @@ fn zero_and_one() { assert_eq(one.low, U128::one()); } -mod trait_from { +mod from_bytes32 { use crate::uint256::U256; global high = U128::from_integer(0x10000000000000000000000000000000); global low = U128::zero(); @@ -40,39 +40,49 @@ mod trait_from { global limit_u256 = U256 {high: limit, low:limit}; #[test] - fn from_bytes32_zero() { + fn zero() { let bytes = [0x00; 32]; assert_eq(U256::from(bytes), U256::zero()); } #[test] - fn from_bytes32() { + fn success() { let mut bytes = [0x00; 32]; bytes[31] = 0x10; assert_eq(U256::from(bytes), big_number); } #[test] - fn from_bytes32_limit() { + fn u256_limit() { let bytes = [0xff; 32]; assert_eq(U256::from(bytes), limit_u256); } +} + +mod into_bytes32 { + use crate::uint256::U256; + global high = U128::from_integer(0x10000000000000000000000000000000); + global low = U128::zero(); + global limit = U128::from_integer(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); + + global big_number = U256 { high, low }; + global limit_u256 = U256 {high: limit, low:limit}; #[test] - fn into_bytes32_zero() { + fn zero() { let bytes = [0x00; 32]; assert_eq(U256::into(U256::zero()), bytes); } #[test] - fn into_bytes32() { + fn success() { let mut bytes = [0x00; 32]; bytes[31] = 0x10; assert_eq(U256::into(big_number), bytes); } #[test] - fn into_bytes32_limit() { + fn u256_limit() { let bytes = [0xff; 32]; assert_eq(U256::into(limit_u256), bytes); } From a367ae4c87d6adaefcd564dc2c13530a2a0bdcaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anna=20Jab=C5=82onowska?= Date: Fri, 7 Jun 2024 11:40:30 +0200 Subject: [PATCH 13/13] Remove unnecessary imports --- vlayer/ethereum/circuits/lib/src/slot.nr | 5 +---- vlayer/ethereum/circuits/lib/src/token.nr | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/vlayer/ethereum/circuits/lib/src/slot.nr b/vlayer/ethereum/circuits/lib/src/slot.nr index 1b8cb1739..dc3079daa 100644 --- a/vlayer/ethereum/circuits/lib/src/slot.nr +++ b/vlayer/ethereum/circuits/lib/src/slot.nr @@ -1,7 +1,4 @@ -use dep::ethereum::misc::{ - types::{Address, Bytes32, ADDRESS_LENGTH, BYTES32_LENGTH}, bytes32::field_to_bytes32, - bytes::add_bigint -}; +use dep::ethereum::misc::types::Bytes32; use dep::std::hash::keccak256; use dep::ethereum::uint256::U256; diff --git a/vlayer/ethereum/circuits/lib/src/token.nr b/vlayer/ethereum/circuits/lib/src/token.nr index ced531e62..f6a648803 100644 --- a/vlayer/ethereum/circuits/lib/src/token.nr +++ b/vlayer/ethereum/circuits/lib/src/token.nr @@ -1,5 +1,5 @@ use dep::ethereum::{ - account_with_storage::get_account_with_storage, misc::types::{Address, Bytes32}, + account_with_storage::get_account_with_storage, misc::types::Address, misc::bytes32::address_to_bytes32 }; use dep::std::field::bytes32_to_field;