#[starknet::contract] mod BridgeToken { use openzeppelin::access::ownable::OwnableComponent; use openzeppelin::token::erc20::{ERC20Component, ERC20HooksEmptyImpl, interface as interface}; use openzeppelin::upgrades::upgradeable::UpgradeableComponent; use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; use starknet::{ClassHash, ContractAddress, get_caller_address}; component!(path: ERC20Component, storage: erc20, event: ERC20Event); component!(path: OwnableComponent, storage: ownable, event: OwnableEvent); component!(path: UpgradeableComponent, storage: upgradeable, event: UpgradeableEvent); #[abi(embed_v0)] impl ERC20Impl = ERC20Component::ERC20Impl; #[abi(embed_v0)] impl ERC20CamelOnlyImpl = ERC20Component::ERC20CamelOnlyImpl; impl ERC20InternalImpl = ERC20Component::InternalImpl; impl OwnableMixinImpl = OwnableComponent::OwnableMixinImpl; impl OwnableInternalImpl = OwnableComponent::InternalImpl; impl UpgradeableInternalImpl = UpgradeableComponent::InternalImpl; #[storage] struct Storage { #[substorage(v0)] erc20: ERC20Component::Storage, #[substorage(v0)] ownable: OwnableComponent::Storage, #[substorage(v0)] upgradeable: UpgradeableComponent::Storage, decimals: u8, } #[event] #[derive(Drop, starknet::Event)] enum Event { #[flat] ERC20Event: ERC20Component::Event, #[flat] OwnableEvent: OwnableComponent::Event, #[flat] UpgradeableEvent: UpgradeableComponent::Event, } #[constructor] fn constructor(ref self: ContractState, name: ByteArray, symbol: ByteArray, decimals: u8) { self._set_decimals(decimals); self.erc20.initializer(name, symbol); self.ownable.initializer(get_caller_address()); } #[abi(embed_v0)] impl ERC20CustomMetadataImpl of interface::IERC20Metadata { fn name(self: @ContractState) -> ByteArray { self.erc20.ERC20_name.read() } fn symbol(self: @ContractState) -> ByteArray { self.erc20.ERC20_symbol.read() } fn decimals(self: @ContractState) -> u8 { self.decimals.read() } } #[generate_trait] impl InternalImpl of InternalTrait { fn _set_decimals(ref self: ContractState, decimals: u8) { self.decimals.write(decimals); } } #[external(v0)] fn mint(ref self: ContractState, recipient: ContractAddress, amount: u256) { self.ownable.assert_only_owner(); self.erc20.mint(recipient, amount); } #[external(v0)] fn burn(ref self: ContractState, account: ContractAddress, amount: u256) { self.ownable.assert_only_owner(); self.erc20.burn(account, amount); } #[external(v0)] fn upgrade(ref self: ContractState, new_class_hash: ClassHash) { self.ownable.assert_only_owner(); self.upgradeable.upgrade(new_class_hash); } }