Advertisement
Guest User

Untitled

a guest
Nov 12th, 2019
135
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.13 KB | None | 0 0
  1. pragma solidity 0.5.8;
  2. import { IFiatFrenzy } from './IFiatFrenzy.sol';
  3. import './Helpers.sol';
  4.  
  5. contract FiatFrenzy is IFiatFrenzy {
  6. // Coin Meta
  7. string internal _name;
  8. string internal _symbol;
  9. uint256 internal _totalSupply;
  10. uint256 internal _granularity;
  11.  
  12. event Sent(
  13. address indexed from,
  14. address indexed to,
  15. uint256 amount,
  16. bytes data
  17. );
  18.  
  19. // Operator Stuff
  20. event AuthorizedOperator(
  21. address indexed operator,
  22. address indexed holder
  23. );
  24.  
  25. event RevokedOperator(address indexed operator, address indexed holder);
  26.  
  27. address[] internal _defaultOperators;
  28. mapping(address => bool) internal _isDefaultOperator;
  29. mapping(address => mapping(address => bool)) internal _revokedDefaultOperator;
  30. mapping(address => mapping(address => bool)) internal _authorizedOperators;
  31.  
  32. // Frenzy
  33. uint256 _reserveRequirement;
  34. // no dynamic sizing of memory arrays, this gets deleted before every mint
  35. uint256[] _digits;
  36. mapping (uint256 => bool) _usedPostIds;
  37.  
  38. struct Account {
  39. // The number of tokens an account has
  40. uint256 _balance;
  41. // The number of positive loan
  42. uint256 _assets;
  43. // The number of negative loan
  44. uint256 _liabilities;
  45. }
  46. mapping (address => Account) _accounts;
  47.  
  48. struct Loan {
  49. uint256 _principle;
  50. uint256 _expiry;
  51. bool _isApproved;
  52. uint256 _createdAt;
  53. uint256 _signedAt;
  54. }
  55. // _loans[lendor][debtor]
  56. mapping (address => mapping (address => Loan[])) _loans;
  57. // indexer, using push to guarantee uniques
  58. mapping (address => mapping (address => uint256[])) _loanIndicies;
  59.  
  60. event Minted(
  61. address indexed _operator,
  62. address indexed _to,
  63. uint256 _amount
  64. );
  65.  
  66. event loanOffer(
  67. address indexed _lendor,
  68. uint256 indexed _index,
  69. address indexed _debtor
  70. );
  71.  
  72. event loanSign(
  73. address indexed _lendor,
  74. uint256 indexed _index,
  75. address indexed _debtor
  76. );
  77.  
  78. event loanRepaid(
  79. address indexed _lendor,
  80. uint256 indexed _index,
  81. address indexed _debtor
  82. );
  83.  
  84. modifier notSelf(address sender, address target) {
  85. require(sender != target, "This function is not self callable");
  86. _;
  87. }
  88.  
  89. modifier isMultipleOf(uint256 amount) {
  90. require(amount % _granularity == 0, 'math warning');
  91. _;
  92. }
  93.  
  94.  
  95. function timeAdjustedRR(
  96. uint256 expiryDate
  97. ) public view returns(uint256) {
  98. // higher numbers further in time
  99. uint256 lengthOfTimeInS = expiryDate - now;
  100. uint256 dayInS = 3600*24;
  101. // i believe this floors, is this satisfactory on the edge?
  102. uint256 daysTillExpiry = lengthOfTimeInS / dayInS;
  103. uint256 not = 1000000000;
  104.  
  105. if (daysTillExpiry < 365) {
  106. uint256 increment = _reserveRequirement / 365;
  107. return daysTillExpiry*increment;
  108. }
  109. return _reserveRequirement;
  110. }
  111.  
  112. modifier isWithinReserveRatio(
  113. address lendor,
  114. uint256 amount
  115. ) {
  116. Account memory account = _accounts[lendor];
  117. uint256 currentRatio = Helpers.percent(account._liabilities + amount, account._balance, 9);
  118. require(currentRatio <= _reserveRequirement, "apologies, reserve requirement exceeded");
  119. _;
  120. }
  121.  
  122. modifier isLoanOfferWithinReserveRatio(
  123. address lendor,
  124. uint256 amount,
  125. uint256 expiry
  126. ) {
  127. Account memory account = _accounts[lendor];
  128. uint256 currentRatio = Helpers.percent(account._liabilities + amount, account._balance, 9);
  129. require(currentRatio <= timeAdjustedRR(expiry), "apologies, reserve requirement exceeded");
  130. _;
  131. }
  132.  
  133. constructor(
  134. address[] memory defaultOperators
  135. ) public {
  136. _name = "Fiat Frenzy";
  137. _symbol = "FRENZ";
  138. _granularity = 1;
  139. _reserveRequirement = Helpers.percent(17167680177565, 27777890035288, 9);
  140. _defaultOperators = defaultOperators;
  141. for (uint256 i = 0; i < _defaultOperators.length; i++) {
  142. _isDefaultOperator[_defaultOperators[i]] = true;
  143. }
  144. // some test coins, remove for prod
  145. _accounts[msg.sender]._balance = 100;
  146.  
  147. }
  148.  
  149. function name() external view returns (string memory) {
  150. return _name;
  151. }
  152.  
  153. function symbol() external view returns (string memory) {
  154. return _symbol;
  155. }
  156.  
  157. function reserveRequirement() external view returns (uint256) {
  158. return _reserveRequirement;
  159. }
  160.  
  161.  
  162. function totalSupply() external view returns (uint256) {
  163. return _totalSupply;
  164. }
  165.  
  166. function balanceOf(address holder) external view returns (uint256) {
  167. Account memory account = _accounts[holder];
  168. return account._balance;
  169. }
  170.  
  171. function assetsOf(address holder) external view returns (uint256) {
  172. Account memory account = _accounts[holder];
  173. return account._assets;
  174. }
  175.  
  176. function liabilitiesOf(address holder) external view returns (uint256) {
  177. Account memory account = _accounts[holder];
  178. return account._liabilities;
  179. }
  180.  
  181. function granularity() external view returns (uint256) {
  182. return _granularity;
  183. }
  184.  
  185. function defaultOperators() external view returns (address[] memory) {
  186. return _defaultOperators;
  187. }
  188.  
  189. function isOperatorFor(
  190. address operator,
  191. address tokenHolder) public view returns (bool) {
  192. return (operator == tokenHolder
  193. || _authorizedOperators[operator][tokenHolder]
  194. || (_isDefaultOperator[operator] && !_revokedDefaultOperator[operator][tokenHolder]));
  195. }
  196.  
  197. function authorizeOperator(address operator) notSelf(msg.sender, operator) external {
  198. if (_isDefaultOperator[operator]) {
  199. _revokedDefaultOperator[operator][msg.sender] = false;
  200. } else {
  201. _authorizedOperators[operator][msg.sender] = true;
  202. }
  203. emit AuthorizedOperator(operator, msg.sender);
  204. }
  205.  
  206. function revokeOperator(address operator) notSelf(msg.sender, operator) external {
  207. if (_isDefaultOperator[operator]) {
  208. _revokedDefaultOperator[operator][msg.sender] = true;
  209. } else {
  210. _authorizedOperators[operator][msg.sender] = false;
  211. }
  212. emit RevokedOperator(operator, msg.sender);
  213. }
  214.  
  215.  
  216. function operatorMint(address to, uint256 amount) isMultipleOf(amount) public payable {
  217. require(_isDefaultOperator[msg.sender], 'executive function only');
  218. _accounts[to]._balance += amount;
  219.  
  220. emit Minted(msg.sender, to, amount);
  221. }
  222.  
  223. function iter(uint256 post) external pure returns (uint256) {
  224. uint256[4] memory test = [uint256(1), uint256(1),uint256(2), uint256(2)];
  225. uint256 last = 0;
  226. uint256 getFactor = 1;
  227. for (uint256 i = test.length; i>0; i--) {
  228. if (i == test.length) {
  229. last = test[i-1];
  230. } else {
  231. if (last == test[i-1]) {
  232. getFactor++;
  233. } else {
  234. break;
  235. }
  236. }
  237. }
  238. return last*getFactor;
  239. }
  240.  
  241. function formGet(uint digit, uint factor) internal pure returns (uint) {
  242. string memory digitAsStr = Helpers.uintToString(digit);
  243. string memory digitsAsStr = '';
  244. uint i = 0;
  245. while (i < factor) {
  246. digitsAsStr = Helpers.append(digitsAsStr, digitAsStr);
  247. i++;
  248. }
  249. return Helpers.parseInt(digitsAsStr, 0);
  250. }
  251. event proof(
  252. uint256 amount
  253. );
  254. function proofOfMeme(address to, uint256 post) external returns (uint256) {
  255. require(_isDefaultOperator[msg.sender], 'executive fn only');
  256. require(_usedPostIds[post] == false, 'no using the same post twice');
  257. delete _digits;
  258. uint256 number = post;
  259. uint256 lastIndex = 0;
  260.  
  261. while (number > 0) {
  262. uint256 digit = uint256(number % 10);
  263. number = number / 10;
  264. _digits.push(digit);
  265. lastIndex = _digits.length - 1;
  266. }
  267. uint256 last = 0;
  268. uint256 getFactor = 1;
  269. for (uint256 i = 0; i < _digits.length; i++) {
  270. if (i == 0) {
  271. last = _digits[i];
  272. } else {
  273. if (last == _digits[i]) {
  274. getFactor++;
  275. } else {
  276. break;
  277. }
  278. }
  279. }
  280. uint256 amount = formGet(last, getFactor);
  281. operatorMint(to, amount);
  282. _usedPostIds[post] = true;
  283. }
  284.  
  285. function _send(
  286. address to,
  287. address from,
  288. uint256 amount
  289. ) internal {
  290. require(to != address(0), 'no tokens to 0x0');
  291. Account storage senderAccount = _accounts[from];
  292. require(senderAccount._balance >= amount, "Insufficient Funds");
  293. Account storage recieverAccount = _accounts[to];
  294.  
  295. senderAccount._balance -= amount;
  296. recieverAccount._balance += amount;
  297.  
  298. }
  299. function send(
  300. address to,
  301. uint256 amount,
  302. bytes calldata data
  303. ) isMultipleOf(amount)
  304. isWithinReserveRatio(msg.sender, amount)
  305. external {
  306. _send(to, msg.sender, amount);
  307. emit Sent(msg.sender, to, amount, data);
  308. }
  309.  
  310. function offerLoan(
  311. address debtor,
  312. uint256 amount,
  313. uint256 expiry
  314. ) isMultipleOf(amount)
  315. isLoanOfferWithinReserveRatio(
  316. msg.sender,
  317. amount,
  318. expiry
  319. )
  320. external {
  321. // minimum day
  322. require((expiry - now) > 3600*24, 'loans must be at least a 24h');
  323. Loan memory newLoan = Loan(amount, expiry, false, now, 0);
  324. // _loans[lendor][debtor]
  325. _loans[msg.sender][debtor].push(newLoan);
  326. uint256 index = _loans[msg.sender][debtor].length;
  327. _loanIndicies[msg.sender][debtor].push(index);
  328.  
  329. emit loanOffer(msg.sender, index, debtor);
  330. }
  331.  
  332. function getLoanIndex(
  333. address lendor,
  334. address debtor
  335. ) external view returns (uint256) {
  336. uint256 index = _loanIndicies[lendor][debtor].length;
  337. return index;
  338. }
  339.  
  340. function getLoan(
  341. address lendor,
  342. address debtor,
  343. uint256 index
  344. ) external view returns (uint256, uint256, bool) {
  345. Loan memory loan = _loans[lendor][debtor][index - 1];
  346. return (loan._principle, loan._createdAt, loan._isApproved);
  347. }
  348.  
  349. function signLoan(
  350. address lendor,
  351. uint256 index
  352. ) isWithinReserveRatio(
  353. lendor,
  354. _loans[lendor][msg.sender][index -1]._principle
  355. ) external {
  356.  
  357. Loan storage loan = _loans[lendor][msg.sender][index - 1];
  358. Account storage lendorAccount = _accounts[lendor];
  359. Account storage debtorAccount = _accounts[msg.sender];
  360.  
  361. debtorAccount._balance += loan._principle;
  362. debtorAccount._liabilities += loan._principle;
  363.  
  364. lendorAccount._liabilities += loan._principle;
  365. lendorAccount._assets += loan._principle;
  366.  
  367. loan._isApproved = true;
  368. loan._signedAt = now;
  369.  
  370. emit loanSign(lendor, index, msg.sender);
  371. }
  372.  
  373. function getDebtIndex(
  374. address lendor
  375. ) external view returns (uint256) {
  376. return _loans[lendor][msg.sender].length;
  377. }
  378.  
  379. function repayLoan(
  380. address lendor,
  381. uint256 index
  382. )
  383. external {
  384. Loan storage loan = _loans[lendor][msg.sender][index - 1];
  385. require(now >= loan._expiry, 'loans must be expired before they are repaid');
  386. Account storage debtorAccount = _accounts[msg.sender];
  387. Account storage lendorAccount = _accounts[lendor];
  388.  
  389. _send(lendor, msg.sender, loan._principle);
  390.  
  391. debtorAccount._liabilities -= loan._principle;
  392.  
  393. lendorAccount._liabilities -= loan._principle;
  394. lendorAccount._assets -= loan._principle;
  395.  
  396. loan._principle = 0;
  397. emit loanRepaid(lendor, index, msg.sender);
  398. }
  399. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement