Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add in-code docs #822

Merged
merged 12 commits into from
Dec 6, 2023
6 changes: 3 additions & 3 deletions src/access/accesscontrol/accesscontrol.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ mod AccessControlComponent {
///
/// Requirements:
///
/// - the caller must have `role`'s admin role.
/// - The caller must have `role`'s admin role.
fn grant_role(
ref self: ComponentState<TContractState>, role: felt252, account: ContractAddress
) {
Expand All @@ -106,7 +106,7 @@ mod AccessControlComponent {
///
/// Requirements:
///
/// - the caller must have `role`'s admin role.
/// - The caller must have `role`'s admin role.
fn revoke_role(
ref self: ComponentState<TContractState>, role: felt252, account: ContractAddress
) {
Expand All @@ -126,7 +126,7 @@ mod AccessControlComponent {
///
/// Requirements:
///
/// - the caller must be `account`.
/// - The caller must be `account`.
fn renounce_role(
ref self: ComponentState<TContractState>, role: felt252, account: ContractAddress
) {
Expand Down
15 changes: 15 additions & 0 deletions src/access/ownable/ownable.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,13 @@ mod OwnableComponent {
}

/// Transfers ownership of the contract to a new address.
///
/// Requirements:
///
/// - `new_owner` is not the zero address.
/// - The caller is the contract owner.
///
/// Emits an `OwnershipTransferred` event.
fn transfer_ownership(
ref self: ComponentState<TContractState>, new_owner: ContractAddress
) {
Expand All @@ -58,6 +65,12 @@ mod OwnableComponent {

/// Leaves the contract without owner. It will not be possible to call `assert_only_owner`
/// functions anymore. Can only be called by the current owner.
///
/// Requirements:
///
/// - The caller is the contract owner.
///
/// Emits an `OwnershipTransferred` event.
fn renounce_ownership(ref self: ComponentState<TContractState>) {
self.assert_only_owner();
self._transfer_ownership(Zeroable::zero());
Expand Down Expand Up @@ -101,6 +114,8 @@ mod OwnableComponent {
/// Transfers ownership of the contract to a new address.
///
/// Internal function without access restriction.
///
/// Emits an `OwnershipTransferred` event.
fn _transfer_ownership(
ref self: ComponentState<TContractState>, new_owner: ContractAddress
) {
Expand Down
13 changes: 13 additions & 0 deletions src/account/account.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ mod AccountComponent {
+Drop<TContractState>
> of interface::ISRC6<ComponentState<TContractState>> {
/// Executes a list of calls from the account.
///
/// Requirements:
///
/// - The transaction version must be `TRANSACTION_VERSION` for actual transactions.
/// For simulations, the version must be `QUERY_VERSION`.
fn __execute__(
self: @ComponentState<TContractState>, mut calls: Array<Call>
) -> Array<Span<felt252>> {
Expand Down Expand Up @@ -140,6 +145,12 @@ mod AccountComponent {
}

/// Sets the public key of the account to `new_public_key`.
///
/// Requirements:
///
/// - The caller must be the contract itself.
///
/// Emits an `OwnerRemoved` event.
fn set_public_key(ref self: ComponentState<TContractState>, new_public_key: felt252) {
self.assert_only_self();
self.emit(OwnerRemoved { removed_owner_guid: self.Account_public_key.read() });
Expand Down Expand Up @@ -213,6 +224,8 @@ mod AccountComponent {

/// Sets the public key without validating the caller.
/// The usage of this method outside the `set_public_key` function is discouraged.
///
/// Emits an `OwnerAdded` event.
fn _set_public_key(ref self: ComponentState<TContractState>, new_public_key: felt252) {
self.Account_public_key.write(new_public_key);
self.emit(OwnerAdded { new_owner_guid: new_public_key });
Expand Down
4 changes: 4 additions & 0 deletions src/introspection/src5.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ mod SRC5Component {
}

/// Deregisters the given interface as supported by the contract.
///
/// Requirements:
///
/// - `interface_id` is not `ISRC5_ID`
fn deregister_interface(ref self: ComponentState<TContractState>, interface_id: felt252) {
assert(interface_id != interface::ISRC5_ID, Errors::INVALID_ID);
self.SRC5_supported_interfaces.write(interface_id, false);
Expand Down
4 changes: 4 additions & 0 deletions src/security/initializable.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ mod InitializableComponent {
TContractState, +HasComponent<TContractState>
> of InternalTrait<TContractState> {
/// Ensures the calling function can only be called once.
///
/// Requirements:
///
/// - `initialize` was not previously called.
fn initialize(ref self: ComponentState<TContractState>) {
assert(!self.is_initialized(), Errors::INITIALIZED);
self.Initializable_initialized.write(true);
Expand Down
14 changes: 12 additions & 2 deletions src/security/pausable.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -67,15 +67,25 @@ mod PausableComponent {
}

/// Triggers a stopped state.
/// The contract must not already be paused.
///
/// Requirements:
///
/// - The contract is not paused.
///
/// Emits a `Paused` event.
fn _pause(ref self: ComponentState<TContractState>) {
self.assert_not_paused();
self.Pausable_paused.write(true);
self.emit(Paused { account: get_caller_address() });
}

/// Lifts the pause on the contract.
/// The contract must already be paused.
///
/// Requirements:
///
/// - The contract is paused.
///
/// Emits an `Unpaused` event.
fn _unpause(ref self: ComponentState<TContractState>) {
self.assert_paused();
self.Pausable_paused.write(false);
Expand Down
2 changes: 0 additions & 2 deletions src/tests/mocks/upgrades_mocks.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ trait UpgradesV1Trait<TState> {
mod UpgradesV1 {
use openzeppelin::upgrades::UpgradeableComponent;
use starknet::ClassHash;
use starknet::ContractAddress;

component!(path: UpgradeableComponent, storage: upgradeable, event: UpgradeableEvent);

Expand Down Expand Up @@ -81,7 +80,6 @@ trait UpgradesV2Trait<TState> {
mod UpgradesV2 {
use openzeppelin::upgrades::UpgradeableComponent;
use starknet::ClassHash;
use starknet::ContractAddress;

component!(path: UpgradeableComponent, storage: upgradeable, event: UpgradeableEvent);

Expand Down
70 changes: 67 additions & 3 deletions src/token/erc20/erc20.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -83,15 +83,20 @@ mod ERC20Component {
/// Returns the remaining number of tokens that `spender` is
/// allowed to spend on behalf of `owner` through `transfer_from`.
/// This is zero by default.
/// This value changes when `approve` or `transfer_from`
/// are called.
/// This value changes when `approve` or `transfer_from` are called.
fn allowance(
self: @ComponentState<TContractState>, owner: ContractAddress, spender: ContractAddress
) -> u256 {
self.ERC20_allowances.read((owner, spender))
}

/// Moves `amount` tokens from the caller's token balance to `to`.
///
/// Requirements:
///
/// - `recipient` is not the zero address.
/// - The caller has a balance of at least `amount`.
///
/// Emits a `Transfer` event.
fn transfer(
ref self: ComponentState<TContractState>, recipient: ContractAddress, amount: u256
Expand All @@ -103,6 +108,14 @@ mod ERC20Component {

/// Moves `amount` tokens from `from` to `to` using the allowance mechanism.
/// `amount` is then deducted from the caller's allowance.
///
/// Requirements:
///
/// - `sender` is not the zero address.
/// - `sender` must have a balance of at least `amount`.
/// - `recipient` is not the zero address.
/// - The caller has an allowance of `sender`'s tokens of at least `amount`.
///
/// Emits a `Transfer` event.
fn transfer_from(
ref self: ComponentState<TContractState>,
Expand All @@ -117,6 +130,12 @@ mod ERC20Component {
}

/// Sets `amount` as the allowance of `spender` over the caller’s tokens.
///
/// Requirements:
///
/// - `spender` is not the zero address.
///
/// Emits an `Approval` event.
fn approve(
ref self: ComponentState<TContractState>, spender: ContractAddress, amount: u256
) -> bool {
Expand Down Expand Up @@ -151,6 +170,11 @@ mod ERC20Component {
TContractState, +HasComponent<TContractState>
> of interface::ISafeAllowance<ComponentState<TContractState>> {
/// Increases the allowance granted from the caller to `spender` by `added_value`.
///
/// Requirements:
///
/// - `spender` is not the zero address.
///
/// Emits an `Approval` event indicating the updated allowance.
fn increase_allowance(
ref self: ComponentState<TContractState>, spender: ContractAddress, added_value: u256
Expand All @@ -159,6 +183,12 @@ mod ERC20Component {
}

/// Decreases the allowance granted from the caller to `spender` by `subtracted_value`.
///
/// Requirements:
///
/// - `spender` is not the zero address.
/// - `spender` must have at least an allowance of `subtracted_value`.
///
/// Emits an `Approval` event indicating the updated allowance.
fn decrease_allowance(
ref self: ComponentState<TContractState>,
Expand Down Expand Up @@ -228,6 +258,13 @@ mod ERC20Component {
}

/// Internal method that moves an `amount` of tokens from `from` to `to`.
///
/// Requirements:
///
/// - `sender` is not the zero address.
/// - `sender` must have at least a balance of `amount`.
/// - `recipient` is not the zero address.
///
/// Emits a `Transfer` event.
fn _transfer(
ref self: ComponentState<TContractState>,
Expand All @@ -244,6 +281,12 @@ mod ERC20Component {

/// Internal method that sets `amount` as the allowance of `spender` over the
/// `owner`s tokens.
///
/// Requirements:
///
/// - `owner` is not the zero address.
/// - `spender` is not the zero address.
///
/// Emits an `Approval` event.
fn _approve(
ref self: ComponentState<TContractState>,
Expand All @@ -258,6 +301,11 @@ mod ERC20Component {
}

/// Creates a `value` amount of tokens and assigns them to `account`.
///
/// Requirements:
///
/// - `recipient` is not the zero address.
///
/// Emits a `Transfer` event with `from` set to the zero address.
fn _mint(
ref self: ComponentState<TContractState>, recipient: ContractAddress, amount: u256
Expand All @@ -268,7 +316,13 @@ mod ERC20Component {
self.emit(Transfer { from: Zeroable::zero(), to: recipient, value: amount });
}

/// Destroys a `value` amount of tokens from `account`.
/// Destroys `amount` of tokens from `account`.
///
/// Requirements:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't enough balance a requirement?

///
/// - `account` is not the zero address.
/// - `account` must have at least a balance of `amount`.
///
/// Emits a `Transfer` event with `to` set to the zero address.
fn _burn(ref self: ComponentState<TContractState>, account: ContractAddress, amount: u256) {
assert(!account.is_zero(), Errors::BURN_FROM_ZERO);
Expand All @@ -291,6 +345,11 @@ mod ERC20Component {
}

/// Internal method for the external `decrease_allowance`.
///
/// Requirements:
///
/// - `spender` must have at least an allowance of `subtracted_value` from caller.
///
/// Emits an `Approval` event indicating the updated allowance.
fn _decrease_allowance(
ref self: ComponentState<TContractState>,
Expand All @@ -309,6 +368,11 @@ mod ERC20Component {

/// Updates `owner`s allowance for `spender` based on spent `amount`.
/// Does not update the allowance value in case of infinite allowance.
///
/// Requirements:
///
/// - `spender` must have at least an allowance of `amount` from `owner`.
///
/// Possibly emits an `Approval` event.
fn _spend_allowance(
ref self: ComponentState<TContractState>,
Expand Down
11 changes: 9 additions & 2 deletions src/token/erc721/erc721.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -226,8 +226,11 @@ mod ERC721Component {
}

/// Returns the Uniform Resource Identifier (URI) for the `token_id` token.
///
/// If the URI is not set for the `token_id`, the return value will be `0`.
///
/// Requirements:
///
/// - `token_id` exists.
fn token_uri(self: @ComponentState<TContractState>, token_id: u256) -> felt252 {
assert(self._exists(token_id), Errors::INVALID_TOKEN_ID);
self.ERC721_token_uri.read(token_id)
Expand Down Expand Up @@ -390,9 +393,13 @@ mod ERC721Component {
}

/// Mints `token_id` and transfers it to `to`.
///
/// Internal function without access restriction.
///
/// Requirements:
///
/// - `to` is not the zero address.
/// - `token_id` does not exist.
///
/// Emits a `Transfer` event.
fn _mint(ref self: ComponentState<TContractState>, to: ContractAddress, token_id: u256) {
assert(!to.is_zero(), Errors::INVALID_RECEIVER);
Expand Down
7 changes: 7 additions & 0 deletions src/upgrades/upgradeable.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ mod UpgradeableComponent {
impl InternalImpl<
TContractState, +HasComponent<TContractState>
> of InternalTrait<TContractState> {
/// Replaces the contract's class hash with `new_class_hash`.
///
/// Requirements:
///
/// - `new_class_hash` is not the zero address.
///
/// Emits an `Upgraded` event.
fn _upgrade(ref self: ComponentState<TContractState>, new_class_hash: ClassHash) {
assert(!new_class_hash.is_zero(), Errors::INVALID_CLASS);
starknet::replace_class_syscall(new_class_hash).unwrap();
Expand Down