metafinance.sol 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. /**
  2. *Submitted for verification at Etherscan.io on 2021-07-22
  3. */
  4. // ----------------------------------------------------------------------------
  5. // Metafinance Contract
  6. // Name : Metafinance
  7. // Symbol : MF
  8. // Decimals : 18
  9. // InitialSupply : 1,000,000,000 MF
  10. // ----------------------------------------------------------------------------
  11. pragma solidity 0.5.8;
  12. interface IERC20 {
  13. function totalSupply() external view returns (uint256);
  14. function balanceOf(address account) external view returns (uint256);
  15. function transfer(address recipient, uint256 amount) external returns (bool);
  16. function allowance(address owner, address spender) external view returns (uint256);
  17. function approve(address spender, uint256 amount) external returns (bool);
  18. function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
  19. event Transfer(address indexed from, address indexed to, uint256 value);
  20. event Approval(address indexed owner, address indexed spender, uint256 value);
  21. }
  22. library SafeMath {
  23. function add(uint256 a, uint256 b) internal pure returns (uint256) {
  24. uint256 c = a + b;
  25. require(c >= a, "SafeMath: addition overflow");
  26. return c;
  27. }
  28. function sub(uint256 a, uint256 b) internal pure returns (uint256) {
  29. require(b <= a, "SafeMath: subtraction overflow");
  30. uint256 c = a - b;
  31. return c;
  32. }
  33. function mul(uint256 a, uint256 b) internal pure returns (uint256) {
  34. if (a == 0) {
  35. return 0;
  36. }
  37. uint256 c = a * b;
  38. require(c / a == b, "SafeMath: multiplication overflow");
  39. return c;
  40. }
  41. function div(uint256 a, uint256 b) internal pure returns (uint256) {
  42. require(b > 0, "SafeMath: division by zero");
  43. uint256 c = a / b;
  44. return c;
  45. }
  46. function mod(uint256 a, uint256 b) internal pure returns (uint256) {
  47. require(b != 0, "SafeMath: modulo by zero");
  48. return a % b;
  49. }
  50. }
  51. contract ERC20 is IERC20 {
  52. using SafeMath for uint256;
  53. mapping (address => uint256) internal _balances;
  54. mapping (address => mapping (address => uint256)) private _allowances;
  55. uint256 private _totalSupply;
  56. function totalSupply() public view returns (uint256) {
  57. return _totalSupply;
  58. }
  59. function balanceOf(address account) public view returns (uint256) {
  60. return _balances[account];
  61. }
  62. function transfer(address recipient, uint256 amount) public returns (bool) {
  63. _transfer(msg.sender, recipient, amount);
  64. return true;
  65. }
  66. function allowance(address owner, address spender) public view returns (uint256) {
  67. return _allowances[owner][spender];
  68. }
  69. function approve(address spender, uint256 value) public returns (bool) {
  70. _approve(msg.sender, spender, value);
  71. return true;
  72. }
  73. function transferFrom(address sender, address recipient, uint256 amount) public returns (bool) {
  74. _transfer(sender, recipient, amount);
  75. _approve(sender, msg.sender, _allowances[sender][msg.sender].sub(amount));
  76. return true;
  77. }
  78. function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {
  79. _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));
  80. return true;
  81. }
  82. function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {
  83. _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue));
  84. return true;
  85. }
  86. function _transfer(address sender, address recipient, uint256 amount) internal {
  87. require(sender != address(0), "ERC20: transfer from the zero address");
  88. require(recipient != address(0), "ERC20: transfer to the zero address");
  89. _balances[sender] = _balances[sender].sub(amount);
  90. _balances[recipient] = _balances[recipient].add(amount);
  91. emit Transfer(sender, recipient, amount);
  92. }
  93. function _mint(address account, uint256 amount) internal {
  94. require(account != address(0), "ERC20: mint to the zero address");
  95. _totalSupply = _totalSupply.add(amount);
  96. _balances[account] = _balances[account].add(amount);
  97. emit Transfer(address(0), account, amount);
  98. }
  99. function _burn(address owner, uint256 value) internal {
  100. require(owner != address(0), "ERC20: burn from the zero address");
  101. _totalSupply = _totalSupply.sub(value);
  102. _balances[owner] = _balances[owner].sub(value);
  103. emit Transfer(owner, address(0), value);
  104. }
  105. function _approve(address owner, address spender, uint256 value) internal {
  106. require(owner != address(0), "ERC20: approve from the zero address");
  107. require(spender != address(0), "ERC20: approve to the zero address");
  108. _allowances[owner][spender] = value;
  109. emit Approval(owner, spender, value);
  110. }
  111. function _burnFrom(address owner, uint256 amount) internal {
  112. _burn(owner, amount);
  113. _approve(owner, msg.sender, _allowances[owner][msg.sender].sub(amount));
  114. }
  115. }
  116. contract Metafinance is ERC20 {
  117. string public constant name = "Metafinance";
  118. string public constant symbol = "MF";
  119. uint8 public constant decimals = 18;
  120. uint256 public constant initialSupply = 1000000000 * (10 ** uint256(decimals));
  121. constructor() public {
  122. super._mint(msg.sender, initialSupply);
  123. owner = msg.sender;
  124. }
  125. address public owner;
  126. event OwnershipRenounced(address indexed previousOwner);
  127. event OwnershipTransferred(
  128. address indexed previousOwner,
  129. address indexed newOwner
  130. );
  131. modifier onlyOwner() {
  132. require(msg.sender == owner, "Not owner");
  133. _;
  134. }
  135. function transferOwnership(address _newOwner) public onlyOwner {
  136. _transferOwnership(_newOwner);
  137. }
  138. function _transferOwnership(address _newOwner) internal {
  139. require(_newOwner != address(0), "Already Owner");
  140. emit OwnershipTransferred(owner, _newOwner);
  141. owner = _newOwner;
  142. }
  143. function transfer(
  144. address _to,
  145. uint256 _value
  146. )
  147. public
  148. returns (bool)
  149. {
  150. releaseLock(msg.sender);
  151. return super.transfer(_to, _value);
  152. }
  153. function transferFrom(
  154. address _from,
  155. address _to,
  156. uint256 _value
  157. )
  158. public
  159. returns (bool)
  160. {
  161. releaseLock(_from);
  162. return super.transferFrom(_from, _to, _value);
  163. }
  164. event Burn(address indexed burner, uint256 value);
  165. function burn(uint256 _value) public onlyOwner {
  166. require(_value <= super.balanceOf(owner), "Balance is too small.");
  167. _burn(owner, _value);
  168. emit Burn(owner, _value);
  169. }
  170. struct LockInfo {
  171. uint256 releaseTime;
  172. uint256 balance;
  173. }
  174. mapping(address => LockInfo[]) internal lockInfo;
  175. event Lock(address indexed holder, uint256 value, uint256 releaseTime);
  176. event Unlock(address indexed holder, uint256 value);
  177. function balanceOf(address _holder) public view returns (uint256 balance) {
  178. uint256 lockedBalance = 0;
  179. for(uint256 i = 0; i < lockInfo[_holder].length ; i++ ) {
  180. lockedBalance = lockedBalance.add(lockInfo[_holder][i].balance);
  181. }
  182. return super.balanceOf(_holder).add(lockedBalance);
  183. }
  184. function releaseLock(address _holder) internal {
  185. for(uint256 i = 0; i < lockInfo[_holder].length ; i++ ) {
  186. if (lockInfo[_holder][i].releaseTime <= now) {
  187. _balances[_holder] = _balances[_holder].add(lockInfo[_holder][i].balance);
  188. emit Unlock(_holder, lockInfo[_holder][i].balance);
  189. lockInfo[_holder][i].balance = 0;
  190. if (i != lockInfo[_holder].length - 1) {
  191. lockInfo[_holder][i] = lockInfo[_holder][lockInfo[_holder].length - 1];
  192. i--;
  193. }
  194. lockInfo[_holder].length--;
  195. }
  196. }
  197. }
  198. function lockCount(address _holder) public view returns (uint256) {
  199. return lockInfo[_holder].length;
  200. }
  201. function lockState(address _holder, uint256 _idx) public view returns (uint256, uint256) {
  202. return (lockInfo[_holder][_idx].releaseTime, lockInfo[_holder][_idx].balance);
  203. }
  204. function lock(address _holder, uint256 _amount, uint256 _releaseTime) public onlyOwner {
  205. require(super.balanceOf(_holder) >= _amount, "Balance is too small.");
  206. require(block.timestamp <= _releaseTime, "TokenTimelock: release time is before current time");
  207. _balances[_holder] = _balances[_holder].sub(_amount);
  208. lockInfo[_holder].push(
  209. LockInfo(_releaseTime, _amount)
  210. );
  211. emit Lock(_holder, _amount, _releaseTime);
  212. }
  213. function unlock(address _holder, uint256 i) public onlyOwner {
  214. require(i < lockInfo[_holder].length, "No lock information.");
  215. _balances[_holder] = _balances[_holder].add(lockInfo[_holder][i].balance);
  216. emit Unlock(_holder, lockInfo[_holder][i].balance);
  217. lockInfo[_holder][i].balance = 0;
  218. if (i != lockInfo[_holder].length - 1) {
  219. lockInfo[_holder][i] = lockInfo[_holder][lockInfo[_holder].length - 1];
  220. }
  221. lockInfo[_holder].length--;
  222. }
  223. function transferWithLock(address _to, uint256 _value, uint256 _releaseTime) public onlyOwner returns (bool) {
  224. require(_to != address(0), "wrong address");
  225. require(_value <= super.balanceOf(owner), "Not enough balance");
  226. require(block.timestamp <= _releaseTime, "TokenTimelock: release time is before current time");
  227. _balances[owner] = _balances[owner].sub(_value);
  228. lockInfo[_to].push(
  229. LockInfo(_releaseTime, _value)
  230. );
  231. emit Transfer(owner, _to, _value);
  232. emit Lock(_to, _value, _releaseTime);
  233. return true;
  234. }
  235. }