diff --git a/src/accounts/base.cairo b/src/accounts/base.cairo index 81938ff..88fab71 100644 --- a/src/accounts/base.cairo +++ b/src/accounts/base.cairo @@ -56,7 +56,7 @@ pub mod RosettaAccount { impl AccountImpl of super::IRosettaAccount { // Instead of Array we use Array since we pass different values to the // parameter - // It is EOA execution so multiple calls are not possible + // It is EOA execution so multiple calls are not possible right now. We will add Multicalls in a different way in beta // calls params can include raw signed tx or can include the abi parsing bit locations for calldata fn __execute__(self: @ContractState, call: RosettanetCall) -> Array> { let sender = get_caller_address(); @@ -69,9 +69,11 @@ pub mod RosettaAccount { let entrypoint = validate_target_function(call.target_function, call.calldata); // If its native transfer do not handle calldata let mut calldata = call.calldata; - calldata.pop_front(); // Remove first element, it is function selector + let _ = calldata.pop_front(); // Remove first element, it is function selector - let result: Span = call_contract_syscall(sn_target, entrypoint, calldata).unwrap(); + let address_updated_calldata = self.update_addresses(calldata, call.directives); // This function security concerns me + + let result: Span = call_contract_syscall(sn_target, entrypoint, address_updated_calldata).unwrap(); // self.nonce.write(self.nonce.read() + 1); // Problem here ??? array![result] } @@ -189,5 +191,26 @@ pub mod RosettaAccount { is_valid_eth_signature(hash, eth_address, rosettanet_signature) } + + // TODO: write tests + fn update_addresses(self: @ContractState, calldata: Span, directives: Span) -> Span { + assert(calldata.len() == directives.len(), 'R-AB-1 sanity fails'); + let mut updated_array = ArrayTrait::::new(); + let mut index = 0; + + while index < calldata.len() { + let current_directive: u8 = *directives.at(index); + if(current_directive == 2_u8) { + let eth_address: EthAddress = (*calldata.at(index)).try_into().unwrap(); + let sn_address = IRosettanetDispatcher{contract_address: self.registry.read()}.get_starknet_address(eth_address); + updated_array.append(sn_address.into()); + } else { + updated_array.append(*calldata.at(index)); + } + index +=1; + }; + + updated_array.span() + } } } diff --git a/src/accounts/utils.cairo b/src/accounts/utils.cairo index 14a697d..c578374 100644 --- a/src/accounts/utils.cairo +++ b/src/accounts/utils.cairo @@ -30,7 +30,7 @@ pub struct RosettanetCall { pub gas_limit: u64, pub value: u256, // To be used future pub calldata: Span, // Calldata len must be +1 directive len - pub directives: Span, // We use this directives to figure out u256 splitting happened in element in same index For ex if 3rd element of this array is true, it means 3rd elem is low, 4th elem is high of u256 + pub directives: Span, // 0 -> do nothing, 1 -> u256, 2-> address pub target_function: Span // Function name and types to used to calculate eth func signature } @@ -92,14 +92,14 @@ pub fn parse_transaction(call: RosettanetCall) -> Eip1559Transaction { } // Merges u256s coming from calldata according to directives -pub fn merge_u256s(calldata: Span, directives: Span) -> Span { +pub fn merge_u256s(calldata: Span, directives: Span) -> Span { assert(calldata.len() == directives.len(), 'R-AU-1 Sanity check fails'); let mut merged_array = ArrayTrait::::new(); let mut index = 0; while index < calldata.len() { let current_directive = *directives.at(index); - if(current_directive) { + if(current_directive == 1) { let element = u256 { low: (*calldata.at(index)).try_into().unwrap(), // We can assume it always fits u128 limit since u256s already splitted low highs high: (*calldata.at(index + 1)).try_into().unwrap() @@ -209,7 +209,7 @@ mod tests { #[test] fn test_parse_transaction_usual() { let calldata = array![0x23b872dd, 0x123123, 0x456456, 0x0, 0x666].span(); // transferFrom(0x123123,0x456456, u256 {0,0x666}) - let directives = array![false, false, true, false].span(); // Directive length must be -1 bcs first is selector + let directives = array![0, 0, 1, 0].span(); // Directive length must be -1 bcs first is selector let target_function = array![0x7472616E7366657246726F6D28616464726573732C616464726573732C, 0x75696E7432353629].span(); // transferFrom let call = RosettanetCall { @@ -376,7 +376,7 @@ mod tests { #[test] fn test_merge_one() { let data = array![0xFF, 0xAB].span(); - let directive = array![true, false].span(); + let directive = array![1, 0].span(); let merged = merge_u256s(data, directive); @@ -386,7 +386,7 @@ mod tests { #[test] fn test_merge_two() { let data = array![0xFF, 0xAB, 0x123123, 0x0].span(); - let directive = array![true, false, true, false].span(); + let directive = array![1, 0, 1, 0].span(); let merged = merge_u256s(data, directive); @@ -398,7 +398,7 @@ mod tests { #[should_panic(expected: 'R-AU-1 Sanity check fails')] fn test_merge_wrong_sanity() { let data = array![0xFF, 0xAB, 0x123123, 0x0].span(); - let directive = array![true, false, true, false, true].span(); + let directive = array![1, 0, 1, 0, 1].span(); let merged = merge_u256s(data, directive);