Skip to content

Commit

Permalink
Merge pull request #682 from Mosamorphing/quat-branch
Browse files Browse the repository at this point in the history
  • Loading branch information
AmazingAng committed Mar 21, 2024
2 parents 0106a84 + 9b44b43 commit 8374775
Show file tree
Hide file tree
Showing 15 changed files with 69 additions and 69 deletions.
2 changes: 1 addition & 1 deletion Languages/en/41_WETH_en/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ Deploy the `WETH` contract as shown in the image.

### 2. Execute `deposit` to deposit `1 ETH`, and check the `WETH` balance

Execute `deposit` function to deposit `1 ETH`, and check the `WETH` balance.
Execute the `deposit` function to deposit `1 ETH`, and check the `WETH` balance.

![WETH](./img/41-3.jpg)

Expand Down
16 changes: 8 additions & 8 deletions Languages/en/42_PaymentSplit_en/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ All codes and tutorials are open-sourced on Github: [github.com/AmazingAng/WTFSo

---

In this lecture, we'll introduce the payment splitting contract, which allows the transfer of `ETH` to a group of accounts according to their respective weights for payment splitting purposes. The code section is a simplification of the PaymentSplitter contract provided by the OpenZeppelin library, which can be found on [Github](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/finance/PaymentSplitter.sol).
In this lecture, we'll introduce the payment-splitting contract, which allows the transfer of `ETH` to a group of accounts according to their respective weights for payment-splitting purposes. The code section is a simplification of the PaymentSplitter contract provided by the OpenZeppelin library, which can be found on [Github](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/finance/PaymentSplitter.sol).

## Payment Split

Expand All @@ -30,9 +30,9 @@ Payment split is the act of dividing money according to a certain ratio. In real
The Payment Split contract (`PaymentSplit`) has the following features:

1. When creating the contract, the beneficiaries `payees` and their share `shares` are predetermined.
2. The shares can be equal or in any other proportions.
3. From all the ETH that the contract receives, each beneficiary is able to withdraw the amount proportional to their allocated share.
4. The Payment Split contract follows the `Pull Payment` pattern, where payments are not automatically transferred to the account, but are kept in the contract. Beneficiaries trigger the actual transfer by calling the `release()` function.
2. The shares can be equal or in any other proportion.
3. From all the ETH that the contract receives, each beneficiary can withdraw the amount proportional to their allocated share.
4. The Payment Split contract follows the `Pull Payment` pattern, where payments are not automatically transferred to the account but are kept in the contract. Beneficiaries trigger the actual transfer by calling the `release()` function.

```solidity
// SPDX-License-Identifier: MIT
Expand Down Expand Up @@ -62,7 +62,7 @@ There are a total of `3` events in the Splitter Contract:

### State Variables

There are `5` state variables in the revenue splitting contract, used to record beneficiary addresses, shares, and paid out `ETH`:
There are `5` state variables in the revenue-splitting contract, used to record beneficiary addresses, shares, and paid-out `ETH`:

- `totalShares`: Total shares, which is the sum of `shares`.
- `totalReleased`: The amount of `ETH` paid out from the revenue splitting contract to beneficiaries, which is the sum of `released`.
Expand All @@ -81,7 +81,7 @@ There are `5` state variables in the revenue splitting contract, used to record

### Functions

There are `6` functions in the revenue sharing contract:
There are `6` functions in the revenue-sharing contract:

- Constructor: initializes the beneficiary array `_payees` and the revenue sharing array `_shares`, where the length of both arrays must not be 0 and their lengths must be equal. Elements of the \_shares array must be greater than 0, and the addresses in the \_payees array can't be the zero address and can't have a duplicate address.
- `receive()`: callback function, releases the `PaymentReceived` event when the revenue sharing contract receives `ETH`.
Expand Down Expand Up @@ -203,7 +203,7 @@ In the constructor, enter two beneficiary addresses with shares of `1` and `3`.

![Viewing the second beneficiary](./img/42-4.png)

### 3. Call `release` function to claim `ETH`
### 3. Call the `release` function to claim `ETH`

![Calling the release function](./img/42-5.png)

Expand All @@ -213,4 +213,4 @@ In the constructor, enter two beneficiary addresses with shares of `1` and `3`.

## Summary

In this lecture, we introduced the revenue sharing contract. In the world of blockchain, `Code is Law`, we can write the proportion that each person should receive in the smart contract beforehand. After receiving revenue, the smart contract will handle revenue sharing to avoid the issue of "unequal distribution of shares" afterwards.
In this lecture, we introduced the revenue-sharing contract. In the world of blockchain, `Code is Law`, we can write the proportion that each person should receive in the smart contract beforehand. After receiving revenue, the smart contract will handle revenue sharing to avoid the issue of "unequal distribution of shares" afterwards.
2 changes: 1 addition & 1 deletion Languages/en/43_TokenVesting_en/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,4 +150,4 @@ There are `3` functions in the LinearVesting contract.

## Summary

A large amount of token unlocking in the short term can cause huge pressure on the token price, while agreed-upon token ownership terms can alleviate selling pressure and prevent the team and capital parties from exiting too early. In this lesson, we introduced token ownership terms and wrote a contract for linear release of ERC20 tokens.
A large amount of token unlocking in the short term can cause huge pressure on the token price, while agreed-upon token ownership terms can alleviate selling pressure and prevent the team and capital parties from exiting too early. In this lesson, we introduced token ownership terms and wrote a contract for the linear release of ERC20 tokens.
4 changes: 2 additions & 2 deletions Languages/en/44_TokenLocker_en/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Feel free to follow me on Twitter: [@0xAA_Science](https://twitter.com/0xAA_Scie

You are also welcome to join the WTF Scientists community and find information on how to join the WeChat group: [link](https://discord.gg/5akcruXrsk)

All of the code and tutorials are open source and can be found on Github (I will provide a course certification for 1024 stars and a community NFT for 2048 stars): [github.com/AmazingAng/WTFSolidity](https://github.com/AmazingAng/WTFSolidity)
All of the code and tutorials are open source and can be found on GitHub (I will provide a course certification for 1024 stars and a community NFT for 2048 stars): [github.com/AmazingAng/WTFSolidity](https://github.com/AmazingAng/WTFSolidity)

---

Expand All @@ -23,7 +23,7 @@ A Token Lock is a simple time-based smart contract that allows one to lock a num

### What are LP Tokens?

In decentralized exchanges (DEX), users trade tokens, such as in the case of Uniswap. Unlike centralized exchanges (CEX), decentralized exchanges use Automated Market Maker (AMM) mechanisms. Users or projects provide a liquidity pool, so that other users can buy and sell tokens instantly. To compensate the user or project for providing the liquidity pool, the DEX will mint corresponding LP tokens, which represent their contribution and entitle them to transaction fees.
In decentralized exchanges (DEX), users trade tokens, such as in the case of Uniswap. Unlike centralized exchanges (CEX), decentralized exchanges use Automated Market Maker (AMM) mechanisms. Users or projects provide a liquidity pool so that other users can buy and sell tokens instantly. To compensate the user or project for providing the liquidity pool, the DEX will mint corresponding LP tokens, which represent their contribution and entitle them to transaction fees.

### Why Lock Liquidity?

Expand Down
10 changes: 5 additions & 5 deletions Languages/en/46_ProxyContract_en/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Is there a way to modify or upgrade the contract after it is deployed? The answe

![Proxy Pattern](./img/46-1.png)

The proxy pattern separates contract data and logic, and saves them in different contracts. Taking the simple proxy contract in the above figure as an example, the data (state variable) is stored in the proxy contract, and the logic (function) is stored in another logic contract. The proxy contract (Proxy) delegates the function call to the logic contract (Implementation) through `delegatecall`, and then returns the final result to the caller(Caller).
The proxy pattern separates contract data and logic and saves them in different contracts. Taking the simple proxy contract in the above figure as an example, the data (state variable) is stored in the proxy contract, and the logic (function) is stored in another logic contract. The proxy contract (Proxy) delegates the function call to the logic contract (Implementation) through `delegatecall`, and then returns the final result to the caller(Caller).

The proxy pattern has two main benefits:
1. Upgradeable: When we need to upgrade the logic of the contract, we only need to point the proxy contract to a new logic contract.
Expand Down Expand Up @@ -77,8 +77,8 @@ The fallback function of `Proxy` delegates external calls to the `Logic` contrac

```solidity
/**
* @dev fallback function, delegates invocations of current contract to `implementation` contract
* with inline assembly, it gives fallback function a return value
* @dev fallback function, delegates invocations of the current contract to `implementation` contract
* with inline assembly, it gives the fallback function a return value
*/
fallback() external payable {
address _implementation = implementation;
Expand All @@ -87,7 +87,7 @@ fallback() external payable {
// the parameters of opcode calldatacopy: start position of memory, start position of calldata, length of calldata
calldatacopy(0, 0, calldatasize())
// use delegatecall to call implementation contract
// use delegatecall to call the implementation contract
// the parameters of opcode delegatecall: gas, target contract address, start position of input memory, length of input memory, start position of output memory, length of output memory
// set start position of output memory and length of output memory to 0
// delegatecall returns 1 if success, 0 if fail
Expand Down Expand Up @@ -199,4 +199,4 @@ The question we left for everyone earlier was: why does a call to `increment()`

In the next lesson, we will introduce upgradeable proxy contracts.

Although the proxy contract is very powerful, it is prone to bugs. When using it, you'd better directly copy the template contract from [OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts/tree/master/contracts/proxy).
Although the proxy contract is very powerful, it is prone to bugs. When using it, you'd better directly copy the template contract from [OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts/tree/master/contracts/proxy).
12 changes: 6 additions & 6 deletions Languages/en/47_Upgrade_en/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,14 @@ It contains `3` functions:

- Constructor: Initializes admin and logic contract addresses.
- `fallback()`: Callback function, delegates the call to the logic contract.
- `upgrade()`: Upgrade function, changes the logic contract's address, can only be called by `admin`.
- `upgrade()`: The upgrade function, changes the logic contract's address, and can only be called by `admin`.

```solidity
// SPDX-License-Identifier: MIT
// wtf.academy
pragma solidity ^0.8.21;
// simple upgradeable contract, the admin could change the logic contract's address by calling upgrade function, thus change the contract logic
// simple upgradeable contract, the admin could change the logic contract's address by calling the upgrade function, thus changing the contract logic
// FOR TEACHING PURPOSE ONLY, DO NOT USE IN PRODUCTION
contract SimpleUpgrade {
// logic contract's address
Expand All @@ -60,7 +60,7 @@ contract SimpleUpgrade {
// admin address
address public admin;
// string variable, could be changed by logic contract's function
// string variable, could be changed by the logic contract's function
string public words;
// constructor, initializing admin address and logic contract's address
Expand All @@ -74,7 +74,7 @@ contract SimpleUpgrade {
(bool success, bytes memory data) = implementation.delegatecall(msg.data);
}
// upgrade function, changes the logic contract's address, can only by called by admin
// upgrade function, changes the logic contract's address, can only be called by admin
function upgrade(address newImplementation) external {
require(msg.sender == admin);
implementation = newImplementation;
Expand Down Expand Up @@ -109,7 +109,7 @@ This logic contract contains `3` state variables, consistent with the proxy cont
```solidity
// Logic Contract 2
contract Logic2 {
// State variables consistent with proxy contract to prevent slot collisions
// State variables consistent with a proxy contract to prevent slot collisions
address public implementation;
address public admin;
// String that can be changed through the function of the logic contract
Expand Down Expand Up @@ -142,4 +142,4 @@ contract Logic2 {

## Summary

In this lesson, we introduced a simple upgradeable contract. It is a proxy contract that can change the logic contract and adds upgrade functionality to immutable smart contracts. However, this contract has a problem of selector conflict and poses security risks. Later, we will introduce the upgradeable contract standards that solve this vulnerability: Transparent Proxy and UUPS.
In this lesson, we introduced a simple upgradeable contract. It is a proxy contract that can change the logic contract and add upgrade functionality to immutable smart contracts. However, this contract has a problem of selector conflict and poses security risks. Later, we will introduce the upgradeable contract standards that solve this vulnerability: Transparent Proxy and UUPS.
20 changes: 10 additions & 10 deletions Languages/en/48_TransparentProxy_en/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ In this lesson, we will introduce the selector clash issue in proxy contracts, a

## Selector Clash

In smart contracts, a function selector is the hash of a function signature's first 4 bytes. For example, the selector of function `mint(address account)` is `bytes4(keccak256("mint(address)"))`, which is `0x6a627842`. More about function selectors see [WTF Solidity Tutorial #29: Function Selectors](https://github.com/AmazingAng/WTFSolidity/blob/main/Languages/en/29_Selector_en/readme.md).
In smart contracts, a function selector is the hash of a function signature's first 4 bytes. For example, the selector of function `mint(address account)` is `bytes4(keccak256("mint(address)"))`, which is `0x6a627842`. For more about function selectors see [WTF Solidity Tutorial #29: Function Selectors](https://github.com/AmazingAng/WTFSolidity/blob/main/Languages/en/29_Selector_en/readme.md).

Because a function selector has only 4 bytes, its range is very small. Therefore, two different functions may have the same selector, such as the following two functions:

Expand All @@ -46,7 +46,7 @@ Currently, there are two upgradeable contract standards that solve this problem:
The logic of the transparent proxy is very simple: admin may mistakenly call the upgradable functions of the proxy contract when calling the functions of the logic contract because of the "selector clash". Restricting the admin's privileges can solve the conflict:

- The admin becomes a tool person and can only upgrade the contract by calling the upgradable function of the proxy contract, without calling the fallback function to call the logic contract.
- Other users cannot call upgradable function, but can call functions of the logic contract.
- Other users cannot call the upgradable function but can call functions of the logic contract.

### Proxy Contract

Expand Down Expand Up @@ -102,27 +102,27 @@ The new and old logic contracts here are the same as in [Lecture 47](https://git
```solidity
// old logic contract
contract Logic1 {
// state variable should be the same as proxy contract, in case of slot clash
// state variable should be the same as a proxy contract, in case of slot clash
address public implementation;
address public admin;
// string variable, can be modified by calling loginc contract's function
// string variable, can be modified by calling the logic contract's function
string public words;
// to change state variable in proxy contract, selector 0xc2985578
//To change state variable in proxy contract, selector 0xc2985578
function foo() public{
words = "old";
}
}
// new logic contract
contract Logic2 {
// state variable should be the same as proxy contract, in case of slot clash
// state variable should be the same as a proxy contract, in case of slot clash
address public implementation;
address public admin;
// string variable, can be modified by calling loginc contract's function
// string variable, can be modified by calling the logic contract's function
string public words;
// to change state variable in proxy contract, selector 0xc2985578
//To change state variable in proxy contract, selector 0xc2985578
function foo() public{
words = "new";
}
Expand Down Expand Up @@ -152,6 +152,6 @@ contract Logic2 {

## Summary

In this lesson, we introduced the "selector clash" in proxy contracts and how to avoid this problem using transparent proxy. The logic of transparent proxy is simple, solving the "selector clash" problem by restricting the admin's access to the logic contract. However, it has a drawback that every time a user calls a function, there is an additional check for whether or not the caller is the admin, which consumes more gas. Nevertheless, transparent proxy are still the solution chosen by most project teams.
In this lesson, we introduced the "selector clash" in proxy contracts and how to avoid this problem using a transparent proxy. The logic of transparent proxy is simple, solving the "selector clash" problem by restricting the admin's access to the logic contract. However, it has a drawback; every time a user calls a function, there is an additional check for whether or not the caller is the admin, which consumes more gas. Nevertheless, transparent proxies are still the solution chosen by most project teams.

In the next lesson, we will introduce the general Universal Upgradeable Proxy Standard (UUPS), which is more complex but consumes less gas.
In the next lesson, we will introduce the general Universal Upgradeable Proxy Standard (UUPS), which is more complex but consumes less gas.
Loading

0 comments on commit 8374775

Please sign in to comment.