diff --git a/src/SUMMARY.md b/src/SUMMARY.md
index 268a0a657..5fb1e302c 100644
--- a/src/SUMMARY.md
+++ b/src/SUMMARY.md
@@ -29,11 +29,11 @@
- [Starknet-py: Python SDK 🚧](ch02-11-starknet-py.md)
- [Starknet-rs: Rust SDK 🚧](ch02-12-starknet-rs.md)
- [Foundry Forge: Testing](ch02-13-foundry-forge.md)
- - [Security Tools](ch02-13-security-tools.md)
- - [Cairo-fuzzer](ch02-13-01-cairo-fuzzer.md)
- - [Caracal](ch02-13-02-caracal.md)
- - [Thoth](ch02-13-03-thoth.md)
- - [Security Considerations](ch02-13-04-security-considerations.md)
+ - [Security Considerations](ch02-14-security-considerations.md)
+ - [Security Tools](ch02-15-security-tools.md)
+ - [Cairo-fuzzer](ch02-15-01-cairo-fuzzer.md)
+ - [Caracal](ch02-15-02-caracal.md)
+ - [Thoth](ch02-15-03-thoth.md)
## Architecture
diff --git a/src/ch02-13-02-caracal.md b/src/ch02-13-02-caracal.md
deleted file mode 100644
index 616e97f3a..000000000
--- a/src/ch02-13-02-caracal.md
+++ /dev/null
@@ -1,33 +0,0 @@
-# Caracal
-
-[Caracal](https://github.com/crytic/caracal) is a static analyzer tool over the SIERRA representation for Starknet smart contracts.
-
-## Features
-
-- Detectors to detect vulnerable Cairo code
-- Printers to report information
-- Taint analysis
-- Data flow analysis framework
-- Easy to run in Scarb projects
-
-## Installation
-
-Precompiled binaries
-
-Precompiled binaries are available on our releases page. If you are using Cairo compiler 1.x.x uses the binary v0.1.x otherwise if you are using the Cairo compiler 2.x.x uses v0.2.x.
-
-### Building from source
-
-You need the Rust compiler and Cargo. Building from git:
-
-```bash
-cargo install --git https://github.com/crytic/caracal --profile release --force
-```
-
-### Building from a local copy:
-
-```bash
-git clone https://github.com/crytic/caracal
-cd caracal
-cargo install --path . --profile release --force
-```
diff --git a/src/ch02-13-03-thoth.md b/src/ch02-13-03-thoth.md
deleted file mode 100644
index 8f13a5d91..000000000
--- a/src/ch02-13-03-thoth.md
+++ /dev/null
@@ -1,28 +0,0 @@
-# Thoth
-
-[Thoth](https://github.com/FuzzingLabs/thoth) (pronounced "taut" or "toss") is a Cairo/Starknet security toolkit including analyzers, disassemblers & decompilers written in Python 3. Thoth's features include the generation of the call graph, the control-flow graph (CFG) and the data-flow graph for a given Sierra file or Cairo/Starknet compilation artifact. It also includes some really advanced tools like a Symbolic execution engine and Symbolic bounded model checker.
-
-## Features
-
-- Remote & Local: Thoth can both analyze contracts deployed on Mainnet/Goerli and compiled locally on your machine.
-- Decompiler: Thoth can convert assembly into decompiled code with SSA (Static Single Assignment)
-- Call Flow analysis: Thoth can generate a Call Flow Graph
-- Static analysis: Thoth can run various analyzers of different types (security/optimization/analytics) on the contract
-- Symbolic execution: Thoth can use the symbolic execution to find the right variables values to get through a specific path in a function and also automatically generate test cases for a function.
-- Data Flow analysis: Thoth can generate a Data Flow Graph (DFG) for each function
-- Disassembler: Thoth can translate bytecode into assembly representation
-- Control Flow analysis: Thoth can generate a Control Flow Graph (CFG)
-- Cairo Fuzzer inputs generation: Thoth can generate inputs for the Cairo fuzzer
-- Sierra files analysis : Thoth can analyze Sierra files
-- Sierra files symbolic execution : Thoth allows symbolic execution on sierra files
-- Symbolic bounded model checker : Thoth can be used as a Symbolic bounded model checker
-
-
-## Installation
-
-```bash
-sudo apt install graphviz
-git clone https://github.com/FuzzingLabs/thoth && cd thoth
-pip install .
-thoth -h
-```
diff --git a/src/ch02-13-04-security-considerations.md b/src/ch02-13-04-security-considerations.md
deleted file mode 100644
index 322f34633..000000000
--- a/src/ch02-13-04-security-considerations.md
+++ /dev/null
@@ -1,385 +0,0 @@
-# Security Considerations
-
-When working with any blockchain programming language, it's crucial to be aware of potential vulnerabilities in smart contracts in order to protect your projects from threats that could compromise the trust users place in your systems. Cairo is no exception.
-
-This section will explain some common security issues and vulnerabilities specific to Starknet and Cairo, and provide recommendations on how to prevent them from affecting your contracts.
-
-Contributions to this chapter are welcome. If you have any suggestions, please submit a pull request to the [Book repo](https://github.com/starknet-edu/starknetbook).
-
-> Please note that some of the code examples provided in this chapter are written in pseudo-code for the sake of simplicity and clarity when explaining the concepts. They are not meant to be used in production.
-
-## 1. Access Control
-
-Access control vulnerabilities arise when a smart contract's functions are inadequately secured, allowing unauthorized users to perform actions that should be restricted. This can lead to unintended smart contract behavior and manipulation of sensitive data.
-
-For example, consider a smart contract that handles token minting without proper access control:
-
-```rust
-#[starknet::contract]
-mod Token {
- #[storage]
- struct Storage {
- total_supply: u256,
- }
-
- #[external(v0)]
- impl ITokenImpl of IToken {
- fn mint_tokens(ref self: ContractState, amount: u256) {
- self.total_supply.write(self.total_supply.read() + amount);
- }
- }
-}
-```
-
-In this example, any user can call the `mint_tokens` function and mint new tokens, potentially leading to an exploit or manipulation of the token supply.
-
-### Recommendation
-
-To mitigate access control vulnerabilities, implement proper authorization mechanisms such as role-based access control (RBAC) or ownership checks. You can create your own custom solution or use existing templates like those provided by OpenZeppelin.
-
-In the example above, we can add an owner variable, set the owner value in the constructor, and add an assert condition in the `mint_tokens` function to ensure that only the owner can mint new tokens.
-
-```rust
-#[starknet::contract]
-mod Token {
-
- #[storage]
- struct Storage {
- owner: ContractAddress,
- total_supply: u256,
- }
-
- #[constructor]
- fn constructor(ref self: ContractState,) {
- let sender = get_caller_address();
- self.owner.write(sender);
- }
-
- #[external(v0)]
- impl ITokenImpl of IToken {
- fn mint_tokens(ref self: ContractState, amount: u256) {
- // Now, only owner can mint
- let sender = get_caller_address();
- assert(sender == self.owner.read());
-
- self.total_supply.write(self.total_supply.read() + amount);
- }
- }
-}
-```
-
-By implementing proper access control, you can ensure that your smart contract functions are only executed by authorized parties, reducing the risk of unauthorized manipulation.
-
-## 2. Reentrancy
-
-Reentrancy vulnerabilities occur when a smart contract's function calls an external contract before updating its internal state, allowing the external contract to recursively call the initial function before it has completed execution.
-
-For example, consider a game contract where whitelisted addresses can mint an NFT sword and execute an `on_receive_sword()` function to use it before returning it to the contract. However, the NFT contract is vulnerable to reentrancy attacks, allowing an attacker to mint multiple NFT swords.
-
-```rust
-#[storage]
-struct Storage {
- available_swords: u256,
- sword: LegacyMap::,
- whitelisted: LegacyMap::,
- ...
- ...
-}
-
-#[constructor]
-fn constructor(ref self: ContractState,) {
- self.available_swords.write(100);
-}
-
-#[external(v0)]
-impl IGameImpl of IGame {
- fn mint_one_sword(ref self: ContractState) {
- let sender = get_caller_address();
- if self.whitelisted.read(sender) == true {
- // Update sword count
- let sword_count = self.available_swords.read();
- self.available_swords.write(sword_count - 1);
- // Mint one sword to caller
- self.sword.write(sender, 1);
- // Callback to sender
- let callback = ICallerDispatcher { contract_address: sender }.on_receive_sword();
- // Remove sender from whitelist
- self.whitelisted.write(sender, false);
- }
-}
-```
-
-An attacker's contract can implement the `on_receive_sword` function to exploit the reentrancy vulnerability and mint multiple swords calling `mint_one_sword` again previous to remove the sender from `whitelisted`:
-
-```rust
-fn on_receive_sword(ref self: ContractState) {
- let nft_sword_contract = get_caller_address();
- let call_number: felt252 = self.total_calls.:read();
- self.total_calls.write(call_number + 1);
- if call_number < 10 {
- let call = ISwordDispatcher { contract_address: nft_sword_contract }.mint_one_sword();
- }
-}
-```
-
-Reentrancy controls may need to be implemented in callback functions in many ERC standards with `safeTransfer` functions (ERC721, ERC777, ERC1155, ERC223, etc.) or in flash loans where lender contracts callback the borrower contract to use and return funds.
-
-### Recommendation:
-
-To mitigate reentrancy vulnerabilities, follow the check-effects-interactions pattern, ensuring that you update the relevant internal state before calling external contracts. In the example above, remove the sender from the whitelist before calling the external function.
-
-```rust
-if self.whitelisted.read(sender) == true {
- // Update sword count
- let sword_count = self.available_swords.read();
- self.available_swords.write(sword_count - 1);
- // Mint one sword to caller
- self.sword.write(sender, 1);
- // Remove sender from whitelist (before calling external function)
- self.whitelisted.write(sender, false);
- // Callback to sender (after setting all effects)
- let callback = ICallerDispatcher { contract_address: sender }.on_receive_sword();
-}
-```
-
-By following the check-effects-interactions pattern, you can reduce the risk of reentrancy attacks, ensuring the integrity of your smart contract's internal state.
-
-## 3. Tx.Origin Authentication
-
-In Solidity, `tx.origin` is a global variable that stores the address of the transaction initiator, while `msg.sender` stores the address of the transaction caller. In Cairo, we have the `account_contract_address` global variable and `get_caller_address` function, which serve the same purpose.
-
-Using `account_contract_address` (the equivalent of `tx.origin`) for authentication in your smart contract functions can lead to phishing attacks. Attackers can create custom smart contracts and trick users into placing them as intermediaries in a transaction call, effectively impersonating the contract owner.
-
-For example, consider a Cairo smart contract that allows transferring funds to the owner and uses `account_contract_address` for authentication:
-
-```rust
-use starknet::get_caller_address;
-use box::BoxTrait;
-
-struct Storage {
- owner: ContractAddress,
-}
-
-#[constructor]
-fn constructor(){
- // Set contract deployer as the owner
- let contract_deployer = get_caller_address();
- self.owner.write(contract_deployer)
-}
-
-#[external(v0)]
-impl ITokenImpl of IToken {
- fn transferTo(ref self: ContractState, to: ContractAddress, amount: u256) {
- let tx_info = starknet::get_tx_info().unbox();
- let authorizer: ContractAddress = tx_info.account_contract_address;
- assert(authorizer == self.owner.read());
- self.balance.write(to + amount);
- }
-}
-```
-
-An attacker can trick the owner into using a malicious contract, allowing the attacker to call the `transferTo` function and impersonate the contract owner:
-
-```rust
-#[starknet::contract]
-mod MaliciousContract {
-...
-...
-#[external(v0)]
-impl IMaliciousContractImpl of IMaliciousContract {
- fn transferTo(ref self: ContractState, to: ContractAddress, amount: u256) {
- let callback = ICallerDispatcher { contract_address: sender }.transferTo(ATTACKER_ACCOUNT, amount);
- }
-}
-```
-
-### Recommendation:
-
-Replace `account_contract_address` (origin) authentication with `get_caller_address` (sender) in the `transferTo` function to prevent phishing attacks:
-
-```rust
-use starknet::get_caller_address;
-
-struct Storage {
- owner: ContractAddress,
-}
-
-#[constructor]
-fn constructor(){
- // Set contract deployer as the owner
- let contract_deployer = get_caller_address();
- self.owner.write(contract_deployer)
-}
-
-#[external(v0)]
-impl ITokenImpl of IToken {
- fn transferTo(ref self: ContractState, to: ContractAddress, amount: u256) {
- let authorizer = get_caller_address();
- assert(authorizer == self.owner.read());
- self.balance.write(to + amount);
- }
-}
-```
-
-By using the correct authentication method, you can prevent phishing attacks and ensure that only authorized users can execute specific smart contract functions.
-
-## 4. Handling Overflow and Underflow in Smart Contracts
-
-Overflow and underflow vulnerabilities occur when assigning a value that is too large (overflow) or too small (underflow) for a given data type. In this section, we'll explore how to mitigate these issues in Starknet smart contracts.
-
-When using the `felt252` data type, adding or subtracting a value outside the valid range can lead to incorrect results:
-
-```rust
- fn overflow_felt252() -> felt252 {
- // Assign max felt252 value = 2^251 + 17 * 2^192
- let max: felt252 = 3618502788666131106986593281521497120414687020801267626233049500247285301248 + 17 * 6277101735386680763835789423207666416102355444464034512896;
- max + 3
- }
-
- fn underflow_felt252() -> felt252 {
- let min: felt252 = 0;
- // Assign max felt252 value = 2^251 + 17 * 2^192
- let substract = (3618502788666131106986593281521497120414687020801267626233049500247285301248 + 17 * 6277101735386680763835789423207666416102355444464034512896);
- min - substract
- }
-```
-
-We will get wrong values:
-
-
-
-### Recommendation:
-
-To avoid incorrect results, _use protected data types_: Utilize data types like `u128` or `u256` that are designed to handle overflows and underflows.
-
-Here's an example of how to use the `u256` data type to handle overflow and underflow:
-
-```rust
- fn overflow_u256() -> u256 {
- let max_u128: u128 = 0xffffffffffffffffffffffffffffffff_u128;
- let max: u256 = u256 { low: max_u128, high: max_u128 }; // Assign max u256 value
- let three: u256 = u256 { low: 3_u128, high: 0_u128 }; // Assign 3 value
- max + three
- }
-
- fn underflow_u256() -> u256 {
- let min: u256 = u256 { low: 0_u128, high: 0_u128 }; // Assign 0 value
- let three: u256 = u256 { low: 3_u128, high: 0_u128 }; // Assign 3 value
- min - three
- }
-```
-
-Executing these functions will revert the transaction if an overflow is detected:
-
-
-
-
-- _Failure reasons for u256_:
- - `0x753235365f616464204f766572666c6f77=u256_add Overflow`
- - `0x753235365f737562204f766572666c6f77=u256_sub Overflow`
-
-Similarly, the `u128` data type can be used to handle overflow and underflow:
-
-```rust
- fn overflow_u128() -> u128 {
- let max: u128 = 0xffffffffffffffffffffffffffffffff_u128; // Assign max u128 value
- (max + 3_u128
- }
-
- fn underflow_u128() -> u128 {
- let min: u128 = 0_u128;
- min - 3_u128
- }
-```
-
-If an overflow or underflow occurs, the transaction will be reverted with a corresponding failure reason:
-
-
-
-
-- _Failure reasons for u128_:
- - `0x753132385f616464204f766572666c6f77=u128_add Overflow`
- - `0x753132385f737562204f766572666c6f77=u128_sub Overflow`
-
-## 5. Private Data On-Chain.
-
-In some cases, a smart contracts may needs to store secret values that can't be revelead to users, however this is not possible
-if you store data on chain because all stored data is public and can be retrieved even if you don't publish your code. In the next
-example, our smart contract will use a contructor parameter to set a password (12345678) and store it on chain:
-
-```rust
-#[starknet::contract]
-mod StoreSecretPassword {
- struct Storage {
- password: felt252,
- }
-
- #[constructor]
- fn constructor(_password: felt252) {
- self.password.write(_password);
- }
-}
-```
-
-
-
-Then, understanding how storage layout works in Cairo, let's build a script to read stored smart contract variables:
-
-```javascript
-import { Provider, hash } from "starknet";
-
-const provider = new Provider({
- sequencer: {
- network: "goerli-alpha", // or 'goerli-alpha'
- },
-});
-
-var passHash = hash.starknetKeccak("password");
-console.log(
- "getStor=",
- await provider.getStorageAt(
- "0x032d0392eae7440063ea0f3f50a75dbe664aaa1df76b4662223430851a113369",
- passHash,
- 812512,
- ),
-);
-```
-
-And we will get the stored value (hex value of 12345678):
-
-
-
-Also, in a block explorer we can go to the deploy transaction and watch deployed parameters values:
-
-
-
-### Recommendation:
-
-If your smart contract needs to store private data on chain, then you must use off chain encryption before to send data to the blockchain
-or may explore some alternatives like using hashes, merkle trees or commit-reveal patterns.
-
-## Call for Contributions: Additional Vulnerabilities
-
-We've covered a few common vulnerabilities in Cairo smart contracts, but there are several more security considerations that developers should be aware of. We are currently seeking contributions from the community to expand this chapter and cover more vulnerabilities, as listed in our To-Do section:
-
-- Storage Collision
-- Flash Loan Attacks
-- Oracle Manipulation
-- Bad Randomness
-- Denial of Service
-- Untrusted Delegate Calls
-- Public Burn
-
-If you have expertise in any of these areas, we encourage you to contribute to this chapter by adding explanations and examples of the respective vulnerabilities. Your contributions will help educate and inform the Starknet and Cairo developer community, promoting the creation of more secure and robust smart contracts.
-
-Thank you for your support in making the Starknet ecosystem safer and more secure for all developers and users.
-
-The Book is a community-driven effort created for the community.
-
-- If you’ve learned something, or not, please take a moment to provide
- feedback through [this 3-question
- survey](https://a.sprig.com/WTRtdlh2VUlja09lfnNpZDo4MTQyYTlmMy03NzdkLTQ0NDEtOTBiZC01ZjAyNDU0ZDgxMzU=).
-
-- If you discover any errors or have additional suggestions, don’t
- hesitate to open an [issue on our GitHub
- repository](https://github.com/starknet-edu/starknetbook/issues).
diff --git a/src/ch02-13-security-tools.md b/src/ch02-13-security-tools.md
deleted file mode 100644
index 76b565d66..000000000
--- a/src/ch02-13-security-tools.md
+++ /dev/null
@@ -1,21 +0,0 @@
-# Security Tools
-
-Today, Starknet provides tools for smart contracts security testing.
-
-We welcome contributors to enhance existing tools or develop new
-solutions.
-
-In this section, you’ll explore:
-
-- Tools for security testing
-
-- Security consideration for smart contracts
-
-Here’s a quick rundown of the tools that could be used for Starknet
-security testing and that we’ll cover in this chapter:
-
-1. Cairo-fuzzer: Designed for smart contract developers to test the security. It can be used as an independent tool or as a library..
-
-2. Caracal: Static analyzer tool over the SIERRA representation for Starknet smart contracts.
-
-3. Thoth: Cairo/Starknet security toolkit including analyzers, disassemblers & decompilers.
diff --git a/src/ch02-14-security-considerations.md b/src/ch02-14-security-considerations.md
new file mode 100644
index 000000000..3d3fb32d7
--- /dev/null
+++ b/src/ch02-14-security-considerations.md
@@ -0,0 +1,385 @@
+# Security Considerations
+
+In blockchain programming, understanding and mitigating smart contract vulnerabilities is vital to maintain user trust. This is as true for Cairo as any other language.
+
+We'll cover common security issues and Starknet-specific vulnerabilities in Cairo, along with strategies to safeguard your contracts.
+
+Your insights can enhance this chapter. To contribute, submit a pull request to the [Book repo](https://github.com/starknet-edu/starknetbook).
+
+> Note: Some code examples here are simplified pseudo-code, meant for concept explanation, not for production use.
+
+## 1. Access Control
+
+Access control vulnerabilities occur when a smart contract's functions are insufficiently protected, allowing unauthorized actions. This can result in unexpected behavior and data manipulation.
+
+Take, for instance, a smart contract for token minting without proper access control:
+
+```rust
+#[starknet::contract]
+mod Token {
+ #[storage]
+ struct Storage {
+ total_supply: u256, // Stores the total supply of tokens.
+ }
+
+ #[external(v0)]
+ impl ITokenImpl of IToken {
+ fn mint_tokens(ref self: ContractState, amount: u256) {
+ // The mint_tokens function updates the total supply.
+ // Without access control, any user can call this function, posing a risk.
+ self.total_supply.write(self.total_supply.read() + amount);
+ }
+ }
+}
+```
+
+In this code, the `mint_tokens` function is vulnerable because any user can call it, leading to potential token supply exploitation. Implementing access controls would restrict this function to authorized users only.
+
+### Recommendation
+
+To prevent access control vulnerabilities, integrate authorization mechanisms like role-based access control (RBAC) or ownership checks. You can develop a custom solution or use templates from sources like [OpenZeppelin](https://docs.openzeppelin.com/contracts-cairo/access).
+
+In our earlier example, we can enhance security by adding an owner variable, initializing the owner in the constructor, and including a verification in the `mint_tokens` function to allow only the owner to mint tokens.
+
+```rust
+#[starknet::contract]
+mod Token {
+
+ #[storage]
+ struct Storage {
+ owner: ContractAddress, // New variable to store the contract owner's address.
+ total_supply: u256,
+ }
+
+ #[constructor]
+ fn constructor(ref self: ContractState,) {
+ let sender = get_caller_address(); // Get the address of the contract creator.
+ self.owner.write(sender); // Set the creator as the owner.
+ }
+
+ #[external(v0)]
+ impl ITokenImpl of IToken {
+ fn mint_tokens(ref self: ContractState, amount: u256) {
+ // Check if the caller is the owner before minting tokens.
+ let sender = get_caller_address();
+ assert(sender == self.owner.read()); // Assert ensures only the owner can mint.
+
+ self.total_supply.write(self.total_supply.read() + amount);
+ }
+ }
+}
+```
+
+By establishing robust access control, you ensure that only authorized entities execute your smart contract functions, significantly reducing the risk of unauthorized interference.
+
+## 2. Reentrancy
+
+Reentrancy vulnerabilities arise when a smart contract calls an external contract before updating its state. This allows the external contract to recursively call the original function, potentially leading to unintended behavior.
+
+Consider a game contract where whitelisted addresses can mint an NFT sword and then execute an `on_receive_sword()` function before returning it. This NFT contract is at risk of a reentrancy attack, where an attacker can mint multiple swords.
+
+```rust
+#[storage]
+struct Storage {
+ available_swords: u256, // Stores available swords.
+ sword: LegacyMap::, // Maps swords to addresses.
+ whitelisted: LegacyMap::, // Tracks whitelisted addresses.
+ ...
+ ...
+}
+
+#[constructor]
+fn constructor(ref self: ContractState,) {
+ self.available_swords.write(100); // Initializes the sword count.
+}
+
+#[external(v0)]
+impl IGameImpl of IGame {
+ fn mint_one_sword(ref self: ContractState) {
+ let sender = get_caller_address();
+ if self.whitelisted.read(sender) {
+ // Update the sword count before minting.
+ let sword_count = self.available_swords.read();
+ self.available_swords.write(sword_count - 1);
+ // Mint a sword.
+ self.sword.write(sender, 1);
+ // Callback to sender's contract.
+ let callback = ICallerDispatcher { contract_address: sender }.on_receive_sword();
+ // Remove sender from whitelist after callback to prevent reentrancy.
+ self.whitelisted.write(sender, false);
+ }
+}
+```
+
+An attacker's contract can implement the `on_receive_sword` function to exploit the reentry vulnerability and mint multiple swords by calling `mint_one_sword` again before removing the sender from the `whitelist`:
+
+```rust
+fn on_receive_sword(ref self: ContractState) {
+ let nft_sword_contract = get_caller_address();
+ let call_number: felt252 = self.total_calls.read();
+ self.total_calls.write(call_number + 1);
+ if call_number < 10 {
+ // Attempt to mint a sword again.
+ let call = ISwordDispatcher { contract_address: nft_sword_contract }.mint_one_sword();
+ }
+}
+```
+Reentrancy protections are critical in many ERC standards with `safeTransfer` functions (like ERC721, ERC777, ERC1155, ERC223) and in flash loans, where borrower contracts need to safely use and return funds.
+
+### Recommendation:
+
+To prevent reentrancy attacks, use the check-effects-interactions pattern. This means updating your contract's internal state before interacting with external contracts. In the previous example, remove the sender from the whitelist before making the external call.
+
+```rust
+if self.whitelisted.read(sender) {
+ // Update the sword count first.
+ let sword_count = self.available_swords.read();
+ self.available_swords.write(sword_count - 1);
+ // Mint a sword to the caller.
+ self.sword.write(sender, 1);
+ // Crucially, remove the sender from the whitelist before the external call.
+ self.whitelisted.write(sender, false);
+ // Only then, make the callback to the sender.
+ let callback = ICallerDispatcher { contract_address: sender }.on_receive_sword();
+}
+```
+
+Adhering to this pattern enhances the security of your smart contract by minimizing the risk of reentrancy attacks and preserving the integrity of its internal state.
+
+## 3. Tx.Origin Authentication
+
+In Solidity, `tx.origin` is a global variable that stores the address of the transaction initiator, while `msg.sender` stores the address of the transaction caller. In Cairo, we have the `account_contract_address` global variable and `get_caller_address` function, which serve the same purpose.
+
+Using `account_contract_address` (the equivalent of `tx.origin`) for authentication in your smart contract functions can lead to phishing attacks. Attackers can create custom smart contracts and trick users into placing them as intermediaries in a transaction call, effectively impersonating the contract owner.
+
+For example, consider a Cairo smart contract that allows transferring funds to the owner and uses `account_contract_address` for authentication:
+
+```rust
+use starknet::get_caller_address;
+use box::BoxTrait;
+
+struct Storage {
+ owner: ContractAddress, // Stores the owner's address.
+}
+
+#[constructor]
+fn constructor(){
+ // Initialize the owner as the contract deployer.
+ let contract_deployer = get_caller_address();
+ self.owner.write(contract_deployer)
+}
+
+#[external(v0)]
+impl ITokenImpl of IToken {
+ fn transferTo(ref self: ContractState, to: ContractAddress, amount: u256) {
+ let tx_info = starknet::get_tx_info().unbox();
+ let authorizer: ContractAddress = tx_info.account_contract_address;
+ // Verifies the transaction initiator as the owner.
+ assert(authorizer == self.owner.read());
+ // Processes the fund transfer.
+ self.balance.write(to + amount);
+ }
+}
+```
+
+An attacker can trick the owner into using a malicious contract, allowing the attacker to call the `transferTo` function and impersonate the contract owner:
+
+```rust
+#[starknet::contract]
+mod MaliciousContract {
+...
+...
+#[external(v0)]
+impl IMaliciousContractImpl of IMaliciousContract {
+ fn transferTo(ref self: ContractState, to: ContractAddress, amount: u256) {
+ // Malicious callback to transfer funds.
+ let callback = ICallerDispatcher { contract_address: sender }.transferTo(ATTACKER_ACCOUNT, amount);
+ }
+}
+```
+
+### Recommendation:
+
+To guard against phishing attacks, replace `account_contract_address` (origin) authentication with `get_caller_address` (sender) in the `transferTo` function:
+
+```rust
+use starknet::get_caller_address;
+
+struct Storage {
+ owner: ContractAddress, // Stores the owner's address.
+}
+
+#[constructor]
+fn constructor(){
+ // Initialize the owner as the contract deployer.
+ let contract_deployer = get_caller_address();
+ self.owner.write(contract_deployer)
+}
+
+#[external(v0)]
+impl ITokenImpl of IToken {
+ fn transferTo(ref self: ContractState, to: ContractAddress, amount: u256) {
+ let authorizer = get_caller_address();
+ // Verify that the caller is the owner.
+ assert(authorizer == self.owner.read());
+ // Execute the fund transfer.
+ self.balance.write(to + amount);
+ }
+}
+```
+
+This change ensures secure authentication, preventing unauthorized users from executing critical functions and safeguarding against phishing attempts.
+
+## 4. Handling Overflow and Underflow in Smart Contracts
+
+Overflow and underflow vulnerabilities arise from assigning values too large (overflow) or too small (underflow) for a specific data type.
+
+Consider the `felt252` data type: adding or subtracting values beyond its range can yield incorrect results:
+
+```rust
+ fn overflow_felt252() -> felt252 {
+ // Assigns the maximum felt252 value: 2^251 + 17 * 2^192
+ let max: felt252 = 3618502788666131106986593281521497120414687020801267626233049500247285301248 + 17 * 6277101735386680763835789423207666416102355444464034512896;
+ // Attempting to add beyond the maximum value.
+ max + 3
+ }
+
+ fn underflow_felt252() -> felt252 {
+ let min: felt252 = 0;
+ // Same maximum value as in overflow.
+ let subtract = (3618502788666131106986593281521497120414687020801267626233049500247285301248 + 17 * 6277101735386680763835789423207666416102355444464034512896);
+ // Subtracting more than the minimum, leading to underflow.
+ min - subtract
+ }
+```
+
+Executing these functions will result in incorrect values due to overflow and underflow, as illustrated in the following image:
+
+
+
+### Recommendation:
+
+To prevent incorrect results, use protected data types like `u128` or `u256`, which are designed to manage overflows and underflows.
+
+Here's how you can use the `u256` data type to handle these issues:
+
+```rust
+ fn overflow_u256() -> u256 {
+ let max_u128: u128 = 0xffffffffffffffffffffffffffffffff_u128; // Maximum u128 value.
+ let max: u256 = u256 { low: max_u128, high: max_u128 }; // Maximum u256 value.
+ let three: u256 = u256 { low: 3_u128, high: 0_u128 }; // Value of 3.
+ max + three // Attempting to add beyond max, will trigger overflow protection.
+ }
+
+ fn underflow_u256() -> u256 {
+ let min: u256 = u256 { low: 0_u128, high: 0_u128 }; // Zero value for u256.
+ let three: u256 = u256 { low: 3_u128, high: 0_u128 }; // Value of 3.
+ min - three // Attempting to subtract from zero, will trigger underflow protection.
+ }
+```
+
+When these functions encounter overflows or underflows, the transaction will revert, as shown in these images:
+
+
+
+
+Failure reasons for `u256`:
+
+* Overflow: `0x753235365f616464204f766572666c6f77=u256_add Overflow`
+* Underflow: `0x753235365f737562204f766572666c6f77=u256_sub Overflow`
+
+Similarly, the `u128` data type can be used to handle overflow and underflow:
+
+```rust
+ fn overflow_u128() -> u128 {
+ let max: u128 = 0xffffffffffffffffffffffffffffffff_u128; // Maximum u128 value.
+ max + 3_u128 // Adding to max, overflow protection triggers if necessary.
+ }
+
+ fn underflow_u128() -> u128 {
+ let min: u128 = 0_u128; // Zero value for u128.
+ min - 3_u128 // Subtracting from zero, underflow protection activates if needed.
+ }
+```
+
+Overflow or underflow in u128 will similarly revert the transaction, with corresponding failure reasons:
+
+
+
+
+Failure reasons for u128:
+ - Overflow: `0x753132385f616464204f766572666c6f77=u128_add Overflow`
+ - Underflow: `0x753132385f737562204f766572666c6f77=u128_sub Overflow`
+
+Using these data types, you can ensure safer arithmetic operations in your smart contracts, avoiding unintended consequences of overflows and underflows.
+
+## 5. Private Data On-Chain.
+
+Storing secret values in smart contracts presents a challenge because all on-chain data is publicly accessible, even if the code isn't published. For example, consider a smart contract storing a password (12345678) using a constructor parameter:
+
+```rust
+#[starknet::contract]
+mod StoreSecretPassword {
+ struct Storage {
+ password: felt252, // Field to store the password.
+ }
+
+ #[constructor]
+ fn constructor(_password: felt252) {
+ // Writing the password to the storage.
+ self.password.write(_password);
+ }
+}
+```
+
+
+
+However, understanding Cairo's [storage layout](https://book.cairo-lang.org/ch99-01-03-01-contract-storage.html?highlight=kecc#storage-addresses), we can create a script to read the stored variable:
+
+```javascript
+import { Provider, hash } from "starknet";
+
+const provider = new Provider({
+ sequencer: {
+ network: "goerli-alpha",
+ },
+});
+
+var passHash = hash.starknetKeccak("password");
+console.log(
+ "getStor=",
+ await provider.getStorageAt(
+ "0x032d0392eae7440063ea0f3f50a75dbe664aaa1df76b4662223430851a113369",
+ passHash,
+ 812512,
+ ),
+);
+```
+
+Executing this script reveals the stored password value (hex value of 12345678):
+
+
+
+Moreover, using a block explorer, we can view the deployed parameters in the transaction:
+
+
+
+### Recommendation:
+
+If your smart contract requires storing private data on-chain, consider off-chain encryption before sending data to the blockchain. Alternatively, explore options like hashes, merkle trees, or commit-reveal patterns to maintain data privacy.
+
+## Call for Contributions: Additional Vulnerabilities
+
+We've discussed several common vulnerabilities in Cairo smart contracts, but many other security risks need attention. We invite community contributions to expand this chapter with more vulnerabilities:
+
+- Storage Collision
+- Flash Loan Attacks
+- Oracle Manipulation
+- Bad Randomness
+- Denial of Service
+- Untrusted Delegate Calls
+- Public Burn
+
+If you have expertise in these areas, please consider contributing your knowledge, including explanations and examples of these vulnerabilities. Your input will greatly benefit the Starknet and Cairo developer community, aiding in the development of more secure and resilient smart contracts.
+
+We appreciate your support in enhancing the safety and security of the Starknet ecosystem for developers and users alike.
diff --git a/src/ch02-13-01-cairo-fuzzer.md b/src/ch02-15-01-cairo-fuzzer.md
similarity index 71%
rename from src/ch02-13-01-cairo-fuzzer.md
rename to src/ch02-15-01-cairo-fuzzer.md
index 8fbee7646..0c4321278 100644
--- a/src/ch02-13-01-cairo-fuzzer.md
+++ b/src/ch02-15-01-cairo-fuzzer.md
@@ -1,26 +1,32 @@
# Cairo-fuzzer
-[Cairo-fuzzer](https://github.com/FuzzingLabs/cairo-fuzzer) is a tool designed for smart contract developers to test the security. It can be used as an independent tool or as a library.
+[Cairo-fuzzer](https://github.com/FuzzingLabs/cairo-fuzzer) is a tool designed for smart contract developers to assess security. It operates both independently and as a library.
-## Features:
+## Features
-
+
-- Run Cairo contract
-- Run Starknet contract
-- Replayer of fuzzing corpus
-- Minimizer of fuzzing corpus
-- Load old corpus
-- Handle multiple arguments
-- Workspace architecture
-- Import dictionnary
-- Use Cairo-fuzzer as a library
+- Execute Cairo contracts.
+- Execute Starknet contracts.
+- Replay fuzzing corpus.
+- Minimize fuzzing corpus.
+- Load previous corpus.
+- Manage multiple arguments.
+- Utilize workspace architecture.
+- Import dictionaries.
+- Integrate Cairo-fuzzer as a library.
-## Usage:
+## Usage
+
+To use Cairo-fuzzer, run the following command:
```bash
cargo run --release -- --cores 3 --contract tests/fuzzinglabs.json --function "Fuzz_symbolic_execution"
+```
+This outputs:
+
+```bash
For more usage information, follow our tutorial
CMDLINE (--help):
diff --git a/src/ch02-15-02-caracal.md b/src/ch02-15-02-caracal.md
new file mode 100644
index 000000000..d09804d5b
--- /dev/null
+++ b/src/ch02-15-02-caracal.md
@@ -0,0 +1,42 @@
+# Caracal
+
+[Caracal](https://github.com/crytic/caracal) is a static analysis tool for Starknet smart contracts, specifically analyzing their SIERRA representation.
+
+## Features
+
+- Vulnerability detectors for Cairo code.
+- Report printers.
+- Taint analysis.
+- Data flow analysis framework.
+- Compatibility with Scarb projects.
+
+## Installation
+
+### Precompiled Binaries
+
+Download precompiled binaries from the [releases page](https://github.com/crytic/caracal/releases). Use binary version v0.1.x for Cairo compiler 1.x.x, and v0.2.x for Cairo compiler 2.x.x.
+
+### Building from Source
+
+#### Requirements
+
+- Rust compiler
+- Cargo
+
+#### Installation Steps
+
+Clone and build from the repository:
+
+```bash
+cargo install --git https://github.com/crytic/caracal --profile release --force
+```
+
+### Building from a Local Copy:
+
+If you prefer to build from a local copy:
+
+```bash
+git clone https://github.com/crytic/caracal
+cd caracal
+cargo install --path . --profile release --force
+```
diff --git a/src/ch02-15-03-thoth.md b/src/ch02-15-03-thoth.md
new file mode 100644
index 000000000..c8f687568
--- /dev/null
+++ b/src/ch02-15-03-thoth.md
@@ -0,0 +1,31 @@
+# Thoth
+
+[Thoth](https://github.com/FuzzingLabs/thoth) (pronounced "taut" or "toss") is a security toolkit for Cairo/Starknet. Written in Python 3, it includes analyzers, disassemblers, and decompilers. Thoth is capable of generating call graphs, control-flow graphs (CFG), and data-flow graphs for Sierra files or Cairo/Starknet compilation artifacts. It also features tools like a symbolic execution engine and a symbolic bounded model checker.
+
+## Features
+
+- **Remote & Local Analysis**: Works with contracts on Mainnet/Goerli and local compilations.
+- **Decompiler**: Transforms assembly into decompiled code using SSA (Static Single Assignment).
+- **Call Flow Analysis**: Generates Call Flow Graphs.
+- **Static Analysis**: Conducts various types of analyses (security/optimization/analytics) on contracts.
+- **Symbolic Execution**: Finds variable values for specific paths in functions and generates test cases.
+- **Data Flow Analysis**: Produces Data Flow Graphs (DFG) for each function.
+- **Disassembler**: Converts bytecode to assembly.
+- **Control Flow Analysis**: Creates Control Flow Graphs (CFG).
+- **Cairo Fuzzer Inputs**: Generates inputs for Cairo fuzzer.
+- **Sierra Files Analysis**: Analyzes Sierra files.
+- **Sierra Files Symbolic Execution**: Performs symbolic execution on Sierra files.
+- **Symbolic Bounded Model Checker**: Functions as a symbolic bounded model checker.
+
+
+
+## Installation
+
+Install Thoth using the following commands:
+
+```bash
+sudo apt install graphviz
+git clone https://github.com/FuzzingLabs/thoth && cd thoth
+pip install .
+thoth -h
+```
diff --git a/src/ch02-15-security-tools.md b/src/ch02-15-security-tools.md
new file mode 100644
index 000000000..a08c12f76
--- /dev/null
+++ b/src/ch02-15-security-tools.md
@@ -0,0 +1,16 @@
+# Starknet Security Tools
+
+Starknet offers a range of tools for testing the security of smart contracts. We invite developers to improve existing tools or create new ones.
+
+This section covers:
+
+- Tools for security testing.
+- Security considerations for smart contracts.
+
+Below is an overview of the tools for Starknet security testing discussed in this chapter:
+
+1. **Cairo-fuzzer**: A tool for smart contract developers to test security. It functions both as a standalone tool and as a library.
+
+2. **Caracal**: A static analysis tool for Starknet smart contracts, utilizing the SIERRA representation.
+
+3. **Thoth**: A comprehensive Cairo/Starknet security toolkit. It includes analyzers, disassemblers, and decompilers.
diff --git a/src/draft-censorship-resistance.md b/src/draft-censorship-resistance.md
new file mode 100644
index 000000000..1bc9f958c
--- /dev/null
+++ b/src/draft-censorship-resistance.md
@@ -0,0 +1,222 @@
+# Censorship Risk and Mitigation in Centralized Roll-ups
+
+Starknet, as a yet centralized roll-ups, while offering Layer 1 (L1) security, face a notable downside: the risk of censorship. It's important to understand that StarkNet still maintains strong security features:
+
+- **Security Inheritance**: StarkNet's state transitions inherit Ethereum's security.
+- **State Recreation**: The state of StarkNet can be reconstructed using Ethereum's available data.
+
+This means, while your assets are secure (i.e., they won't be stolen), there's a risk of transaction delays or non-execution, constituting censorship. StarkNet is at the early stages of its journey towards decentralization, with StarkWare currently operating all sequencer and prover nodes.
+
+## Addressing Censorship
+
+Currently all Starknet users trust Starkware to add their transactions to blocks and trust that they will not censor these transactions. But the StarkNet ecosystem aims to create a censorship-resistant network. This leads to two primary approaches:
+
+1. **Decentralization**: The long-term goal is to increase the number of sequencers, diversifying entities validating the network. Although this doesn't completely eliminate censorship, it significantly reduces the risk.
+2. **Escape Hatches**: Designed to ensure roll-ups remain censorship-resistant, allowing assets to be moved to Ethereum. This adds either protocol or application complexity and involves trade-offs.
+
+## Ensuring Self-Custody and Asset Security
+
+Ensuring self-custody in the face of potentially dishonest sequencers presents a significant challenge. Key questions include:
+
+- **Handling Dishonest Sequencers**: If sequencers refuse to include transactions, how can we guarantee the security and autonomy of user assets?
+- **Chain Interruptions**: What measures are in place if the chain stops producing blocks, leading to stranded assets?
+
+These concerns underscore the importance of both decentralization and applicative escape hatches as vital mechanisms to safeguard user assets and maintain transaction integrity, even in scenarios of compromised sequencer integrity or chain functionality disruptions.
+
+## Decentralization and Escape Hatches
+
+### Decentralization
+
+StarkNet is committed to decentralization as a key strategy for countering censorship. The plan involves expanding the number of sequencers, thereby diversifying the network's validators. With more validators, the risk of censorship decreases, though it's acknowledged that decentralization is a complex challenge, involving various incentives and strategic considerations. Despite its complexity, decentralization is not just a long-term goal but an essential immediate action. It's recognized as a crucial first step, though it might not be the complete solution to all issues.
+
+Looking ahead to 2024, StarkNet's focus is on making the system operation as broad and permissionless as possible. The emphasis is not on resolving more subtle challenges like monopolies in searchers or builders at this stage. The primary objective is to remove operational barriers, enhancing accessibility and hopefully, this approach will significantly address the concerns around censorship.
+
+ On the other side, a talked about topic are escape hatches.
+
+---
+
+ 1. Escape Hatch:
+
+ lets think about an apllication that does not want to be decentralize right of the way. In their priorities they have two things: 1) be able to claim they maintain self-custody of their funds and that they wont censor transactions and 2) to make money. These are very credible and common requirements by companies. The question, do they need to be decentralize from the get go in order to make money and claim censorship resistance? Notice that they need to start earning money as soon as possible, they are entrepreneurs that might not want to decentralize their applications: create a token, economic incentives, consensus mechanism, voting and so on. They are entrepreneurs and clients not necesarilly means they need to be your community. They will want full decentralization eventually but they need a solution in the meantime but at the same time they want to legally claim that they maintain self custody and for this they need to confirm they are implementing a solution to be censorship resistance. But consider the real case that clients might not look for decentralization.
+
+ We are talking about Starknet Appchains, not the public Starknet layer 2 which is in its way to full decentralization. However, on the other side, notice that a escape hatch does not mean full decentralization. Only certain transactions are the ones that can be escaped from. In other words it is not that any aribitrary transactin can be escaped from. If you want to be full censorship resistance then you need all transactions to be non censaroable which is what we are looking for with decentralization. Supose the case of an exchange, for them the to crutial transactions to be non censraoble are trades and withdraws. Those are the msin things. The escpa hatch can handle those. Why not make the escape hatch able to escape all transactions? because the more transactions it handle the higher the risk the escape hatch can be hacked. You want your escape hatch to be secure. It has a attack surfface we want to limit their functionality to the minimum necessary. That is why having a generic escape hatch for a large network such as starknet would be really complex to build, however, we can have a escape hatch that with some tweaks is able to adapt itself to different types froo transactions.
+
+ As an extension of what we believe in Starknet: In order to guarantee self custody of funds, thereby preventing censorship, for example StarkEx enables a user to perform a forced request at any point in time. The user initiates a forced request with an on-chain transaction. If you, the operator, do not serve the request within a specific time frame, the user can freeze the contract, and thus the exchange, and withdraw directly from the frozen contract.
+
+ Currently the Starknet public network does not have escape hatches implementations neither the appchains that would conform the Layer 3s. However, possible implementations would likely be inspired by the already battle tested escape hatches in the StarkEx implementation. For example the implementation for a trading platform would support the following forced operations (source https://docs.starkware.co/starkex/spot/shared/README-forced-operations.html):
+
+ * Full Withdrawal
+
+ * Forced Trade
+
+ The flow of the escape hatch is the following although they vary depending on the specific application StarkEx serves. However, in general, there are two possible flows, based on how you, the aplication, respond to the forced request:
+
+ * Option 1: The application serves the forced operation.
+ * Option 2: They do not serve the forced operation.
+
+ The application sends the forced operation to StarkEx and StarkEx decides whether the on-chain request is valid based on the identity of the exact request and the business logic involved. Whether the request is valid or invalid, after the proof for this request is submitted, the request is removed from the pending forced operations area in the StarkEx contract, so it can no longer justify any future request to freeze the contract.
+
+ If the application does not serve the forced operation. in other words, If the freeze grace period has passed, and the forced operation is still in the pending forced operations area, the user can call the freezeRequest function, with the public Stark key and the vault ID they used in the ignored forced operation.
+
+ As a result, the exchange becomes frozen, and it can accept no further state updates. Withdrawals of on-chain funds are still possible.
+
+ The following diagram illustrates the workflow.
+
+ [IMAGE HERE]
+
+ The same flow but in technical terms: The function fullWithdrawalRequest is a part of an anti-censorship mechanism that lets the user withdraw their funds. The user supplies the vault ID and the Stark key. Only the user to whom this Stark key belongs may submit this request. When this function is called, the event LogFullWithdrawalRequest (with the relevant starkKey, vaultId) is emitted.
+ If the application fails to service the request, upon the expiration of a FREEZE_GRACE_PERIOD, the user is entitled to freeze the contract by calling freezeRequest.
+
+ The user supplies the vaultId and the Stark key and indicating the vaultId for which the full withdrawal request has not been serviced. Once the contract is frozen, funds can be extracted using the escape operation. More details on the functions called here https://docs.starkware.co/starkex/spot/in-spot-trading-smart-contracts.html.
+
+
+ Risks with escape hatches
+
+ Escape hatches are delicate components and the less the number of transactions they cover the better. the most common attack a escape hatch could receive are Denial of Services Attacks (DoS). Where attackers spam the network with forced transactions not allowing the application to invalidate or validate all of them in time and thus reaching the freezing of the application. For this The Full Withdrawal function consumes a lot of gas and is expected to be used only as an anticensorship mechanism. This works to prevent spamming as much as possible. To avoid the potential attack of the application by a flood of full withdrawal requests, the rate of such requests must be limited. In the current implementation, this is achieved by making the request’s cost exceed 1M gas.
+
+ A generic enough escape hatch is a really complicated task if we want to preserve security. This would work kind of for a public network like the whole starknet layer 2. However, once Starknet is fully decentralized the escape hatch would not be needed anymore (likely). However, for the appchains, the escape hatch would be needed. The escape hatch would be needed for the appchains because they might not be fully decentralized.
+
+ Design for Appchains
+ [image from slides]
+ Since it is an appchain, they are running a sequencer. On the top right part of the slide you can see there is the starknet app chain. The network has two contracts: the Forc Tx Handler and the Balance Calculator. In the middle we have a Escape Tool using Madara and Stone.
+
+
+ Lets see the different cases:
+ A user wants to make a forced transaction (only two types: forced withdrawal or forced trade) to the transaction queue. They send the transaction trough the layer 1 so theoritically it can not be censored. The forced transaction queue stores the transaction and sends it as a L1 to L2 message.
+ Then if the message is not consumed within for example 7 days the user uses the forced transaction queue to start a freeze to the Starknet Core contract. which means the L1 will not receiving any state updates from L2 anymore. So you have effectively frozen the application. This is a big penalty not serving the transaction in teh transaction queue from the appchain.
+ Then the user suses an offchain tool taht is using madara sequcener and Stone prover. The Madara sequencer will sync up from the L1 from the last state update and then use the balance calculator contract which says how you calculate your remaining balance from the last state update. You can calulate your balance then create a proof using stone of funds whatever your balance is, gives it to the verifier whichverifies it, theen submit that proof to the verufier which will create a fact and then you can withdraw your money from the bridge. This only happens if the appchain is frozen. If the appchain is not frozen then you can not withdraw your money. This is the escape hatch for the appchain. Everyone can escape their funds from the frozen app.
+
+# Handling Forced Transactions in Appchain
+
+Forced transactions include two types: forced withdrawals and forced trades.
+
+## Process Flow
+
+1. **Initiating a Forced Transaction:**
+
+ - The user sends a forced transaction (withdrawal or trade) through Layer 1 (L1), theoretically avoiding censorship.
+ - The forced transaction queue receives and stores this transaction, then forwards it as an L1 to Layer 2 (L2) message.
+
+2. **Transaction Queue and Starknet Core Contract:**
+
+ - If the transaction remains unconsumed for a set period (e.g., 7 days), the user initiates a freeze on the Starknet Core contract via the forced transaction queue.
+ - This freeze stops all state updates from L2 to L1, effectively freezing the application. It's a significant penalty for not processing transactions in the appchain's queue.
+
+3. **Using Offchain Tools for Balance Calculation and Proof Submission:**
+
+ - In case of a freeze, the user employs an offchain tool that uses the Madara Sequencer and Stone Prover.
+ - The Madara Sequencer syncs up with the last L1 state update.
+ - The user then utilizes the Balance Calculator Contract to determine their remaining balance from the last state update.
+ - After calculating the balance, the user creates a proof of funds using Stone, which is verified by the verifier.
+ - The verified proof is then submitted to the verifier, which generates a fact, allowing the user to withdraw funds from the bridge.
+
+4. **Withdrawal Conditions:**
+ - Withdrawals are only permissible if the appchain is frozen.
+ - If the appchain is operational, fund withdrawal is not possible.
+ - This mechanism serves as an escape hatch, enabling users to retrieve funds from a frozen appchain.
+
+### Approaches to Ensuring Censorship Resistance
+
+#### Decentralization as a Long-term Strategy
+
+- **Goal:** Increase the number of sequencers to diversify network validation, substantially reducing censorship risks.
+- **Challenge:** Achieving decentralization involves complex incentive structures and strategic planning.
+- **2024 Focus:** StarkNet aims to make the operation of the system permissionless, inviting a wider range of participants and thereby reducing potential points of control or censorship.
+
+#### Escape Hatches for Immediate Solutions
+
+- **Purpose:** Provide a mechanism for users to transfer assets back to Ethereum in case of censorship or operational failures in StarkNet.
+- **Design Considerations:** These mechanisms must balance between security and complexity, covering only essential transactions to mitigate risk.
+- **Implementation Examples:** StarkEx showcases a model where users can initiate forced operations, such as Full Withdrawal or Forced Trade. If these requests are ignored, users can freeze the contract and withdraw assets directly.
+
+## Escape Hatch Workflow in StarkEx Applications
+
+The escape hatch flow in StarkEx applications varies, but generally follows two possible scenarios based on the application's response to a forced request:
+
+- **Option 1**: The application serves the forced operation.
+- **Option 2**: The application does not serve the forced operation.
+
+This is the workflow:
+
+1. **Initial Request**: The application sends the forced operation to StarkEx. StarkEx then assesses the on-chain request's validity based on the specific request identity and underlying business logic.
+
+2. **Request Processing**:
+
+ - If valid or invalid, once proof for this request is submitted, it's removed from the pending forced operations area in the StarkEx contract. This prevents it from justifying any future contract freeze requests.
+
+3. **Non-Service of Operation**:
+
+ - If the application doesn't serve the forced operation and the freeze grace period expires with the operation still pending, the user can activate the `freezeRequest` function using their public Stark key and the relevant vault ID from the ignored forced operation.
+
+4. **Result of Freeze Request**:
+
+ - Triggering this function freezes the exchange, halting state updates. Withdrawals of on-chain funds remain possible.
+
+5. **Workflow Illustration**:
+ - [IMAGE HERE]
+
+Technically this is what happens:
+
+- **`fullWithdrawalRequest` Function**: Part of an anti-censorship mechanism, it allows users to withdraw funds by providing their vault ID and Stark key. This request is exclusive to the Stark key owner.
+ - On invocation, the event `LogFullWithdrawalRequest` is emitted with the relevant starkKey and vaultId.
+- **Contract Freeze**: If the application fails to service the request within the `FREEZE_GRACE_PERIOD`, the user can freeze the contract by calling `freezeRequest`.
+
+ - The user indicates the vaultId and Stark key for the unattended full withdrawal request. Once frozen, funds can be extracted using the escape operation.
+
+- For more details on the functions involved, visit [Starkware Documentation](https://docs.starkware.co/starkex/spot/in-spot-trading-smart-contracts.html).
+
+## Risks with Escape Hatches
+
+- **Nature of Risk**: Escape hatches are sensitive components, best suited for a minimal number of transactions.
+- **Common Attack - DoS**: Attackers may spam the network with forced transactions, preventing the application from processing them in time, leading to a freeze.
+ - **Mitigation**: The Full Withdrawal function consumes substantial gas (over 1M) to deter spamming and is intended solely as an anti-censorship measure.
+
+### Managing Risks in the Transition to Decentralization
+
+StarkNet's journey involves carefully managing various risks:
+
+- **Censorship Risks:** Centralized control of transaction processing can lead to censorship, which StarkNet aims to mitigate through decentralization and escape hatches.
+- **Security Risks in Escape Hatches:** Escape hatches, while crucial for user autonomy, are susceptible to Denial of Service (DoS) attacks. StarkNet mitigates this by imposing high gas costs for operations like Full Withdrawal, deterring frivolous or malicious requests.
+- **Complexity and User Experience:** Balancing the technical complexity of escape hatches and the user experience is critical. StarkNet's approach involves implementing mechanisms that are secure yet user-friendly, ensuring that users can exercise their rights without unnecessary complexity.
+
+In conclusion, StarkNet's path towards a decentralized and censorship-resistant ecosystem involves addressing security challenges, implementing effective escape hatches, and carefully managing the transition to ensure user empowerment and network integrity.
+
+## Case Study - FinTech Ventures Inc.
+
+FinTech Ventures Inc., a fintech startup, offers a high-speed trading platform designed for professional traders and financial institutions. It stands out for its reliability, speed, and sophisticated features.
+
+FinTech Ventures Inc. recognizes the benefits of decentralization but limits its engagement in the process. The company focuses on:
+
+- **Self-Custody and Non-Censorship**: Ensuring platform users retain control over their funds and that transactions are uncensored.
+- **Business Profitability**: As a startup, the priority is generating revenue and building a profitable business, rather than diverting resources to decentralize through token creation, economic incentives, or consensus mechanisms.
+
+### Adopting Escape Hatches
+
+In line with these priorities, FinTech Ventures Inc. implements escape hatches in their platform. This choice allows them to claim non-censorship and self-custody without fully embracing decentralization.
+
+The escape hatch mechanism includes:
+
+- **Forced Operations**: Supports critical operations like Full Withdrawal and Forced Trade, allowing users to maintain control over their assets.
+- **Operation Flow**:
+ - _Option 1_: User-initiated operations (e.g., withdrawals) are processed normally.
+ - _Option 2_: If not processed timely, users can freeze the contract, halting all platform operations.
+- **Security and Implementation**: Escape hatches are designed to focus on critical transactions, enhancing security and reducing attack risks.
+
+## Risks and Mitigation
+
+- **Denial of Service (DoS) Attacks**: The Full Withdrawal function requires high gas consumption to prevent frivolous requests.
+- **Rate Limiting**: The platform limits the rate of full withdrawal requests to prevent system overload and maintain stability.
+
+This way, FinTech Ventures Inc. effectively integrates escape hatches, balancing self-custody and non-censorship with business goals. This strategy enhances profitability and user satisfaction, while providing security and autonomy for users.
+
+Imagine you're playing a game where you have a special mailbox (the application inbox on Layer 1, or L1). Now, your game (the Layer 2, or L2 contract) runs smoothly as long as this mailbox is empty. But if someone puts a letter (a pending transaction) in your mailbox and you don't deal with it, your game pauses. It's like a "freeze" button gets hit.
+
+Your game knows when to pause because it's constantly getting little "hello" notes (keepalive messages) from your mailbox. If these notes stop coming, it means there's an unhandled letter waiting, and it's time to pause the game.
+
+Sounds simple, right? But here's the catch. First, it makes the whole gaming system more complicated. Imagine every player's game could pause anytime. They would need to plan for this, making everything more complex. For example, if you're trading in-game items (like DAI contracts on Uniswap), and suddenly your game pauses, everyone else must adapt or pretend it didn't happen, ignoring the potential problem of being censored.
+
+Secondly, this system works only if the person controlling the game (the operator) has your best interests at heart. What if they don't? Suppose a powerful player (like a law enforcement agency) tells the game controller to ignore your letter on purpose. Just by doing that, they can pause your game. So, it's not foolproof.
+
+With Cairo 0 that was the mainw ay to create Starknet code until February 2023, you were not able to prove invalid transactions which makes them indistinguisahable from censored transactions. In other words: It is impossible to distinguish between censorship (when a sequencer purposefully decides not to include certain transactions) and invalid transactions since both types of transactions will not be included in blocks.
+
+Soundness ensures that valid transactions are not rejected, preventing censorship. this is needed to be achieved or takled by starknet.
diff --git a/src/img/ch02-13-cairo-fuzzer.png b/src/img/ch02-cairo-fuzzer.png
similarity index 100%
rename from src/img/ch02-13-cairo-fuzzer.png
rename to src/img/ch02-cairo-fuzzer.png
diff --git a/src/img/ch02-13-sec_over_felt.png b/src/img/ch02-sec_over_felt.png
similarity index 100%
rename from src/img/ch02-13-sec_over_felt.png
rename to src/img/ch02-sec_over_felt.png
diff --git a/src/img/ch02-13-sec_over_u128.png b/src/img/ch02-sec_over_u128.png
similarity index 100%
rename from src/img/ch02-13-sec_over_u128.png
rename to src/img/ch02-sec_over_u128.png
diff --git a/src/img/ch02-13-sec_over_u256.png b/src/img/ch02-sec_over_u256.png
similarity index 100%
rename from src/img/ch02-13-sec_over_u256.png
rename to src/img/ch02-sec_over_u256.png
diff --git a/src/img/ch02-13-sec_priv01.png b/src/img/ch02-sec_priv01.png
similarity index 100%
rename from src/img/ch02-13-sec_priv01.png
rename to src/img/ch02-sec_priv01.png
diff --git a/src/img/ch02-13-sec_priv02.png b/src/img/ch02-sec_priv02.png
similarity index 100%
rename from src/img/ch02-13-sec_priv02.png
rename to src/img/ch02-sec_priv02.png
diff --git a/src/img/ch02-13-sec_priv03.png b/src/img/ch02-sec_priv03.png
similarity index 100%
rename from src/img/ch02-13-sec_priv03.png
rename to src/img/ch02-sec_priv03.png
diff --git a/src/img/ch02-13-sec_under_u128.png b/src/img/ch02-sec_under_u128.png
similarity index 100%
rename from src/img/ch02-13-sec_under_u128.png
rename to src/img/ch02-sec_under_u128.png
diff --git a/src/img/ch02-13-sec_under_u256.png b/src/img/ch02-sec_under_u256.png
similarity index 100%
rename from src/img/ch02-13-sec_under_u256.png
rename to src/img/ch02-sec_under_u256.png
diff --git a/src/img/ch02-13-thoth.png b/src/img/ch02-thoth.png
similarity index 100%
rename from src/img/ch02-13-thoth.png
rename to src/img/ch02-thoth.png