Created
May 26, 2022 03:30
-
-
Save korrio/a7aa71631ddd979dd6cd3f43ee8753fc to your computer and use it in GitHub Desktop.
SimpleBankWithCDGToken.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: MIT | |
pragma solidity ^0.6.0; | |
library SafeMath { | |
/** | |
* @dev Returns the addition of two unsigned integers, reverting on | |
* overflow. | |
* | |
* Counterpart to Solidity's `+` operator. | |
* | |
* Requirements: | |
* - Addition cannot overflow. | |
*/ | |
function add(uint256 a, uint256 b) internal pure returns (uint256) { | |
uint256 c = a + b; | |
require(c >= a, "SafeMath: addition overflow"); | |
return c; | |
} | |
/** | |
* @dev Returns the subtraction of two unsigned integers, reverting on | |
* overflow (when the result is negative). | |
* | |
* Counterpart to Solidity's `-` operator. | |
* | |
* Requirements: | |
* - Subtraction cannot overflow. | |
*/ | |
function sub(uint256 a, uint256 b) internal pure returns (uint256) { | |
require(b <= a, "SafeMath: subtraction overflow"); | |
uint256 c = a - b; | |
return c; | |
} | |
/** | |
* @dev Returns the multiplication of two unsigned integers, reverting on | |
* overflow. | |
* | |
* Counterpart to Solidity's `*` operator. | |
* | |
* Requirements: | |
* - Multiplication cannot overflow. | |
*/ | |
function mul(uint256 a, uint256 b) internal pure returns (uint256) { | |
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the | |
// benefit is lost if 'b' is also tested. | |
// See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 | |
if (a == 0) { | |
return 0; | |
} | |
uint256 c = a * b; | |
require(c / a == b, "SafeMath: multiplication overflow"); | |
return c; | |
} | |
/** | |
* @dev Returns the integer division of two unsigned integers. Reverts on | |
* division by zero. The result is rounded towards zero. | |
* | |
* Counterpart to Solidity's `/` operator. Note: this function uses a | |
* `revert` opcode (which leaves remaining gas untouched) while Solidity | |
* uses an invalid opcode to revert (consuming all remaining gas). | |
* | |
* Requirements: | |
* - The divisor cannot be zero. | |
*/ | |
function div(uint256 a, uint256 b) internal pure returns (uint256) { | |
// Solidity only automatically asserts when dividing by 0 | |
require(b > 0, "SafeMath: division by zero"); | |
uint256 c = a / b; | |
// assert(a == b * c + a % b); // There is no case in which this doesn't hold | |
return c; | |
} | |
/** | |
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), | |
* Reverts when dividing by zero. | |
* | |
* Counterpart to Solidity's `%` operator. This function uses a `revert` | |
* opcode (which leaves remaining gas untouched) while Solidity uses an | |
* invalid opcode to revert (consuming all remaining gas). | |
* | |
* Requirements: | |
* - The divisor cannot be zero. | |
*/ | |
function mod(uint256 a, uint256 b) internal pure returns (uint256) { | |
require(b != 0, "SafeMath: modulo by zero"); | |
return a % b; | |
} | |
} | |
interface IERC20 { | |
/** | |
* @dev Emitted when `value` tokens are moved from one account (`from`) to | |
* another (`to`). | |
* | |
* Note that `value` may be zero. | |
*/ | |
event Transfer(address indexed from, address indexed to, uint256 value); | |
/** | |
* @dev Emitted when the allowance of a `spender` for an `owner` is set by | |
* a call to {approve}. `value` is the new allowance. | |
*/ | |
event Approval(address indexed owner, address indexed spender, uint256 value); | |
/** | |
* @dev Returns the amount of tokens in existence. | |
*/ | |
function totalSupply() external view returns (uint256); | |
/** | |
* @dev Returns the amount of tokens owned by `account`. | |
*/ | |
function balanceOf(address account) external view returns (uint256); | |
/** | |
* @dev Moves `amount` tokens from the caller's account to `to`. | |
* | |
* Returns a boolean value indicating whether the operation succeeded. | |
* | |
* Emits a {Transfer} event. | |
*/ | |
function transfer(address to, uint256 amount) external returns (bool); | |
/** | |
* @dev Returns the remaining number of tokens that `spender` will be | |
* allowed to spend on behalf of `owner` through {transferFrom}. This is | |
* zero by default. | |
* | |
* This value changes when {approve} or {transferFrom} are called. | |
*/ | |
function allowance(address owner, address spender) external view returns (uint256); | |
/** | |
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens. | |
* | |
* Returns a boolean value indicating whether the operation succeeded. | |
* | |
* IMPORTANT: Beware that changing an allowance with this method brings the risk | |
* that someone may use both the old and the new allowance by unfortunate | |
* transaction ordering. One possible solution to mitigate this race | |
* condition is to first reduce the spender's allowance to 0 and set the | |
* desired value afterwards: | |
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 | |
* | |
* Emits an {Approval} event. | |
*/ | |
function approve(address spender, uint256 amount) external returns (bool); | |
/** | |
* @dev Moves `amount` tokens from `from` to `to` using the | |
* allowance mechanism. `amount` is then deducted from the caller's | |
* allowance. | |
* | |
* Returns a boolean value indicating whether the operation succeeded. | |
* | |
* Emits a {Transfer} event. | |
*/ | |
function transferFrom( | |
address from, | |
address to, | |
uint256 amount | |
) external returns (bool); | |
function mint(address to, uint256 amount) external; | |
} | |
contract SimpleBank { // CamelCase | |
using SafeMath for uint256; | |
mapping (address => uint256) private balances; | |
address[] accounts; | |
// Interest rate | |
uint256 rate = 3; | |
IERC20 cdgToken; | |
// Constructor, can receive one or many variables here; only one allowed | |
constructor(address tokenAddress) public { | |
cdgToken = IERC20(tokenAddress); | |
} | |
/// @notice Deposit ether into bank | |
/// @return The balance of the user after the deposit is made | |
function deposit(uint256 depositAmount) public returns (uint256) { | |
// Record account in array for looping | |
if (0 == balances[msg.sender]) { | |
accounts.push(msg.sender); | |
} | |
balances[msg.sender] = balances[msg.sender].add(depositAmount); | |
cdgToken.transferFrom(msg.sender,address(this),depositAmount); | |
return balances[msg.sender]; | |
} | |
/// @notice Withdraw ether from bank | |
/// @dev This does not return any excess ether sent to it | |
/// @param withdrawAmount amount you want to withdraw | |
/// @return remainingBal The balance remaining for the user | |
function withdraw(uint256 withdrawAmount) public returns (uint256 remainingBal) { | |
require(balances[msg.sender] >= withdrawAmount); // 1. check condition | |
balances[msg.sender] = balances[msg.sender].sub(withdrawAmount); // 2. data layer | |
cdgToken.transfer(msg.sender,withdrawAmount); // 3. money layer | |
return balances[msg.sender]; | |
} | |
/// @notice Get balance | |
/// @return The balance of the user | |
// 'constant' prevents function from editing state variables; | |
// allows function to run locally/off blockchain | |
function mybalance() public view returns (uint256) { | |
return balances[msg.sender]; | |
} | |
// Fallback function - Called if other functions don't match call or | |
// sent ether without data | |
// Typically, called when invalid data is sent | |
// Added so ether sent to this contract is reverted if the contract fails | |
// otherwise, the sender's money is transferred to contract | |
fallback () external { | |
revert(); // throw reverts state to before call | |
} | |
function calculateInterest(address user, uint256 _rate) private returns(uint256) { | |
uint256 interest = balances[user].mul(_rate).div(100); | |
cdgToken.mint(address(this),interest); | |
return interest; | |
} | |
function increaseYear() public { | |
for(uint256 i = 0; i < accounts.length; i++) { | |
address account = accounts[i]; | |
uint256 interest = calculateInterest(account, rate); | |
balances[account] = balances[account].add(interest); | |
} | |
} | |
function systemBalance() public view returns(uint256) { | |
// return address(this).balance; // check ETH (native) | |
cdgToken.balanceOf(address(this)); // check cdgToken balance of the bank | |
} | |
} | |
// ** END EXAMPLE ** |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment