Skip to content

Instantly share code, notes, and snippets.

@ChanJuiHuang
Created September 3, 2022 02:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ChanJuiHuang/800a312931d44220fb27ba12b5d1d42e to your computer and use it in GitHub Desktop.
Save ChanJuiHuang/800a312931d44220fb27ba12b5d1d42e to your computer and use it in GitHub Desktop.
// SPDX-License-Identifier: MIT
pragma solidity 0.8.16;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
/*
建立一個 Bank 銀行
在 web3 世界人人都可以當銀行家!我們想開張一間去中心化金融中心,簡易小而美的銀行
使用者可以將我們發行的 Staking Token (ERC20代幣)存入銀行
使用者執行定存,會開始計算 Reward 利息回饋
使用者解除定存(withdraw),獲得 Reward 利息回饋
Deposit 定存:實作 deposit function,可以將 Staking Token 存入 Bank 合約
Withdraw 解除定存並提款,實作 withdraw function
TimeLock 固定鎖倉期
*/
contract BasicBank {
IERC20 public stakingToken;
uint256 public totalSupply;
mapping(address => uint256) public balanceOf;
uint256 public withdrawDeadline = 10 seconds;
uint256 public rewardRate = 1;
mapping (address => uint256) public rewardOf;
struct Deposit {
uint256 amount;
uint256 startTime;
uint256 endTime;
}
mapping (address => Deposit[]) public depositOf;
constructor(IERC20 _stakingToken) {
stakingToken = _stakingToken;
}
function deposit(uint256 _amount) public {
stakingToken.transferFrom(msg.sender, address(this), _amount);
totalSupply = totalSupply + _amount;
balanceOf[msg.sender] = balanceOf[msg.sender] + _amount;
depositOf[msg.sender].push(Deposit({
amount: _amount,
startTime: block.timestamp,
endTime: (block.timestamp + withdrawDeadline)
}));
}
function withdraw(uint256 _index) public {
require(balanceOf[msg.sender] > 0, "You have no balance to withdraw");
Deposit[] storage deposits = depositOf[msg.sender];
require(block.timestamp > deposits[_index].endTime, "End time does not reach");
uint256 amount = deposits[_index].amount;
rewardOf[msg.sender] = rewardOf[msg.sender] + getReward(_index);
stakingToken.transfer(msg.sender, amount);
totalSupply = totalSupply - amount;
balanceOf[msg.sender] = balanceOf[msg.sender] - amount;
deposits[_index] = deposits[deposits.length - 1];
deposits.pop();
}
function getReward(uint256 _index) public view returns(uint256) {
uint256 start = depositOf[msg.sender][_index].startTime;
uint256 amount = depositOf[msg.sender][_index].amount;
return (block.timestamp - start) * rewardRate * amount;
}
function getAllReward() public view returns (uint256) {
uint256 N = depositOf[msg.sender].length;
uint256 allRewards;
for (uint256 i = 0; i < N; i++) {
allRewards += getReward(i);
}
return allRewards;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment