Skip to content

Commit

Permalink
Fix Caller Opcode (#664)
Browse files Browse the repository at this point in the history
<!--- Please provide a general summary of your changes in the title
above -->

Adding the `origin` arg to the `eth_call` and the `ExecutionContext`.
This solves the `from` (`msg.sender`) being 0 when in `@view` mode.

Time spent on this PR: 0.5

## Pull request type

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?

## What is the new behavior?

The `ExecutionContext` stores the ORIGIN of the calls, given as
argument.

## Other information

---------

Co-authored-by: Danilo Woo Hyung Kim <danilowoohyungkim@Danilos-MacBook-Pro-2.local>
Co-authored-by: Clément Walter <clement0walter@gmail.com>
  • Loading branch information
3 people authored Aug 25, 2023
1 parent ee6458a commit 95df46c
Show file tree
Hide file tree
Showing 35 changed files with 461 additions and 463 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ and this project adheres to

### Added

- fix: ORIGIN and CALLER work in both view and execute mode
- ci: add `CHANGELOG.md` and enforce it is edited for each PR on `main`
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ markers = [
"UniswapV2ERC20",
"UniswapV2Factory",
"Utils",
"Safe",
]

[tool.isort]
Expand Down
1 change: 1 addition & 0 deletions scripts/utils/kakarot.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ async def _wrapper(self, *args, **kwargs):
if abi["stateMutability"] == "view":
kakarot_contract = await _get_starknet_contract("kakarot")
result = await kakarot_contract.functions["eth_call"].call(
origin=int(EVM_ADDRESS, 16),
to=int(self.address, 16),
gas_limit=gas_limit,
gas_price=gas_price,
Expand Down
2 changes: 2 additions & 0 deletions src/kakarot/accounts/eoa/library.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,10 @@ namespace ExternallyOwnedAccount {
) = EthTransaction.decode([call_array].data_len, calldata + [call_array].data_offset);

let (_kakarot_address) = kakarot_address.read();
let (address) = evm_address.read();
let (return_data_len, return_data) = IKakarot.eth_send_transaction(
contract_address=_kakarot_address,
origin=address,
to=destination,
gas_limit=gas_limit,
gas_price=gas_price,
Expand Down
19 changes: 19 additions & 0 deletions src/kakarot/execution_context.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ namespace ExecutionContext {
dw 0; // gas_price
dw 0; // starknet_contract_address
dw 0; // evm_contract_address
dw 0; // origin
dw 0; // calling_context
dw 0; // sub_context
dw 0; // destroy_contracts_len
Expand All @@ -76,6 +77,7 @@ namespace ExecutionContext {
// @param call_context The call_context (see model.CallContext) to be executed.
// @param starknet_contract_address The context starknet address.
// @param evm_contract_address The context corresponding evm address.
// @param origin The caller EVM address
// @param gas_limit The available gas for the ExecutionContext.
// @param gas_price The price per unit of gas.
// @param calling_context A reference to the context of the calling contract. This context stores the return data produced by the called contract in its memory.
Expand All @@ -92,6 +94,7 @@ namespace ExecutionContext {
call_context: model.CallContext*,
starknet_contract_address: felt,
evm_contract_address: felt,
origin: felt,
gas_limit: felt,
gas_price: felt,
calling_context: model.ExecutionContext*,
Expand Down Expand Up @@ -125,6 +128,7 @@ namespace ExecutionContext {
gas_price=gas_price,
starknet_contract_address=starknet_contract_address,
evm_contract_address=evm_contract_address,
origin=origin,
calling_context=calling_context,
sub_context=sub_context,
destroy_contracts_len=0,
Expand Down Expand Up @@ -222,6 +226,7 @@ namespace ExecutionContext {
gas_price=self.gas_price,
starknet_contract_address=self.starknet_contract_address,
evm_contract_address=self.evm_contract_address,
origin=self.origin,
calling_context=self.calling_context,
sub_context=self.sub_context,
destroy_contracts_len=self.destroy_contracts_len,
Expand Down Expand Up @@ -267,6 +272,7 @@ namespace ExecutionContext {
gas_price=self.gas_price,
starknet_contract_address=self.starknet_contract_address,
evm_contract_address=self.evm_contract_address,
origin=self.origin,
calling_context=self.calling_context,
sub_context=self.sub_context,
destroy_contracts_len=self.destroy_contracts_len,
Expand Down Expand Up @@ -458,6 +464,7 @@ namespace ExecutionContext {
gas_price=self.gas_price,
starknet_contract_address=self.starknet_contract_address,
evm_contract_address=self.evm_contract_address,
origin=self.origin,
calling_context=self.calling_context,
sub_context=self.sub_context,
destroy_contracts_len=self.destroy_contracts_len,
Expand Down Expand Up @@ -493,6 +500,7 @@ namespace ExecutionContext {
gas_price=self.gas_price,
starknet_contract_address=self.starknet_contract_address,
evm_contract_address=self.evm_contract_address,
origin=self.origin,
calling_context=self.calling_context,
sub_context=self.sub_context,
destroy_contracts_len=self.destroy_contracts_len,
Expand Down Expand Up @@ -534,6 +542,7 @@ namespace ExecutionContext {
gas_price=self.gas_price,
starknet_contract_address=self.starknet_contract_address,
evm_contract_address=self.evm_contract_address,
origin=self.origin,
calling_context=self.calling_context,
sub_context=self.sub_context,
destroy_contracts_len=self.destroy_contracts_len,
Expand Down Expand Up @@ -569,6 +578,7 @@ namespace ExecutionContext {
gas_price=self.gas_price,
starknet_contract_address=self.starknet_contract_address,
evm_contract_address=self.evm_contract_address,
origin=self.origin,
calling_context=self.calling_context,
sub_context=self.sub_context,
destroy_contracts_len=self.destroy_contracts_len,
Expand Down Expand Up @@ -604,6 +614,7 @@ namespace ExecutionContext {
gas_price=self.gas_price,
starknet_contract_address=self.starknet_contract_address,
evm_contract_address=self.evm_contract_address,
origin=self.origin,
calling_context=self.calling_context,
sub_context=self.sub_context,
destroy_contracts_len=self.destroy_contracts_len,
Expand Down Expand Up @@ -639,6 +650,7 @@ namespace ExecutionContext {
gas_price=self.gas_price,
starknet_contract_address=self.starknet_contract_address,
evm_contract_address=self.evm_contract_address,
origin=self.origin,
calling_context=self.calling_context,
sub_context=sub_context,
destroy_contracts_len=self.destroy_contracts_len,
Expand Down Expand Up @@ -675,6 +687,7 @@ namespace ExecutionContext {
gas_price=self.gas_price,
starknet_contract_address=starknet_contract_address,
evm_contract_address=evm_contract_address,
origin=self.origin,
calling_context=self.calling_context,
sub_context=self.sub_context,
destroy_contracts_len=self.destroy_contracts_len,
Expand Down Expand Up @@ -715,6 +728,7 @@ namespace ExecutionContext {
gas_price=self.gas_price,
starknet_contract_address=self.starknet_contract_address,
evm_contract_address=self.evm_contract_address,
origin=self.origin,
calling_context=self.calling_context,
sub_context=self.sub_context,
destroy_contracts_len=self.destroy_contracts_len + destroy_contracts_len,
Expand Down Expand Up @@ -757,6 +771,7 @@ namespace ExecutionContext {
gas_price=self.gas_price,
starknet_contract_address=self.starknet_contract_address,
evm_contract_address=self.evm_contract_address,
origin=self.origin,
calling_context=self.calling_context,
sub_context=self.sub_context,
destroy_contracts_len=self.destroy_contracts_len,
Expand Down Expand Up @@ -791,6 +806,7 @@ namespace ExecutionContext {
gas_price=self.gas_price,
starknet_contract_address=self.starknet_contract_address,
evm_contract_address=self.evm_contract_address,
origin=self.origin,
calling_context=self.calling_context,
sub_context=self.sub_context,
destroy_contracts_len=self.destroy_contracts_len,
Expand Down Expand Up @@ -826,6 +842,7 @@ namespace ExecutionContext {
gas_price=self.gas_price,
starknet_contract_address=self.starknet_contract_address,
evm_contract_address=self.evm_contract_address,
origin=self.origin,
calling_context=self.calling_context,
sub_context=self.sub_context,
destroy_contracts_len=self.destroy_contracts_len + 1,
Expand Down Expand Up @@ -862,6 +879,7 @@ namespace ExecutionContext {
gas_price=self.gas_price,
starknet_contract_address=self.starknet_contract_address,
evm_contract_address=self.evm_contract_address,
origin=self.origin,
calling_context=self.calling_context,
sub_context=self.sub_context,
destroy_contracts_len=self.destroy_contracts_len,
Expand Down Expand Up @@ -917,6 +935,7 @@ namespace ExecutionContext {
gas_price=self.gas_price,
starknet_contract_address=self.starknet_contract_address,
evm_contract_address=self.evm_contract_address,
origin=self.origin,
calling_context=self.calling_context,
sub_context=self.sub_context,
destroy_contracts_len=self.destroy_contracts_len,
Expand Down
15 changes: 4 additions & 11 deletions src/kakarot/instructions/environmental_information.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -125,11 +125,7 @@ namespace EnvironmentalInformation {
}(ctx: model.ExecutionContext*) -> model.ExecutionContext* {
alloc_locals;

// Get the transaction info which contains the starknet origin address
let (tx_info) = get_tx_info();
// Get the EVM address from Starknet address
let (evm_contract_address) = IAccount.get_evm_address(tx_info.account_contract_address);
let origin_address = Helpers.to_uint256(evm_contract_address);
let origin_address = Helpers.to_uint256(ctx.origin);

// Update Context stack
let stack: model.Stack* = Stack.push(self=ctx.stack, element=origin_address);
Expand All @@ -155,13 +151,10 @@ namespace EnvironmentalInformation {
bitwise_ptr: BitwiseBuiltin*,
}(ctx: model.ExecutionContext*) -> model.ExecutionContext* {
alloc_locals;
// Get caller address.
let (current_address) = get_caller_address();
let (current_evm_address) = IAccount.get_evm_address(current_address);
let is_root = ExecutionContext.is_root(ctx);
let evm_address = (1 - is_root) * ctx.calling_context.evm_contract_address + is_root *
current_evm_address;
let evm_address_uint256 = Helpers.to_uint256(evm_address);
let caller = (1 - is_root) * ctx.calling_context.evm_contract_address + is_root *
ctx.origin;
let evm_address_uint256 = Helpers.to_uint256(caller);
let stack: model.Stack* = Stack.push(self=ctx.stack, element=evm_address_uint256);

// Update the execution context.
Expand Down
4 changes: 4 additions & 0 deletions src/kakarot/instructions/system_operations.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -524,6 +524,7 @@ namespace CallHelper {
call_context=call_context,
starknet_contract_address=starknet_contract_address,
evm_contract_address=call_args.address,
origin=calling_ctx.origin,
gas_limit=call_args.gas,
gas_price=calling_ctx.gas_price,
calling_context=calling_ctx,
Expand Down Expand Up @@ -842,6 +843,7 @@ namespace CreateHelper {
gas_price=0,
starknet_contract_address=starknet_contract_address,
evm_contract_address=evm_contract_address,
origin=ctx.origin,
calling_context=ctx,
sub_context=empty_context,
destroy_contracts_len=0,
Expand Down Expand Up @@ -886,6 +888,7 @@ namespace CreateHelper {
gas_price=0,
starknet_contract_address=starknet_contract_address,
evm_contract_address=evm_contract_address,
origin=ctx.origin,
calling_context=ctx,
sub_context=empty_context,
destroy_contracts_len=0,
Expand Down Expand Up @@ -1005,6 +1008,7 @@ namespace SelfDestructHelper {
gas_price=ctx.gas_price,
starknet_contract_address=ctx.starknet_contract_address,
evm_contract_address=ctx.evm_contract_address,
origin=ctx.origin,
calling_context=ctx.calling_context,
sub_context=ctx.sub_context,
destroy_contracts_len=0,
Expand Down
16 changes: 14 additions & 2 deletions src/kakarot/interfaces/interfaces.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,24 @@ namespace IKakarot {
}

func eth_call(
to: felt, gas_limit: felt, gas_price: felt, value: felt, data_len: felt, data: felt*
origin: felt,
to: felt,
gas_limit: felt,
gas_price: felt,
value: felt,
data_len: felt,
data: felt*,
) -> (return_data_len: felt, return_data: felt*) {
}

func eth_send_transaction(
to: felt, gas_limit: felt, gas_price: felt, value: felt, data_len: felt, data: felt*
origin: felt,
to: felt,
gas_limit: felt,
gas_price: felt,
value: felt,
data_len: felt,
data: felt*,
) -> (return_data_len: felt, return_data: felt*) {
}
}
36 changes: 25 additions & 11 deletions src/kakarot/kakarot.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ func deploy_externally_owned_account{
// @notice The eth_call function as described in the spec,
// see https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_call
// This is a view only function, meaning that it doesn't make any state change.
// @dev "from" parameter is taken from get_caller_address syscall
// @param origin The address the transaction is sent from.
// @param to The address the transaction is directed to.
// @param gas_limit Integer of the gas provided for the transaction execution
// @param gas_price Integer of the gas price used for each paid gas
Expand All @@ -128,17 +128,23 @@ func deploy_externally_owned_account{
@view
func eth_call{
syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, bitwise_ptr: BitwiseBuiltin*
}(to: felt, gas_limit: felt, gas_price: felt, value: felt, data_len: felt, data: felt*) -> (
return_data_len: felt, return_data: felt*
) {
return Kakarot.eth_call(to, gas_limit, gas_price, value, data_len, data);
}(
origin: felt,
to: felt,
gas_limit: felt,
gas_price: felt,
value: felt,
data_len: felt,
data: felt*,
) -> (return_data_len: felt, return_data: felt*) {
Kakarot.assert_view();
return Kakarot.eth_call(origin, to, gas_limit, gas_price, value, data_len, data);
}

// @notice The eth_send_transaction function as described in the spec,
// see https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_sendtransaction
// @dev "from" parameter is taken from get_caller_address syscall
// @dev "nonce" parameter is taken from the corresponding account contract
// @dev "from" parameter is taken from get_caller_address syscall
// @param origin The address the transaction is sent from.
// @param to The address the transaction is directed to.
// @param gas_limit Integer of the gas provided for the transaction execution
// @param gas_price Integer of the gas price used for each paid gas
Expand All @@ -150,8 +156,16 @@ func eth_call{
@external
func eth_send_transaction{
syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, bitwise_ptr: BitwiseBuiltin*
}(to: felt, gas_limit: felt, gas_price: felt, value: felt, data_len: felt, data: felt*) -> (
return_data_len: felt, return_data: felt*
) {
return Kakarot.eth_send_transaction(to, gas_limit, gas_price, value, data_len, data);
}(
origin: felt,
to: felt,
gas_limit: felt,
gas_price: felt,
value: felt,
data_len: felt,
data: felt*,
) -> (return_data_len: felt, return_data: felt*) {
Kakarot.assert_caller_is_kakarot_account();
Kakarot.assert_caller_is_origin(origin);
return Kakarot.eth_call(origin, to, gas_limit, gas_price, value, data_len, data);
}
Loading

0 comments on commit 95df46c

Please sign in to comment.