Advertisement
Guest User

Untitled

a guest
May 24th, 2019
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 16.65 KB | None | 0 0
  1. pragma solidity ^0.5.2;
  2.  
  3. contract Utils {
  4. /**
  5. constructor
  6. */
  7. constructor() public {
  8. }
  9.  
  10. // verifies that an amount is greater than zero
  11. modifier greaterThanZero(uint256 _amount) {
  12. require(_amount > 0);
  13. _;
  14. }
  15.  
  16. // validates an address - currently only checks that it isn't null
  17. modifier validAddress(address _address) {
  18. require(_address != address(0));
  19. _;
  20. }
  21.  
  22. // verifies that the address is different than this contract address
  23. modifier notThis(address _address) {
  24. require(_address != address(this));
  25. _;
  26. }
  27.  
  28. // Overflow protected math functions
  29.  
  30. /**
  31. @dev returns the sum of _x and _y, asserts if the calculation overflows
  32.  
  33. @param _x value 1
  34. @param _y value 2
  35.  
  36. @return sum
  37. */
  38. function safeAdd(uint256 _x, uint256 _y) internal pure returns (uint256) {
  39. uint256 z = _x + _y;
  40. assert(z >= _x);
  41. return z;
  42. }
  43.  
  44. /**
  45. @dev returns the difference of _x minus _y, asserts if the subtraction results in a negative number
  46.  
  47. @param _x minuend
  48. @param _y subtrahend
  49.  
  50. @return difference
  51. */
  52. function safeSub(uint256 _x, uint256 _y) internal pure returns (uint256) {
  53. assert(_x >= _y);
  54. return _x - _y;
  55. }
  56.  
  57. /**
  58. @dev returns the product of multiplying _x by _y, asserts if the calculation overflows
  59.  
  60. @param _x factor 1
  61. @param _y factor 2
  62.  
  63. @return product
  64. */
  65. function safeMul(uint256 _x, uint256 _y) internal pure returns (uint256) {
  66. uint256 z = _x * _y;
  67. assert(_x == 0 || z / _x == _y);
  68. return z;
  69. }
  70.  
  71. /**
  72. @dev returns the product of dividing _x by _y, asserts if the division by zero.
  73.  
  74. @param _x factor 1
  75. @param _y factor 2
  76.  
  77. @return product
  78. */
  79. function safeDiv(uint256 _x, uint256 _y) internal pure returns (uint256) {
  80. require(_y > 0);
  81. uint256 c = _x / _y;
  82.  
  83. return c;
  84. }
  85. }
  86.  
  87. contract DSAuthority {
  88. function canCall(
  89. address src, address dst, bytes4 sig
  90. ) public view returns (bool);
  91. }
  92.  
  93. contract DSAuthEvents {
  94. event LogSetAuthority (address indexed authority);
  95. event LogSetOwner (address indexed owner);
  96. event OwnerUpdate (address indexed owner, address indexed newOwner);
  97. }
  98.  
  99. contract DSAuth is DSAuthEvents {
  100. DSAuthority public authority;
  101. address public owner;
  102. address public newOwner;
  103.  
  104. constructor() public {
  105. owner = msg.sender;
  106. emit LogSetOwner(msg.sender);
  107. }
  108.  
  109. function transferOwnership(address newOwner_) public onlyOwner {
  110. require(newOwner_ != owner);
  111. newOwner = newOwner_;
  112. }
  113.  
  114. function acceptOwnership() public {
  115. require(msg.sender == newOwner);
  116. emit OwnerUpdate(owner, newOwner);
  117. owner = newOwner;
  118. newOwner = address(0x0);
  119. }
  120.  
  121. ///[snow] guard is Authority who inherit DSAuth.
  122. function setAuthority(DSAuthority authority_)
  123. public
  124. onlyOwner
  125. {
  126. authority = authority_;
  127. emit LogSetAuthority(address(authority));
  128. }
  129.  
  130. modifier onlyOwner {
  131. require(isOwner(msg.sender), "ds-auth-non-owner");
  132. _;
  133. }
  134.  
  135. function isOwner(address src) internal view returns (bool) {
  136. return bool(src == owner);
  137. }
  138.  
  139. modifier auth {
  140. require(isAuthorized(msg.sender, msg.sig), "ds-auth-unauthorized");
  141. _;
  142. }
  143.  
  144. function isAuthorized(address src, bytes4 sig) internal view returns (bool) {
  145. if (src == address(this)) {
  146. return true;
  147. } else if (src == owner) {
  148. return true;
  149. } else if (authority == DSAuthority(0)) {
  150. return false;
  151. } else {
  152. return authority.canCall(src, address(this), sig);
  153. }
  154. }
  155. }
  156.  
  157. library ColQueue
  158. {
  159. struct ColList {
  160. uint size;
  161. uint head;
  162. uint last;
  163. uint seed;
  164. uint amount;
  165. mapping(uint => ColItem) data;
  166. mapping(address => uint) balanceOf;
  167. }
  168.  
  169. struct ColItem {
  170. uint prevIdx;
  171. uint nextIdx;
  172. address depositor;
  173. uint256 total;
  174. uint256 balance;
  175. }
  176.  
  177. function getHeadIdx(ColList storage self) public view returns (uint) {
  178. return self.head;
  179. }
  180.  
  181. function getLastIdx(ColList storage self) public view returns (uint) {
  182. return self.last;
  183. }
  184.  
  185. function getNextbyIdx(ColList storage self, uint idx) public view returns (uint) {
  186. return self.data[idx].nextIdx;
  187. }
  188.  
  189. function getPrevbyIdx(ColList storage self, uint idx) public view returns (uint) {
  190. return self.data[idx].prevIdx;
  191. }
  192.  
  193. function push(ColList storage self, address depositor, uint value) internal {
  194. uint idx = self.seed++;
  195.  
  196. self.data[idx] = ColItem(0, 0, depositor, value, value);
  197.  
  198. if (0 == self.size) {
  199. self.data[idx].prevIdx = uint(-1);
  200. self.data[idx].nextIdx = uint(-1);
  201. self.head = idx;
  202. self.last = idx;
  203. } else {
  204. self.data[self.last].nextIdx = idx;
  205. self.data[idx].prevIdx = self.last;
  206. self.data[idx].nextIdx = uint(-1);
  207. self.last = idx;
  208. }
  209.  
  210. self.size++;
  211. self.amount += value;
  212. self.balanceOf[depositor] += value;
  213. }
  214.  
  215. function pop(ColList storage self) internal {
  216. popIdx(self, self.head);
  217. }
  218.  
  219. function popIdx(ColList storage self, uint idx) internal {
  220. require(self.size > 0, "PopIdx: fifo is empty.");
  221. require(idx >= self.head, "PopIdx: idx is left overflow.");
  222. require(idx <= self.last, "PopIdx: idx is right overflow.");
  223.  
  224. uint prevIdx = self.data[idx].prevIdx;
  225. uint nextIdx = self.data[idx].nextIdx;
  226. uint balance = self.data[idx].balance;
  227. address depositor = self.data[idx].depositor;
  228.  
  229. if(idx == self.head) {
  230. self.data[nextIdx].prevIdx = uint(-1);
  231. self.head = nextIdx;
  232. } else if(idx == self.last) {
  233. self.data[prevIdx].nextIdx = uint(-1);
  234. self.last = prevIdx;
  235. } else {
  236. self.data[prevIdx].nextIdx = nextIdx;
  237. self.data[nextIdx].prevIdx = prevIdx;
  238. }
  239.  
  240. delete self.data[idx];
  241. self.amount -= balance;
  242. self.balanceOf[depositor] -= balance;
  243. self.size--;
  244. }
  245.  
  246. function updateBalance(ColList storage self, uint idx, uint value) internal {
  247. self.data[idx].balance = value;
  248. }
  249.  
  250. function withdraw(ColList storage self, address depositor, uint _value) internal {
  251. require(self.size > 0, "Withdraw: Queue is empty");
  252. require(_value > 0, "Withdraw: zero not support.");
  253.  
  254. uint idx = getLastIdx(self);
  255. uint balance;
  256. uint value = _value;
  257.  
  258. while(int(value) > 0 && idx != uint(-1)) {
  259. if (depositor == self.data[idx].depositor) {
  260. balance = self.data[idx].balance;
  261. if(balance > value) {
  262. self.data[idx].balance -= value;
  263. self.amount -= value;
  264. self.balanceOf[depositor] -= value;
  265. break;
  266. } else if(balance == value) {
  267. popIdx(self, idx);
  268. break;
  269. } else {
  270. popIdx(self, idx);
  271. value -= balance;
  272. }
  273. }
  274. idx = getPrevbyIdx(self, idx);
  275. }
  276. }
  277.  
  278. function getCollateralQueue(ColList storage self, uint consume) internal view returns (uint, address[] memory, uint256[] memory) {
  279. require(self.size > 0, "GetCollateralQueue: fifo is empty.");
  280.  
  281. uint queueLength = self.size;
  282. uint idx = self.head;
  283. uint balance;
  284. uint i = 0;
  285.  
  286. while(i < queueLength) {
  287. balance += self.data[idx].balance;
  288. i++;
  289. if(balance >= consume) {
  290. break;
  291. }
  292. idx = getNextbyIdx(self, idx);
  293. }
  294.  
  295. address[] memory addrs = new address[](i);
  296. uint256[] memory balances = new uint256[](i);
  297.  
  298. idx = self.head;
  299. for(uint j = 0; j < i; j++) {
  300. addrs[j] = self.data[idx].depositor;
  301. balances[j] = self.data[idx].balance;
  302. idx = getNextbyIdx(self, idx);
  303. }
  304.  
  305. require(balance - consume >= 0, "GetCollateralQueue: not enough balance.");
  306. return (balance - consume, addrs, balances);
  307. }
  308. }
  309.  
  310. contract DataStore2 is DSAuth, Utils {
  311.  
  312. // MEMBERS
  313.  
  314. /// @dev cw - The Weight of collateral
  315. struct SectionInfo {
  316. uint256 minted;
  317. uint256 burned;
  318. address[] collateralAddress;
  319. mapping (address => uint256) cw;
  320. }
  321.  
  322. SectionInfo[] public sectionInfoList;
  323.  
  324. /// @dev The position of current sectionInfoList
  325. uint256 private _mintSectionPosition;
  326.  
  327. /// @dev The position of old sectionInfoList
  328. uint256 private _burnSectionPosition;
  329.  
  330. /// @dev The total amount of minted.
  331. uint256 private _totalMinted;
  332.  
  333. /// @dev The total amount of burned.
  334. uint256 private _totalBurned;
  335.  
  336. mapping (address => ColQueue.ColList) public collateralQueue;
  337.  
  338. event UpdateTokens(address[] _collateral, uint256[] number);
  339.  
  340. // constructor(address[] memory _collateral, uint256[] memory _weight) public {
  341. // _setSectionInfo(_collateral, _weight);
  342. // }
  343.  
  344. // PUBLIC FUNCTIONS
  345. // (Data Store)
  346.  
  347. function mintSectionPosition() public view returns (uint256) {
  348. return _mintSectionPosition;
  349. }
  350.  
  351. function burnSectionPosition() public view returns (uint256) {
  352. return _burnSectionPosition;
  353. }
  354.  
  355. function totalMinted() public view returns (uint256) {
  356. return _totalMinted;
  357. }
  358.  
  359. function totalBurned() public view returns (uint256) {
  360. return _totalBurned;
  361. }
  362.  
  363. /**
  364. @dev set collateral token info in structure of SectionInfo
  365.  
  366. @param _collateral collateral address
  367. @param _weight collateral weight
  368. */
  369. function _setSectionInfo(address[] memory _collateral, uint256[] memory _weight) internal {
  370. require(_collateral.length == _weight.length, "_SetSectionInfo: data not enough.");
  371.  
  372. uint256 numTokenOfsection = _collateral.length;
  373.  
  374. address[] memory addrs = new address[](numTokenOfsection);
  375.  
  376. sectionInfoList.push(SectionInfo(0,0,addrs));
  377.  
  378. _mintSectionPosition = sectionInfoList.length - 1;
  379.  
  380. for (uint256 i = 0; i < numTokenOfsection; i++) {
  381. address token = _collateral[i];
  382. require(token != address(0), "_SetSectionInfo: token contract address invalid.");
  383. uint256 weight = _weight[i] * (10 ** 18);
  384. require(weight > 0, "_SetSectionInfo: weight must greater than 0.");
  385. sectionInfoList[_mintSectionPosition].cw[token] = weight;
  386. sectionInfoList[_mintSectionPosition].collateralAddress[i] = token;
  387. }
  388. emit UpdateTokens(sectionInfoList[_mintSectionPosition].collateralAddress, _weight);
  389. }
  390.  
  391. function setSectionInfo(address[] memory _collateral, uint256[] memory _weight) public auth {
  392. _setSectionInfo(_collateral, _weight);
  393. emit UpdateTokens(sectionInfoList[_mintSectionPosition].collateralAddress, _weight);
  394. }
  395.  
  396. function sectionToken(uint256 _position) public view returns (address[] memory) {
  397. return sectionInfoList[_position].collateralAddress;
  398. }
  399.  
  400. function collateralWeight(uint256 _position, address _collateral) public view returns (uint256) {
  401. return sectionInfoList[_position].cw[_collateral];
  402. }
  403.  
  404. /**
  405. @dev set the number of minted in structure of SectionInfo
  406.  
  407. @param _newMinted number of minted
  408. */
  409. function setSectionMinted(uint256 _newMinted) public auth {
  410. require(_newMinted >= sectionInfoList[_mintSectionPosition].minted, "SetSectionMinted: minted number not right.");
  411. sectionInfoList[_mintSectionPosition].minted = _newMinted;
  412. }
  413.  
  414. /**
  415. @dev the number of minted in structure of SectionInfo
  416. */
  417. function sectionMinted(uint256 _position) public view returns (uint256) {
  418. return sectionInfoList[_position].minted;
  419. }
  420.  
  421. /**
  422. @dev set the number of burned in structure of SectionInfo
  423.  
  424. @param _newBurned number of burned
  425. */
  426. function setSectionBurned(uint256 _newBurned) public auth {
  427. require(_newBurned <= sectionInfoList[_burnSectionPosition].minted, "SetSectionBurned: burned number not right.");
  428. sectionInfoList[_burnSectionPosition].burned = _newBurned;
  429. }
  430.  
  431. /**
  432. @dev the number of burned in structure of SectionInfo
  433. */
  434. function sectionBurned() public view returns (uint256) {
  435. return sectionInfoList[_burnSectionPosition].burned;
  436. }
  437.  
  438. /**
  439. @dev clear collateral token info in structure of SectionInfo
  440. */
  441. function burnSectionMoveon() public auth {
  442. uint _p = _burnSectionPosition;
  443. require(sectionInfoList[_p].minted == sectionInfoList[_p].burned, "BurnSectionMoveon: not ready for move on.");
  444. _burnSectionPosition += 1;
  445. }
  446.  
  447. function tokenPool(address token) public view returns (uint256) {
  448. return collateralQueue[token].amount;
  449. }
  450.  
  451. function setTokenPool(address token, uint256 amount) public auth {
  452. collateralQueue[token].amount = amount;
  453. }
  454.  
  455. function balanceOfTokens(address token, address owner) public view returns (uint256) {
  456. return collateralQueue[token].balanceOf[owner];
  457. }
  458.  
  459. function setBalanceOfTokens(address token, address owner, uint256 amount) public auth {
  460. collateralQueue[token].balanceOf[owner] = amount;
  461. }
  462.  
  463. function headOfQueue(address token) public view returns (address, uint, uint) {
  464. ColQueue.ColItem storage _head = collateralQueue[token].data[collateralQueue[token].head];
  465. return (_head.depositor, _head.total, _head.balance);
  466. }
  467.  
  468. function pushCollateralQueue(address token, address depositor, uint256 total) public auth {
  469. if(collateralQueue[token].seed == 0) {
  470. collateralQueue[token] = ColQueue.ColList(0, 0, 0, 0, 0);
  471. }
  472.  
  473. ColQueue.push(collateralQueue[token], depositor, total);
  474. }
  475.  
  476. event idxLog(uint idx, uint pre, uint nex);
  477. function loopIdxF(address token) public {
  478. uint idx = ColQueue.getHeadIdx(collateralQueue[token]);
  479. uint size = collateralQueue[token].size;
  480. uint prev = ColQueue.getPrevbyIdx(collateralQueue[token], idx);
  481. uint next = ColQueue.getNextbyIdx(collateralQueue[token], idx);
  482. int i = 1;
  483.  
  484. emit idxLog(idx, prev, next);
  485. while (i++ < int(size)) {
  486. idx = ColQueue.getNextbyIdx(collateralQueue[token], idx);
  487. prev = ColQueue.getPrevbyIdx(collateralQueue[token], idx);
  488. next = ColQueue.getNextbyIdx(collateralQueue[token], idx);
  489. emit idxLog(idx, prev, next);
  490. }
  491. }
  492.  
  493. function loopIdxB(address token) public {
  494. uint idx = ColQueue.getLastIdx(collateralQueue[token]);
  495. uint size = collateralQueue[token].size;
  496. uint prev = ColQueue.getPrevbyIdx(collateralQueue[token], idx);
  497. uint next = ColQueue.getNextbyIdx(collateralQueue[token], idx);
  498. int i = 1;
  499.  
  500. emit idxLog(idx, prev, next);
  501. while (i++ < int(size)) {
  502. idx = ColQueue.getPrevbyIdx(collateralQueue[token], idx);
  503. prev = ColQueue.getPrevbyIdx(collateralQueue[token], idx);
  504. next = ColQueue.getNextbyIdx(collateralQueue[token], idx);
  505. emit idxLog(idx, prev, next);
  506. }
  507. }
  508.  
  509. function popCollateralQueue(address token, uint256 length) public auth {
  510. for(uint i = 0; i < length; i++) {
  511. ColQueue.pop(collateralQueue[token]);
  512. }
  513. }
  514.  
  515. function takeOffCollateralQueue(address token, address depositor, uint256 amount) public auth {
  516. ColQueue.withdraw(collateralQueue[token], depositor, amount);
  517. }
  518.  
  519. function getCollateralQueue(address token, uint consume) public view returns (uint, address[] memory, uint256[] memory) {
  520. return ColQueue.getCollateralQueue(collateralQueue[token], consume);
  521. }
  522.  
  523. function updateCollateralQueue(address token, address depositor, uint256 balance) public auth {
  524. uint ihead = collateralQueue[token].head;
  525. require(depositor == collateralQueue[token].data[ihead].depositor, "UpdateCollateralQueue: Not the same depositor");
  526. ColQueue.updateBalance(collateralQueue[token], ihead, balance);
  527. }
  528.  
  529. function setTotalMinted(uint256 _amount) public auth {
  530. _totalMinted = _amount;
  531. }
  532.  
  533. function setTotalBurned(uint256 _amount) public auth {
  534. _totalBurned = _amount;
  535. }
  536.  
  537. function getCollateralQueueLength(address _token) public view returns (uint256) {
  538. return collateralQueue[_token].size;
  539. }
  540. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement