Skip to content
This repository has been archived by the owner on Jan 9, 2025. It is now read-only.

Commit

Permalink
Use DualVmToken for Coinbase (#1487)
Browse files Browse the repository at this point in the history
Resolves: #1486

<!-- Reviewable:start -->
- - -
This change is [<img src="https://reviewable.io/review_button.svg"
height="34" align="absmiddle"
alt="Reviewable"/>](https://reviewable.io/reviews/kkrt-labs/kakarot/1487)
<!-- Reviewable:end -->
  • Loading branch information
ClementWalter authored Oct 10, 2024
1 parent 521d141 commit f247bab
Show file tree
Hide file tree
Showing 15 changed files with 698 additions and 83 deletions.
2 changes: 1 addition & 1 deletion .trunk/trunk.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ lint:
- solidity_contracts/src/WETH/**/*.sol
- solidity_contracts/src/UniswapV2Router/**/*.sol
- solidity_contracts/src/Solmate/**/*.sol
- solidity_contracts/src/starknet/**/*.sol
- solidity_contracts/src/Starknet/**/*.sol
actions:
disabled:
- trunk-announce
Expand Down
6 changes: 4 additions & 2 deletions kakarot_scripts/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,8 @@ class ChainId(IntEnum):
NETWORK["chain_id"] = ChainId.chain_id

ETH_TOKEN_ADDRESS = 0x49D36570D4E46F48E99674BD3FCC84644DDD6B96F7C741B1562B82F9E004DC7
STRK_TOKEN_ADDRESS = 0x04718F5A0FC34CC1AF16A1CDEE98FFB20C31F5CD61D6AB07201858F4287C938D

COINBASE = int(
os.getenv("KAKAROT_COINBASE_RECIPIENT")
or "0x20eB005C0b9c906691F885eca5895338E15c36De", # Defaults to faucet on appchain sepolia
Expand Down Expand Up @@ -357,8 +359,8 @@ def __next__(self) -> Account:

NETWORK["relayers"] = RelayerPool(NETWORK.get("relayers", [default_relayer]))


kakarot_chain_ascii = bytes.fromhex(f"{ChainId.chain_id.value:014x}").lstrip(b"\x00")
logger.info(
f"ℹ️ Connected to Starknet chain id {bytes.fromhex(f'{ChainId.starknet_chain_id.value:x}')} "
f"and Kakarot chain id {bytes.fromhex(f'{ChainId.chain_id.value:014x}')}"
f"and Kakarot chain id {kakarot_chain_ascii}"
)
70 changes: 48 additions & 22 deletions kakarot_scripts/deploy_kakarot.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# %% Imports
import logging

from eth_utils.address import to_checksum_address
from uvloop import run

from kakarot_scripts.constants import (
Expand All @@ -18,6 +19,7 @@
MULTICALL3_SIGNED_TX,
NETWORK,
RPC_CLIENT,
STRK_TOKEN_ADDRESS,
NetworkType,
)
from kakarot_scripts.utils.kakarot import deploy as deploy_evm
Expand Down Expand Up @@ -136,6 +138,7 @@ async def main():
remove_lazy_account(account.address)

# %% EVM Deployments
starknet_deployments = get_starknet_deployments()
evm_deployments = get_evm_deployments()

# %% Pre-EIP155 deployments, done only once
Expand All @@ -159,6 +162,7 @@ async def main():
max_fee=int(0.2e18),
)

# %% Tokens deployments
if not EVM_ADDRESS:
logger.info("ℹ️ No EVM address provided, skipping EVM deployments")
return
Expand All @@ -169,41 +173,63 @@ async def main():
EVM_ADDRESS, amount=100 if NETWORK["type"] is NetworkType.DEV else 0.01
)

coinbase = (await call("kakarot", "get_coinbase")).coinbase
if evm_deployments.get("Bridge", {}).get("address") != coinbase:
bridge = await deploy_evm("CairoPrecompiles", "EthStarknetBridge")
evm_deployments["Bridge"] = {
"address": int(bridge.address, 16),
"starknet_address": bridge.starknet_address,
for contract_app, contract_name, deployed_name, *deployment_args in [
("WETH", "WETH9", "WETH9"),
(
"CairoPrecompiles",
"DualVmToken",
"KakarotETH",
starknet_deployments["kakarot"],
ETH_TOKEN_ADDRESS,
),
(
"CairoPrecompiles",
"DualVmToken",
"KakarotSTRK",
starknet_deployments["kakarot"],
STRK_TOKEN_ADDRESS,
),
]:
deployment = evm_deployments.get(deployed_name)
if deployment is not None:
token_starknet_address = (
await call("kakarot", "get_starknet_address", deployment["address"])
).starknet_address
if deployment["starknet_address"] == token_starknet_address:
logger.info(f"✅ {deployed_name} already deployed, skipping")
continue

token = await deploy_evm(contract_app, contract_name, *deployment_args)
evm_deployments[deployed_name] = {
"address": int(token.address, 16),
"starknet_address": token.starknet_address,
}
await invoke(
"kakarot",
"set_authorized_cairo_precompile_caller",
int(bridge.address, 16),
int(token.address, 16),
1,
)
await invoke("kakarot", "set_coinbase", int(bridge.address, 16))

coinbase = (await call("kakarot", "get_coinbase")).coinbase
if evm_deployments.get("Coinbase", {}).get("address") != coinbase:
contract = await deploy_evm(
"Kakarot",
"Coinbase",
to_checksum_address(f'{evm_deployments["KakarotETH"]["address"]:040x}'),
)
evm_deployments["Coinbase"] = {
"address": int(contract.address, 16),
"starknet_address": contract.starknet_address,
}
await invoke("kakarot", "set_coinbase", int(contract.address, 16))

coinbase = (await call("kakarot", "get_coinbase")).coinbase
if coinbase == 0:
logger.error("❌ Coinbase is set to 0, all transaction fees will be lost")
else:
logger.info(f"✅ Coinbase set to: 0x{coinbase:040x}")

weth_starknet_address = (
await call(
"kakarot",
"get_starknet_address",
evm_deployments.get("WETH", {}).get("address", 0),
)
).starknet_address
if evm_deployments.get("WETH", {}).get("starknet_address") != weth_starknet_address:
weth = await deploy_evm("WETH", "WETH9")
evm_deployments["WETH"] = {
"address": int(weth.address, 16),
"starknet_address": weth.starknet_address,
}

dump_evm_deployments(evm_deployments)
balance_after = await get_balance(account.address)
logger.info(
Expand Down
4 changes: 3 additions & 1 deletion kakarot_scripts/utils/kakarot.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,9 @@ def get_solidity_artifacts(
)
if len(target_solidity_file_path) != 1:
raise ValueError(
f"Cannot locate a unique {contract_name} in {contract_app}"
f"Cannot locate a unique {contract_name} in {contract_app}:\n"
f"Search path: {str(src_path / contract_app)}/**/{contract_name}.sol\n"
f"Found: {target_solidity_file_path}"
)

target_compilation_output = [
Expand Down
48 changes: 0 additions & 48 deletions solidity_contracts/src/CairoPrecompiles/EthStarknetBridge.sol

This file was deleted.

40 changes: 40 additions & 0 deletions solidity_contracts/src/Kakarot/Coinbase.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0 <0.9.0;

import {DualVmToken} from "../CairoPrecompiles/DualVmToken.sol";

contract Coinbase {
/// @dev The EVM address of the DualVmToken for Kakarot ETH.
DualVmToken public immutable kakarotEth;

/// @dev State variable to store the owner of the contract
address public owner;

/// Constructor sets the owner of the contract
constructor(address _kakarotEth) {
owner = msg.sender;
kakarotEth = DualVmToken(_kakarotEth);
}

/// Modifier to restrict access to owner only
/// @dev Assert that msd.sender is the owner
modifier onlyOwner() {
require(msg.sender == owner, "Not the contract owner");
_;
}

/// @notice Withdraws ETH from the contract to a Starknet address
/// @dev DualVmToken.balanceOf(this) is the same as address(this).balance
/// @param toStarknetAddress The Starknet address to withdraw to
function withdraw(uint256 toStarknetAddress) external onlyOwner {
uint256 balance = address(this).balance;
kakarotEth.transfer(toStarknetAddress, balance);
}

/// @notice Transfers ownership of the contract to a new address
/// @param newOwner The address to transfer ownership to
function transferOwnership(address newOwner) external onlyOwner {
require(newOwner != address(0), "New owner cannot be the zero address");
owner = newOwner;
}
}
76 changes: 76 additions & 0 deletions solidity_contracts/src/Starknet/IStarknetMessaging.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
Copyright 2019-2022 StarkWare Industries Ltd.
Licensed under the Apache License, Version 2.0 (the "License").
You may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.starkware.co/open-source-license/
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions
and limitations under the License.
*/
// SPDX-License-Identifier: Apache-2.0.
pragma solidity ^0.8.0;

import "./IStarknetMessagingEvents.sol";

interface IStarknetMessaging is IStarknetMessagingEvents {
/**
Returns the max fee (in Wei) that StarkNet will accept per single message.
*/
function getMaxL1MsgFee() external pure returns (uint256);

/**
Sends a message to an L2 contract.
This function is payable, the paid amount is the message fee.
Returns the hash of the message and the nonce of the message.
*/
function sendMessageToL2(
uint256 toAddress,
uint256 selector,
uint256[] calldata payload
) external payable returns (bytes32, uint256);

/**
Consumes a message that was sent from an L2 contract.
Returns the hash of the message.
*/
function consumeMessageFromL2(uint256 fromAddress, uint256[] calldata payload)
external
returns (bytes32);

/**
Starts the cancellation of an L1 to L2 message.
A message can be canceled messageCancellationDelay() seconds after this function is called.
Note: This function may only be called for a message that is currently pending and the caller
must be the sender of the that message.
*/
function startL1ToL2MessageCancellation(
uint256 toAddress,
uint256 selector,
uint256[] calldata payload,
uint256 nonce
) external returns (bytes32);

/**
Cancels an L1 to L2 message, this function should be called at least
messageCancellationDelay() seconds after the call to startL1ToL2MessageCancellation().
A message may only be cancelled by its sender.
If the message is missing, the call will revert.
Note that the message fee is not refunded.
*/
function cancelL1ToL2Message(
uint256 toAddress,
uint256 selector,
uint256[] calldata payload,
uint256 nonce
) external returns (bytes32);
}
66 changes: 66 additions & 0 deletions solidity_contracts/src/Starknet/IStarknetMessagingEvents.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
Copyright 2019-2022 StarkWare Industries Ltd.
Licensed under the Apache License, Version 2.0 (the "License").
You may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.starkware.co/open-source-license/
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions
and limitations under the License.
*/
// SPDX-License-Identifier: Apache-2.0.
pragma solidity ^0.8.0;

interface IStarknetMessagingEvents {
// This event needs to be compatible with the one defined in Output.sol.
event LogMessageToL1(uint256 indexed fromAddress, address indexed toAddress, uint256[] payload);

// An event that is raised when a message is sent from L1 to L2.
event LogMessageToL2(
address indexed fromAddress,
uint256 indexed toAddress,
uint256 indexed selector,
uint256[] payload,
uint256 nonce,
uint256 fee
);

// An event that is raised when a message from L2 to L1 is consumed.
event ConsumedMessageToL1(
uint256 indexed fromAddress,
address indexed toAddress,
uint256[] payload
);

// An event that is raised when a message from L1 to L2 is consumed.
event ConsumedMessageToL2(
address indexed fromAddress,
uint256 indexed toAddress,
uint256 indexed selector,
uint256[] payload,
uint256 nonce
);

// An event that is raised when a message from L1 to L2 Cancellation is started.
event MessageToL2CancellationStarted(
address indexed fromAddress,
uint256 indexed toAddress,
uint256 indexed selector,
uint256[] payload,
uint256 nonce
);

// An event that is raised when a message from L1 to L2 is canceled.
event MessageToL2Canceled(
address indexed fromAddress,
uint256 indexed toAddress,
uint256 indexed selector,
uint256[] payload,
uint256 nonce
);
}
Loading

0 comments on commit f247bab

Please sign in to comment.