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

Commit

Permalink
feat: Ownable2Step coinbase
Browse files Browse the repository at this point in the history
  • Loading branch information
obatirou committed Oct 10, 2024
1 parent 62503d3 commit 307cb8a
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 26 deletions.
1 change: 1 addition & 0 deletions remappings.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@openzeppelin-contracts/=solidity_contracts/lib/openzeppelin-contracts/contracts/
23 changes: 3 additions & 20 deletions solidity_contracts/src/Kakarot/Coinbase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,39 +2,22 @@
pragma solidity >=0.8.0 <0.9.0;

import {DualVmToken} from "../CairoPrecompiles/DualVmToken.sol";
import {Ownable2Step, Ownable} from "@openzeppelin-contracts/access/Ownable2Step.sol";

contract Coinbase {
contract Coinbase is Ownable2Step {
/// @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;
constructor(address _kakarotEth) Ownable(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;
}
}
27 changes: 21 additions & 6 deletions tests/end_to_end/Kakarot/test_coinbase.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import pytest
import pytest_asyncio
from eth_abi import encode
from eth_utils import keccak
from eth_utils.address import to_checksum_address

from kakarot_scripts.utils.kakarot import deploy, eth_balance_of, fund_address
from kakarot_scripts.utils.starknet import invoke
Expand Down Expand Up @@ -39,23 +42,35 @@ async def test_should_withdraw_all_eth(self, coinbase, owner):
assert balance_owner - balance_owner_prev + tx["gas_used"] == 0.001e18

async def test_should_revert_when_not_owner(self, coinbase, other):
with evm_error("Not the contract owner"):
error = keccak(b"OwnableUnauthorizedAccount(address)")[:4] + encode(
["address"], [other.address]
)
with evm_error(error):
await coinbase.withdraw(0xDEAD, caller_eoa=other.starknet_contract)

class TestTransferOwnership:

async def test_should_transfer_ownership(self, coinbase, owner, other):
# initiate transfer process
await coinbase.transferOwnership(other.address)
assert await coinbase.pendingOwner() == other.address
assert await coinbase.owner() == owner.address
# accept the transfer
await coinbase.acceptOwnership(caller_eoa=other.starknet_contract)
ZERO_ADDRESS = to_checksum_address(f"0x{0:040x}")
assert await coinbase.pendingOwner() == ZERO_ADDRESS
assert await coinbase.owner() == other.address
# teardown
await coinbase.transferOwnership(
owner.address, caller_eoa=other.starknet_contract
)

async def test_should_revert_when_new_owner_is_zero_address(self, coinbase):
with evm_error("New owner cannot be the zero address"):
await coinbase.transferOwnership(f"0x{0:040x}")
await coinbase.acceptOwnership(caller_eoa=owner.starknet_contract)

async def test_should_revert_when_not_owner(self, coinbase, other):
with evm_error("Not the contract owner"):
error = keccak(b"OwnableUnauthorizedAccount(address)")[:4] + encode(
["address"], [other.address]
)
with evm_error(error):
await coinbase.transferOwnership(
other.address, caller_eoa=other.starknet_contract
)

0 comments on commit 307cb8a

Please sign in to comment.