Skip to content

Commit

Permalink
handle deposit batch
Browse files Browse the repository at this point in the history
  • Loading branch information
maciejka committed Jan 3, 2025
1 parent 95fe4a4 commit 1536d35
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 18 deletions.
65 changes: 50 additions & 15 deletions l2/src/bridge.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,15 @@ use starknet::ContractAddress;
// TODO: Add the correct type for L1Address
type L1Address = u256;

#[derive(Drop, Serde)]
struct Deposit {
recipient: ContractAddress,
amount: u256,
}

#[starknet::interface]
pub trait IBridge<TContractState> {
fn deposit(ref self: TContractState, recipient: ContractAddress, amount: u256);
fn deposit(ref self: TContractState, deposits: Span<Deposit>);
fn withdraw(ref self: TContractState, recipient: L1Address, amount: u256);
fn close_batch(ref self: TContractState);
}
Expand All @@ -18,13 +24,15 @@ pub mod Bridge {
use starknet::ContractAddress;
use starknet::get_caller_address;
use crate::utils::hash::{Digest, DigestTrait};
use crate::utils::merkle_tree::merkle_root;
use super::L1Address;
use super::Deposit;
use starknet::storage::{
StoragePointerReadAccess, StoragePointerWriteAccess, Vec, MutableVecTrait,
};
use crate::btc::{IBTCDispatcher, IBTCDispatcherTrait};
use crate::utils::{
double_sha256::{double_sha256_digests, double_sha256_word_array},
double_sha256::{double_sha256_parent, double_sha256_word_array},
word_array::{WordArray, WordArrayTrait},
};

Expand Down Expand Up @@ -58,8 +66,8 @@ pub mod Bridge {

#[derive(Drop, starknet::Event)]
struct DepositEvent {
recipient: ContractAddress,
amount: u256,
root: Digest,
total: u256,
}

#[derive(Drop, starknet::Event)]
Expand Down Expand Up @@ -95,11 +103,25 @@ pub mod Bridge {

#[abi(embed_v0)]
impl Bridge of super::IBridge<ContractState> {
fn deposit(ref self: ContractState, recipient: ContractAddress, amount: u256) {
fn deposit(ref self: ContractState, deposits: Span<Deposit>) {
self.ownable.assert_only_owner();
self.btc.read().mint(recipient, amount);

self.emit(DepositEvent { recipient, amount });
let mut deposits_ = deposits;
let mut leafs: Array<Digest> = array![];
while let Option::Some(Deposit { recipient, amount }) = deposits_.pop_front() {
leafs.append(HelpersTrait::double_sha256_deposit(*recipient, *amount));
};

let root = merkle_root(leafs.span());
let btc = self.btc.read();
let mut total = 0;
let mut deposits_ = deposits;
while let Option::Some(d) = deposits_.pop_front() {
btc.mint(*d.recipient, *d.amount);
total = total + *d.amount;
};

self.emit(DepositEvent { root, total });
}

fn withdraw(ref self: ContractState, recipient: L1Address, amount: u256) {
Expand All @@ -126,6 +148,19 @@ pub mod Bridge {

#[generate_trait]
pub impl HelpersImpl of HelpersTrait {
fn double_sha256_deposit(recipient: ContractAddress, amount: u256) -> Digest {
let mut b: WordArray = Default::default();

let recipient: felt252 = recipient.into();
let recipient: u256 = recipient.into();
let recipient: Digest = recipient.into();
b.append_span(recipient.value.span());

let amount: Digest = amount.into();
b.append_span(amount.value.span());

double_sha256_word_array(b)
}
fn double_sha256_withdrawal(recipient: L1Address, amount: u256) -> Digest {
let mut b: WordArray = Default::default();

Expand Down Expand Up @@ -186,7 +221,7 @@ pub mod Bridge {
let mut i = 0;

while size % 2 == 1 {
value = double_sha256_digests(@self.get_element(i), @value);
value = double_sha256_parent(@self.get_element(i), @value);
size = size / 2;
i += 1;
};
Expand All @@ -209,9 +244,9 @@ pub mod Bridge {

while height < Self::TREE_HEIGHT.into() {
if size % 2 == 1 {
root = double_sha256_digests(@self.get_element(height.into()), @root);
root = double_sha256_parent(@self.get_element(height.into()), @root);
} else {
root = double_sha256_digests(@root, @DigestTrait::new(*zero_hashes.at(height)));
root = double_sha256_parent(@root, @DigestTrait::new(*zero_hashes.at(height)));
}
size = size / 2;
height += 1;
Expand All @@ -225,7 +260,7 @@ pub mod Bridge {
#[cfg(test)]
mod merkle_tree_tests {
use crate::utils::hash::{Digest, DigestTrait};
use crate::utils::double_sha256::double_sha256_digests;
use crate::utils::double_sha256::double_sha256_parent;
use super::Bridge;
use super::Bridge::{InternalTrait, InternalImpl};

Expand All @@ -244,7 +279,7 @@ mod merkle_tree_tests {
let mut next_hashes: Array<Digest> = array![];
while let Option::Some(v) = hashes.multi_pop_front::<2>() {
let [a, b] = (*v).unbox();
next_hashes.append(double_sha256_digests(@a, @b));
next_hashes.append(double_sha256_parent(@a, @b));
};
hashes = next_hashes.span();
};
Expand All @@ -258,7 +293,7 @@ mod merkle_tree_tests {
fn print_zero_hashes() {
let mut previous: Digest = 0_u256.into();
for _ in 0..InternalImpl::TREE_HEIGHT {
previous = double_sha256_digests(@previous, @previous);
previous = double_sha256_parent(@previous, @previous);
}
}

Expand Down Expand Up @@ -322,7 +357,7 @@ mod bridge_tests {
};
use starknet::{ContractAddress, contract_address_const};
use crate::btc::{IBTCDispatcher, IBTCDispatcherTrait};
use super::{IBridgeDispatcher, IBridgeDispatcherTrait};
use super::{Deposit, IBridgeDispatcher, IBridgeDispatcherTrait};
use openzeppelin_access::ownable::interface::{IOwnableDispatcher, IOwnableDispatcherTrait};

fn fixture() -> (
Expand Down Expand Up @@ -372,7 +407,7 @@ mod bridge_tests {
let (admin_address, alice_address, bob_address, carol_address, btc, bridge) = fixture();

cheat_caller_address(bridge.contract_address, admin_address, CheatSpan::TargetCalls(1));
bridge.deposit(alice_address, 100);
bridge.deposit(array![Deposit { recipient: alice_address, amount: 100 }].span());

start_cheat_caller_address_global(alice_address);
btc.transfer(bob_address, 50);
Expand Down
1 change: 1 addition & 0 deletions l2/src/lib.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ mod btc;
mod utils {
pub mod bit_shifts;
pub mod double_sha256;
pub mod merkle_tree;
pub mod hash;
pub mod word_array;
#[cfg(target: 'test')]
Expand Down
6 changes: 3 additions & 3 deletions l2/src/utils/double_sha256.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use core::sha256::compute_sha256_u32_array;
use super::word_array::WordArray;

/// Calculates double sha256 digest of a concatenation of two hashes.
pub fn double_sha256_digests(a: @Digest, b: @Digest) -> Digest {
pub fn double_sha256_parent(a: @Digest, b: @Digest) -> Digest {
let mut input1: Array<u32> = array![];
input1.append_span(a.value.span());
input1.append_span(b.value.span());
Expand All @@ -30,7 +30,7 @@ pub fn double_sha256_word_array(words: WordArray) -> Digest {
#[cfg(test)]
mod tests {
use crate::utils::{hex::from_hex, hash::Digest, word_array::hex::words_from_hex};
use super::{double_sha256_word_array, double_sha256_digests};
use super::{double_sha256_word_array, double_sha256_parent};

#[test]
fn test_double_sha256_word_array() {
Expand All @@ -55,7 +55,7 @@ mod tests {
// hashlib.sha256(sha256(bytes.fromhex("00000001" * 8 + "00000002" *
// 8)).digest()).hexdigest()
assert_eq!(
double_sha256_digests(@Digest { value: [1; 8] }, @Digest { value: [2; 8] }).into(),
double_sha256_parent(@Digest { value: [1; 8] }, @Digest { value: [2; 8] }).into(),
from_hex("14a6e4a4caef969126944266724d11866b39b3390cee070b0aa4c9390cd77f47"),
)
}
Expand Down

0 comments on commit 1536d35

Please sign in to comment.