Skip to content

Commit

Permalink
Bugfix: create2 opcode should use deterministically derived evm contr…
Browse files Browse the repository at this point in the history
…act address (#443)

<!--- Please provide a general summary of your changes in the title
above -->

<!-- Give an estimate of the time you spent on this PR in terms of work
days. Did you spend 0.5 days on this PR or rather 2 days? -->

Time spent on this PR: 1.75 days

## Pull request type

<!-- Please try to limit your pull request to one type, submit multiple
pull requests if needed. -->

Please check the type of change your PR introduces:

- [X] Bugfix
- [ ] Feature
- [ ] Code style update (formatting, renaming)
- [ ] Refactoring (no functional changes, no api changes)
- [ ] Build related changes
- [ ] Documentation content changes
- [ ] Other (please describe):

## What is the current behavior?

The EVM address of a contract account is computed as follows:

```
        // Generate EVM_contract address from the new cairo contract
        // TODO: Use RLP to compute proper EVM address, see https://www.evm.codes/#f0
        let (_, low) = split_felt(starknet_contract_address);
        local evm_contract_address = 0xAbdE100700000000000000000000000000000000 + low;
```

<!-- Please describe the current behavior that you are modifying, or
link to a relevant issue. -->

Resolves #427 

also resolves #426 wrt create2 opcode

## What is the new behavior?

<!-- Please describe the behavior or changes that are being added by
this PR. -->
Create2's address is defined via
```
address = keccak256(0xff + sender_address + salt + keccak256(initialisation_code))[12:]
```
-
-
-

## Other information

There is a current temporary split in deploy code, where create2 logic
is handled separately from create. When both construct their address
deterministically, the temporary refactor will be removed.
<!-- Any other information that is important to this PR such as
screenshots of how the component looks before and after the change. -->

Co-authored-by: Clément Walter <[email protected]>
Co-authored-by: kakarot CI <[email protected]>
  • Loading branch information
3 people authored Jan 21, 2023
1 parent 90e0071 commit 5a07753
Show file tree
Hide file tree
Showing 14 changed files with 358 additions and 126 deletions.
15 changes: 5 additions & 10 deletions src/kakarot/accounts/contract/library.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,14 @@ namespace ContractAccount {
return ();
}

// @notice This function is a factory to handle salt and registration of EVM<>Starknet binding.
// @param salt: The salt for computing the corresponding EVM address
// @notice This function is a factory to handle evm contract address and registration of EVM<>Starknet binding in the case of create2.
// @param evm_contract_address: The computed evm contract address to map deployment to.
func deploy{
syscall_ptr: felt*,
pedersen_ptr: HashBuiltin*,
range_check_ptr,
bitwise_ptr: BitwiseBuiltin*,
}(salt: felt) -> (evm_contract_address: felt, starknet_contract_address: felt) {
}(evm_contract_address: felt) -> (starknet_contract_address: felt) {
alloc_locals;

// Prepare constructor data
Expand All @@ -88,17 +88,12 @@ namespace ContractAccount {
let (class_hash) = evm_contract_class_hash.read();
let (starknet_contract_address) = deploy_syscall(
class_hash=class_hash,
contract_address_salt=salt,
contract_address_salt=evm_contract_address,
constructor_calldata_size=2,
constructor_calldata=calldata,
deploy_from_zero=FALSE,
);

// Generate EVM_contract address from the new cairo contract
// TODO: Use RLP to compute proper EVM address, see https://www.evm.codes/#f0
let (_, low) = split_felt(starknet_contract_address);
local evm_contract_address = 0xAbdE100700000000000000000000000000000000 + low;

evm_contract_deployed.emit(
evm_contract_address=evm_contract_address,
starknet_contract_address=starknet_contract_address,
Expand All @@ -112,7 +107,7 @@ namespace ContractAccount {
evm_contract_address=evm_contract_address,
);

return (evm_contract_address, starknet_contract_address);
return (starknet_contract_address,);
}

// @notice Store the bytecode of the contract.
Expand Down
3 changes: 3 additions & 0 deletions src/kakarot/constants.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ func salt() -> (value: felt) {
namespace Constants {
// Define constants
// ADDRESSES
const ADDRESS_BYTES_LEN = 20;
// BLOCK
// CHAIN_ID = KKRT (0x4b4b5254) in ASCII
const CHAIN_ID = 1263227476;
Expand Down
7 changes: 4 additions & 3 deletions src/kakarot/instructions/environmental_information.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ from kakarot.execution_context import ExecutionContext
from kakarot.stack import Stack
from kakarot.memory import Memory
from kakarot.constants import native_token_address, registry_address
from kakarot.interfaces.interfaces import IEth, IRegistry, IEvmContract
from kakarot.interfaces.interfaces import IEth, IRegistry, IEvmContract, IAccount

// @title Environmental information opcodes.
// @notice This file contains the functions to execute for environmental information opcodes.
Expand Down Expand Up @@ -163,8 +163,9 @@ namespace EnvironmentalInformation {
alloc_locals;
// Get caller address.
let (current_address) = get_caller_address();
let caller_address = Helpers.to_uint256(current_address);
let stack: model.Stack* = Stack.push(self=ctx.stack, element=caller_address);
let (evm_address) = IAccount.get_eth_address(current_address);
let evm_address_uint256 = Helpers.to_uint256(evm_address);
let stack: model.Stack* = Stack.push(self=ctx.stack, element=evm_address_uint256);

// Update the execution context.
// Update context stack.
Expand Down
48 changes: 3 additions & 45 deletions src/kakarot/instructions/sha3.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,13 @@ namespace Sha3 {
);

let (local dest: felt*) = alloc();
bytes_to_byte8_little_endian(
Helpers.bytes_to_bytes8_little_endian(
bytes_len=length.low,
bytes=bigendian_data,
index=0,
size=length.low,
byte8=0,
byte8_shift=0,
bytes8=0,
bytes8_shift=0,
dest=dest,
dest_index=0,
);
Expand Down Expand Up @@ -91,46 +91,4 @@ namespace Sha3 {

return ctx;
}

// TODO: natspec
func bytes_to_byte8_little_endian{range_check_ptr}(
bytes_len: felt,
bytes: felt*,
index: felt,
size: felt,
byte8: felt,
byte8_shift: felt,
dest: felt*,
dest_index: felt,
) {
alloc_locals;
if (index == size) {
return ();
}

local current_byte;
let out_of_bound = is_le(a=bytes_len, b=index);
if (out_of_bound != FALSE) {
current_byte = 0;
} else {
assert current_byte = [bytes + index];
}

let (bit_shift) = pow(256, byte8_shift);

let _byte8 = byte8 + bit_shift * current_byte;

let byte8_full = is_le(a=7, b=byte8_shift);
let end_of_loop = is_le(size, index + 1);
let write_to_dest = is_le(1, byte8_full + end_of_loop);
if (write_to_dest != FALSE) {
assert dest[dest_index] = _byte8;
return bytes_to_byte8_little_endian(
bytes_len, bytes, index + 1, size, 0, 0, dest, dest_index + 1
);
}
return bytes_to_byte8_little_endian(
bytes_len, bytes, index + 1, size, _byte8, byte8_shift + 1, dest, dest_index
);
}
}
Loading

0 comments on commit 5a07753

Please sign in to comment.