From 692344235307c1b5b76ee95603d3702446c72315 Mon Sep 17 00:00:00 2001 From: eiyen <937915771@qq.com> Date: Mon, 17 Apr 2023 12:27:52 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=A0=E9=99=A4=E4=BA=86=E4=B8=8D=E9=9C=80?= =?UTF-8?q?=E8=A6=81=E7=9A=84=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- W3-1/contracts/MyToken.sol | 21 ------ W3-1/contracts/Recipient.sol | 10 --- W3-1/contracts/TokenVault.sol | 68 ------------------- W3-2/contracts/MyToken.sol | 14 ---- W3-2/contracts/MyTokenWithCallback.sol | 25 ------- W3-2/contracts/TokenVault.sol | 33 --------- W3-2/contracts/TokenVaultWithCallback.sol | 43 ------------ .../TokenVaultWithCallbackAndMigration.sol | 52 -------------- 8 files changed, 266 deletions(-) delete mode 100644 W3-1/contracts/MyToken.sol delete mode 100644 W3-1/contracts/Recipient.sol delete mode 100644 W3-1/contracts/TokenVault.sol delete mode 100644 W3-2/contracts/MyToken.sol delete mode 100644 W3-2/contracts/MyTokenWithCallback.sol delete mode 100644 W3-2/contracts/TokenVault.sol delete mode 100644 W3-2/contracts/TokenVaultWithCallback.sol delete mode 100644 W3-2/contracts/TokenVaultWithCallbackAndMigration.sol diff --git a/W3-1/contracts/MyToken.sol b/W3-1/contracts/MyToken.sol deleted file mode 100644 index 98d6457..0000000 --- a/W3-1/contracts/MyToken.sol +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.9; - -import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; -import "./Recipient.sol"; - -contract MyToken is ERC20 { - constructor() ERC20("MyToken", "MTK") { - _mint(msg.sender, 1000 * 10 ** decimals()); - } - - /** - * @dev 添加 transfer with callback 功能 - * @notice 无需通过 IERC777Recipient 接口实现该功能, - * 因为接口要求函数传入 Data 等参数,在直接调用函数的场景下并不友好。 - */ - function transferWithCallback(address recipient, uint256 amount) external { - transfer(recipient, amount); - require(Recipient(recipient).tokensReceived(msg.sender, amount), "Callback function failed"); - } -} \ No newline at end of file diff --git a/W3-1/contracts/Recipient.sol b/W3-1/contracts/Recipient.sol deleted file mode 100644 index b0f8804..0000000 --- a/W3-1/contracts/Recipient.sol +++ /dev/null @@ -1,10 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.9; - -/** - * @dev Recipient 接口是通过回调函数,来实现在无需授权的情况下,完成向目标合约的转账和记录。 - * 其效果类似于 ERC777Recipient 接口,但是所需参数更加简洁,方便开发者直接调用函数。 - */ -interface Recipient { - function tokensReceived(address sender, uint256 amount) external returns(bool); -} \ No newline at end of file diff --git a/W3-1/contracts/TokenVault.sol b/W3-1/contracts/TokenVault.sol deleted file mode 100644 index add6c81..0000000 --- a/W3-1/contracts/TokenVault.sol +++ /dev/null @@ -1,68 +0,0 @@ -// SPDX-License-Identifier: MIT - -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import "./Recipient.sol"; - -pragma solidity ^0.8.9; - -contract TokenVault is Recipient { - mapping(address => uint256) private _balances; - IERC20 private _token; - - constructor(address tokenAddress) { - _token = IERC20(tokenAddress); - } - - /** - * TODO: - * 1. 实现 deposit 函数,能够更新 _balances,使用 transferFrom 函数转账,并检查转账是否成功。 - * 2. 实现 withdraw 函数,能够检查目标地址是否合法,更新 _balances,使用 transfer 函数转账,并检查转账是否成功。 - * 3. 实现 balanceOf 函数,能够返回指定地址的余额 - * 4. 实现 token 函数,能够返回 _token 代币的地址 - * 5. 实现 onTokenTransfer 回调函数,能够在接收 ERC20 代币的转账后,更新 _balances - */ - - /** - * NOTE: - * - * 目的:比较 external 和 public 可见性的差异 - * - * 场景:仅有用户调用函数 - * - * 作用: - * - external: 在外部调用时,会产生更少的 gas 费用。 - * - public: 在调用时,gas 费用高于 external 的外部调用,低于 external 的内部调用。 - * - * 结论:deposit 函数由于仅需被外部调用,因此使用 external 可见性更加合适。 - */ - - /** - * NOTE: 使用 _msgSender() 调用 msg.sender, 能够在 meta-transaction 也就是代付中,获取正确的用户地址。 - * 但是在当前场景下暂不考虑代付情况,所以 deposit 中直接使用 msg.sender 而非 _msgSender() - */ - - function deposit(uint256 amount) external { - require(_token.transferFrom(msg.sender, address(this), amount), "Failed transaction"); - _balances[msg.sender] += amount; - } - - function withdraw(uint256 amount) external { - require(_balances[msg.sender] >= amount, "Insufficient balance"); - _balances[msg.sender] -= amount; - require(_token.transfer(msg.sender, amount), "Failed transaction"); - } - - function balanceOf() external view returns(uint256) { - return _balances[msg.sender]; - } - - function token() external view returns(address) { - return address(_token); - } - - function tokensReceived(address sender, uint256 amount) external override returns(bool) { - require(msg.sender == address(_token), "Invalid address"); - _balances[sender] += amount; - return true; - } -} \ No newline at end of file diff --git a/W3-2/contracts/MyToken.sol b/W3-2/contracts/MyToken.sol deleted file mode 100644 index 49c6942..0000000 --- a/W3-2/contracts/MyToken.sol +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.9; - -import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; -import "@openzeppelin/contracts/access/Ownable.sol"; -import "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol"; - -contract MyToken is ERC20, Ownable, ERC20Permit { - constructor() ERC20("MyToken", "MTK") ERC20Permit("MyToken") {} - - function mint(address to, uint256 amount) public onlyOwner { - _mint(to, amount); - } -} \ No newline at end of file diff --git a/W3-2/contracts/MyTokenWithCallback.sol b/W3-2/contracts/MyTokenWithCallback.sol deleted file mode 100644 index ced1671..0000000 --- a/W3-2/contracts/MyTokenWithCallback.sol +++ /dev/null @@ -1,25 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.9; - -import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; -import "@openzeppelin/contracts/access/Ownable.sol"; -import "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol"; - -contract MyTokenWithCallback is ERC20, Ownable, ERC20Permit { - constructor() ERC20("MyToken", "MTK") ERC20Permit("MyToken") {} - - function mint(address to, uint256 amount) public onlyOwner { - _mint(to, amount); - } - - // 在不调用Vault合约中deposit函数的情况下,向Vault合约进行转账,同时能让合约记录转账 - function transferWithCallback(address recipient, uint256 amount) external returns (bool) { - require(balanceOf(msg.sender) >= amount, "Insufficient balance"); - require(recipient != address(0), "Invalid recipient address"); - - _transfer(_msgSender(), recipient, amount); - - ICallbackReceiver(msg.sender).onTokenTransfer(msg.sender, recipient, amount); - return true; - } -} \ No newline at end of file diff --git a/W3-2/contracts/TokenVault.sol b/W3-2/contracts/TokenVault.sol deleted file mode 100644 index 95b3335..0000000 --- a/W3-2/contracts/TokenVault.sol +++ /dev/null @@ -1,33 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.9; - -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import "@openzeppelin/contracts/access/Ownable.sol"; - -contract TokenVault is Ownable { - mapping(address => uint256) private _balances; - IERC20 private _token; - - constructor(address tokenAddress) { - _token = IERC20(tokenAddress); - } - - function deposit(uint256 amount) external { - _token.transferFrom(msg.sender, address(this), amount); - _balances[msg.sender] += amount; - } - - function token() public view returns (address) { - return address(_token); - } - - function withdraw(uint256 amount) external { - require(_balances[msg.sender] >= amount, "Insufficient balance"); - _balances[msg.sender] -= amount; - _token.transfer(msg.sender, amount); - } - - function balanceOf(address account) external view returns (uint256) { - return _balances[account]; - } -} diff --git a/W3-2/contracts/TokenVaultWithCallback.sol b/W3-2/contracts/TokenVaultWithCallback.sol deleted file mode 100644 index 01eb3c4..0000000 --- a/W3-2/contracts/TokenVaultWithCallback.sol +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.9; - -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import "@openzeppelin/contracts/access/Ownable.sol"; - -interface ICallbackReceiver { - function onTokenTransfer(address from, address to, uint256 amount) external returns (bool); -} - -contract TokenVaultWithCallback is Ownable { - mapping(address => uint256) private _balances; - IERC20 private _token; - - constructor(address tokenAddress) { - _token = IERC20(tokenAddress); - } - - function deposit(uint256 amount) external { - _token.transferFrom(msg.sender, address(this), amount); - _balances[msg.sender] += amount; - } - - function token() public view returns (address) { - return address(_token); - } - - function withdraw(uint256 amount) external { - require(_balances[msg.sender] >= amount, "Insufficient balance"); - _balances[msg.sender] -= amount; - _token.transfer(msg.sender, amount); - } - - function balanceOf(address account) external view returns (uint256) { - return _balances[account]; - } - - function onTokenTransfer(address from, address to, uint256 amount) external returns (bool) { - require(msg.sender == address(_token), "Invalid token address"); - _balances[to] += amount; - return true; - } -} diff --git a/W3-2/contracts/TokenVaultWithCallbackAndMigration.sol b/W3-2/contracts/TokenVaultWithCallbackAndMigration.sol deleted file mode 100644 index b423338..0000000 --- a/W3-2/contracts/TokenVaultWithCallbackAndMigration.sol +++ /dev/null @@ -1,52 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.9; - -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import "@openzeppelin/contracts/access/Ownable.sol"; - -interface ICallbackReceiver { - function onTokenTransfer(address from, address to, uint256 amount) external returns (bool); -} - -contract TokenVaultWithCallback is Ownable { - mapping(address => uint256) private _balances; - IERC20 private _token; - - constructor(address tokenAddress) { - _token = IERC20(tokenAddress); - } - - function deposit(uint256 amount) external { - _token.transferFrom(msg.sender, address(this), amount); - _balances[msg.sender] += amount; - } - - function token() public view returns (address) { - return address(_token); - } - - function withdraw(uint256 amount) external { - require(_balances[msg.sender] >= amount, "Insufficient balance"); - _balances[msg.sender] -= amount; - _token.transfer(msg.sender, amount); - } - - function balanceOf(address account) external view returns (uint256) { - return _balances[account]; - } - - // 更新的功能,当用户在没有调用 deposit 的情况下进行转账时,自动执行该函数,记录用户转账数额 - function onTokenTransfer(address from, address to, uint256 amount) external returns (bool) { - require(msg.sender == address(_token), "Invalid token address"); - _balances[to] += amount; - return true; - } - - // 数据迁移函数,将原先Vault合约中的金额,全部转移到当前的Vault合约中 - function migrateBalance(TokenVault tokenVault) external { - uint256 balanceToMigrate = tokenVault.balanceOf(msg.sender); - require(balanceToMigrate > 0, "No balance to migrate"); - tokenVault.withdraw(balanceToMigrate); - _balances[msg.sender] += balanceToMigrate; - } -}