# **CrytoCamp Homework3** ###### tags: `Solidity` ## 1. <基礎作業> 1. 透過 remix JavaScript VM 部署合約 2. 部署任一自訂 ERC20 Token 3. 部署質押合約 - Deposit(存入) - Reward(回饋) - TimeLock(固定鎖倉期) ### ERC20 ```solidity= // contracts/GLDToken.sol // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; contract MyToken is ERC20 { constructor() ERC20("MyToken", "MT") { _mint(msg.sender, 100000); } } ``` ### Bank ```solidity= // contracts/GLDToken.sol // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; contract Bank { IERC20 public stakingToken; mapping(address => uint256) public balanceOf; // 池中總量 uint256 public totalSupply; // 鎖倉時間 uint256 public lockRcord; mapping(address => uint256) public lockStartOf; mapping(address => uint256) public lockEndOf; // 獎勵 uint256 public rewardRate = 1; mapping(address => uint256) public rewardOf; constructor(IERC20 _stakingToken) { stakingToken = _stakingToken; } // 質押 function deposit(uint256 _amount, uint256 _lockTime) external { require(_lockTime > 5, "Please enter a longer time"); lockRcord = _lockTime; stakingToken.transferFrom(msg.sender, address(this), _amount); // 轉移代幣 totalSupply += _amount; // 紀錄質押數量 balanceOf[msg.sender] += _amount; // 紀錄個人質押數量 // 紀錄鎖倉時間 lockStartOf[msg.sender] = block.timestamp; lockEndOf[msg.sender] = block.timestamp + _lockTime; } // 贖回 function withdraw(uint256 _amount) public { require(block.timestamp > lockEndOf[msg.sender], "withdraw too soon"); require(_amount <= balanceOf[msg.sender], "insufficient token"); // 獲得獎勵 rewardOf[msg.sender] += getReward(); stakingToken.transfer(msg.sender, _amount); totalSupply -= _amount; balanceOf[msg.sender] -= _amount; } // 獎勵 function getReward() public view returns (uint256) { uint256 duration = block.timestamp - lockStartOf[msg.sender]; //Rewaord scale if (lockRcord <= 20) { return duration * (rewardRate * 5) * balanceOf[msg.sender]; }else if (lockRcord > 20 && lockRcord <= 40) { return duration * (rewardRate * 10) * balanceOf[msg.sender]; }else { return duration * (rewardRate * 20) * balanceOf[msg.sender]; } } } ``` ### 功能說明 存入時需要輸入存放金額與時間 一開始決定存放的時間,會影響到結算Reward金額 ## 2. <進階作業> ### ERC20 ```solidity= // contracts/GLDToken.sol // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; contract MyToken is ERC20 { constructor() ERC20("MyToken", "MT") { _mint(msg.sender, 100000); } } ``` ### 會找時間補上 X﹏X ## 3. <進階作業> ### ERC20 ```solidity= // contracts/GLDToken.sol // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; contract MyToken is ERC20 { constructor() ERC20("MyToken", "MT") { _mint(msg.sender, 100000); } } ``` ### 會找時間補上 X﹏X