Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Update syntax
  • Loading branch information
smonicas committed Oct 27, 2022
commit 528922eccc39a05ebf486bccb217806645fd7461
5 changes: 2 additions & 3 deletions not-so-smart-contracts/cairo/arithmetic_overflow/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@

The default primitive type, the felt or field element, behaves a lot like an integer does in any other language but it has a few important differences to keep in mind. The range of valid felt values is (-P/2,P/2). P here is the prime used by Cairo, which is current a 252-bit number. Arithemtic using felts is unchecked for overflow and can lead to unexpected results if this isn't properly accounted for. And since the range of values spans both negative and positive values, things like multiplying two positive numbers can have a negative value as a result, and vice versa, multiplying a two negative numbers doesn't always have a positive result.

StarkNet also provides the Uint256 module which offers a more typical 256-bit integer to developers. However, the arithmetic provided by this module is also unchecked so overflow is still something to keep in mind. For more robust integer support, consider using SafeMath from OpenZeppelin's Contracts for Cairo.
StarkNet also provides the Uint256 module which offers a more typical 256-bit integer to developers. However, the arithmetic provided by this module is also unchecked so overflow is still something to keep in mind. For more robust integer support, consider using SafeUint256 from OpenZeppelin's Contracts for Cairo.

## Attack Scenarios



## Mitigations

- Always add checks for overflow when working with felts or Uint256s directly.
- Consider using the [OpenZeppelin Contracts for Cairo's SafeMath functions](https://github.com/OpenZeppelin/cairo-contracts/blob/main/src/openzeppelin/security/safemath.cairo) instead of doing arithmetic directly
- Consider using the [OpenZeppelin Contracts for Cairo's SafeUint256 functions](https://github.com/OpenZeppelin/cairo-contracts/blob/main/src/openzeppelin/security/safemath/library.cairo) instead of doing arithmetic directly

## Examples
28 changes: 16 additions & 12 deletions not-so-smart-contracts/cairo/integer_division/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,28 @@ Consider the following functions that normalize a user's token balance to a huma

```cairo
@external
func bad_normalize_tokens{syscall_ptr : felt*, pedersen_ptr : HashBuiltin*, range_check_ptr}() -> (normalized_balance : felt):
let (user) = get_caller_address()
func bad_normalize_tokens{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() -> (
normalized_balance: felt
) {
let (user) = get_caller_address();

let (user_current_balance) = user_balances.read(user)
let (normalized_balance) = user_current_balance / 10**18
let (user_current_balance) = user_balances.read(user);
let (normalized_balance) = user_current_balance / 10 ** 18;

return (normalized_balance)
end
return (normalized_balance,);
}

@external
func better_normalize_tokens{syscall_ptr : felt*, pedersen_ptr : HashBuiltin*, range_check_ptr}() -> (normalized_balance : Uint256):
let (user) = get_caller_address()
func better_normalize_tokens{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() -> (
normalized_balance: Uint256
) {
let (user) = get_caller_address();

let (user_current_balance) = user_balances.read(user)
let (normalized_balance, _) = uint256_unsigned_div_rem(user_current_balance, 10**18)
let (user_current_balance) = user_balances.read(user);
let (normalized_balance, _) = uint256_unsigned_div_rem(user_current_balance, 10 ** 18);

return (normalized_balance)
end
return (normalized_balance,);
}
```

## Mitigations
Expand Down
16 changes: 9 additions & 7 deletions not-so-smart-contracts/cairo/view_state/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@ Consider the following function that's declared as a `@view`. It may have origin

```cairo
@view
func bad_get_nonce{syscall_ptr : felt*, pedersen_ptr : HashBuiltin*, range_check_ptr}() -> (nonce : felt):
let (user) = get_caller_address()
let (nonce) = user_nonces.read(user)
user_nonces.write(user, nonce + 1)

return (nonce)
end
func bad_get_nonce{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() -> (
nonce: felt
) {
let (user) = get_caller_address();
let (nonce) = user_nonces.read(user);
user_nonces.write(user, nonce + 1);

return (nonce);
}
```

## Mitigations
Expand Down