Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- pragma solidity ^0.5.2;
- contract Utils {
- /**
- constructor
- */
- constructor() public {
- }
- // verifies that an amount is greater than zero
- modifier greaterThanZero(uint256 _amount) {
- require(_amount > 0);
- _;
- }
- // validates an address - currently only checks that it isn't null
- modifier validAddress(address _address) {
- require(_address != address(0));
- _;
- }
- // verifies that the address is different than this contract address
- modifier notThis(address _address) {
- require(_address != address(this));
- _;
- }
- // Overflow protected math functions
- /**
- @dev returns the sum of _x and _y, asserts if the calculation overflows
- @param _x value 1
- @param _y value 2
- @return sum
- */
- function safeAdd(uint256 _x, uint256 _y) internal pure returns (uint256) {
- uint256 z = _x + _y;
- assert(z >= _x);
- return z;
- }
- /**
- @dev returns the difference of _x minus _y, asserts if the subtraction results in a negative number
- @param _x minuend
- @param _y subtrahend
- @return difference
- */
- function safeSub(uint256 _x, uint256 _y) internal pure returns (uint256) {
- assert(_x >= _y);
- return _x - _y;
- }
- /**
- @dev returns the product of multiplying _x by _y, asserts if the calculation overflows
- @param _x factor 1
- @param _y factor 2
- @return product
- */
- function safeMul(uint256 _x, uint256 _y) internal pure returns (uint256) {
- uint256 z = _x * _y;
- assert(_x == 0 || z / _x == _y);
- return z;
- }
- /**
- @dev returns the product of dividing _x by _y, asserts if the division by zero.
- @param _x factor 1
- @param _y factor 2
- @return product
- */
- function safeDiv(uint256 _x, uint256 _y) internal pure returns (uint256) {
- require(_y > 0);
- uint256 c = _x / _y;
- return c;
- }
- }
- contract DSAuthority {
- function canCall(
- address src, address dst, bytes4 sig
- ) public view returns (bool);
- }
- contract DSAuthEvents {
- event LogSetAuthority (address indexed authority);
- event LogSetOwner (address indexed owner);
- event OwnerUpdate (address indexed owner, address indexed newOwner);
- }
- contract DSAuth is DSAuthEvents {
- DSAuthority public authority;
- address public owner;
- address public newOwner;
- constructor() public {
- owner = msg.sender;
- emit LogSetOwner(msg.sender);
- }
- function transferOwnership(address newOwner_) public onlyOwner {
- require(newOwner_ != owner);
- newOwner = newOwner_;
- }
- function acceptOwnership() public {
- require(msg.sender == newOwner);
- emit OwnerUpdate(owner, newOwner);
- owner = newOwner;
- newOwner = address(0x0);
- }
- ///[snow] guard is Authority who inherit DSAuth.
- function setAuthority(DSAuthority authority_)
- public
- onlyOwner
- {
- authority = authority_;
- emit LogSetAuthority(address(authority));
- }
- modifier onlyOwner {
- require(isOwner(msg.sender), "ds-auth-non-owner");
- _;
- }
- function isOwner(address src) internal view returns (bool) {
- return bool(src == owner);
- }
- modifier auth {
- require(isAuthorized(msg.sender, msg.sig), "ds-auth-unauthorized");
- _;
- }
- function isAuthorized(address src, bytes4 sig) internal view returns (bool) {
- if (src == address(this)) {
- return true;
- } else if (src == owner) {
- return true;
- } else if (authority == DSAuthority(0)) {
- return false;
- } else {
- return authority.canCall(src, address(this), sig);
- }
- }
- }
- library ColQueue
- {
- struct ColList {
- uint size;
- uint head;
- uint last;
- uint seed;
- uint amount;
- mapping(uint => ColItem) data;
- mapping(address => uint) balanceOf;
- }
- struct ColItem {
- uint prevIdx;
- uint nextIdx;
- address depositor;
- uint256 total;
- uint256 balance;
- }
- function getHeadIdx(ColList storage self) public view returns (uint) {
- return self.head;
- }
- function getLastIdx(ColList storage self) public view returns (uint) {
- return self.last;
- }
- function getNextbyIdx(ColList storage self, uint idx) public view returns (uint) {
- return self.data[idx].nextIdx;
- }
- function getPrevbyIdx(ColList storage self, uint idx) public view returns (uint) {
- return self.data[idx].prevIdx;
- }
- function push(ColList storage self, address depositor, uint value) internal {
- uint idx = self.seed++;
- self.data[idx] = ColItem(0, 0, depositor, value, value);
- if (0 == self.size) {
- self.data[idx].prevIdx = uint(-1);
- self.data[idx].nextIdx = uint(-1);
- self.head = idx;
- self.last = idx;
- } else {
- self.data[self.last].nextIdx = idx;
- self.data[idx].prevIdx = self.last;
- self.data[idx].nextIdx = uint(-1);
- self.last = idx;
- }
- self.size++;
- self.amount += value;
- self.balanceOf[depositor] += value;
- }
- function pop(ColList storage self) internal {
- popIdx(self, self.head);
- }
- function popIdx(ColList storage self, uint idx) internal {
- require(self.size > 0, "PopIdx: fifo is empty.");
- require(idx >= self.head, "PopIdx: idx is left overflow.");
- require(idx <= self.last, "PopIdx: idx is right overflow.");
- uint prevIdx = self.data[idx].prevIdx;
- uint nextIdx = self.data[idx].nextIdx;
- uint balance = self.data[idx].balance;
- address depositor = self.data[idx].depositor;
- if(idx == self.head) {
- self.data[nextIdx].prevIdx = uint(-1);
- self.head = nextIdx;
- } else if(idx == self.last) {
- self.data[prevIdx].nextIdx = uint(-1);
- self.last = prevIdx;
- } else {
- self.data[prevIdx].nextIdx = nextIdx;
- self.data[nextIdx].prevIdx = prevIdx;
- }
- delete self.data[idx];
- self.amount -= balance;
- self.balanceOf[depositor] -= balance;
- self.size--;
- }
- function updateBalance(ColList storage self, uint idx, uint value) internal {
- self.data[idx].balance = value;
- }
- function withdraw(ColList storage self, address depositor, uint _value) internal {
- require(self.size > 0, "Withdraw: Queue is empty");
- require(_value > 0, "Withdraw: zero not support.");
- uint idx = getLastIdx(self);
- uint balance;
- uint value = _value;
- while(int(value) > 0 && idx != uint(-1)) {
- if (depositor == self.data[idx].depositor) {
- balance = self.data[idx].balance;
- if(balance > value) {
- self.data[idx].balance -= value;
- self.amount -= value;
- self.balanceOf[depositor] -= value;
- break;
- } else if(balance == value) {
- popIdx(self, idx);
- break;
- } else {
- popIdx(self, idx);
- value -= balance;
- }
- }
- idx = getPrevbyIdx(self, idx);
- }
- }
- function getCollateralQueue(ColList storage self, uint consume) internal view returns (uint, address[] memory, uint256[] memory) {
- require(self.size > 0, "GetCollateralQueue: fifo is empty.");
- uint queueLength = self.size;
- uint idx = self.head;
- uint balance;
- uint i = 0;
- while(i < queueLength) {
- balance += self.data[idx].balance;
- i++;
- if(balance >= consume) {
- break;
- }
- idx = getNextbyIdx(self, idx);
- }
- address[] memory addrs = new address[](i);
- uint256[] memory balances = new uint256[](i);
- idx = self.head;
- for(uint j = 0; j < i; j++) {
- addrs[j] = self.data[idx].depositor;
- balances[j] = self.data[idx].balance;
- idx = getNextbyIdx(self, idx);
- }
- require(balance - consume >= 0, "GetCollateralQueue: not enough balance.");
- return (balance - consume, addrs, balances);
- }
- }
- contract DataStore2 is DSAuth, Utils {
- // MEMBERS
- /// @dev cw - The Weight of collateral
- struct SectionInfo {
- uint256 minted;
- uint256 burned;
- address[] collateralAddress;
- mapping (address => uint256) cw;
- }
- SectionInfo[] public sectionInfoList;
- /// @dev The position of current sectionInfoList
- uint256 private _mintSectionPosition;
- /// @dev The position of old sectionInfoList
- uint256 private _burnSectionPosition;
- /// @dev The total amount of minted.
- uint256 private _totalMinted;
- /// @dev The total amount of burned.
- uint256 private _totalBurned;
- mapping (address => ColQueue.ColList) public collateralQueue;
- event UpdateTokens(address[] _collateral, uint256[] number);
- // constructor(address[] memory _collateral, uint256[] memory _weight) public {
- // _setSectionInfo(_collateral, _weight);
- // }
- // PUBLIC FUNCTIONS
- // (Data Store)
- function mintSectionPosition() public view returns (uint256) {
- return _mintSectionPosition;
- }
- function burnSectionPosition() public view returns (uint256) {
- return _burnSectionPosition;
- }
- function totalMinted() public view returns (uint256) {
- return _totalMinted;
- }
- function totalBurned() public view returns (uint256) {
- return _totalBurned;
- }
- /**
- @dev set collateral token info in structure of SectionInfo
- @param _collateral collateral address
- @param _weight collateral weight
- */
- function _setSectionInfo(address[] memory _collateral, uint256[] memory _weight) internal {
- require(_collateral.length == _weight.length, "_SetSectionInfo: data not enough.");
- uint256 numTokenOfsection = _collateral.length;
- address[] memory addrs = new address[](numTokenOfsection);
- sectionInfoList.push(SectionInfo(0,0,addrs));
- _mintSectionPosition = sectionInfoList.length - 1;
- for (uint256 i = 0; i < numTokenOfsection; i++) {
- address token = _collateral[i];
- require(token != address(0), "_SetSectionInfo: token contract address invalid.");
- uint256 weight = _weight[i] * (10 ** 18);
- require(weight > 0, "_SetSectionInfo: weight must greater than 0.");
- sectionInfoList[_mintSectionPosition].cw[token] = weight;
- sectionInfoList[_mintSectionPosition].collateralAddress[i] = token;
- }
- emit UpdateTokens(sectionInfoList[_mintSectionPosition].collateralAddress, _weight);
- }
- function setSectionInfo(address[] memory _collateral, uint256[] memory _weight) public auth {
- _setSectionInfo(_collateral, _weight);
- emit UpdateTokens(sectionInfoList[_mintSectionPosition].collateralAddress, _weight);
- }
- function sectionToken(uint256 _position) public view returns (address[] memory) {
- return sectionInfoList[_position].collateralAddress;
- }
- function collateralWeight(uint256 _position, address _collateral) public view returns (uint256) {
- return sectionInfoList[_position].cw[_collateral];
- }
- /**
- @dev set the number of minted in structure of SectionInfo
- @param _newMinted number of minted
- */
- function setSectionMinted(uint256 _newMinted) public auth {
- require(_newMinted >= sectionInfoList[_mintSectionPosition].minted, "SetSectionMinted: minted number not right.");
- sectionInfoList[_mintSectionPosition].minted = _newMinted;
- }
- /**
- @dev the number of minted in structure of SectionInfo
- */
- function sectionMinted(uint256 _position) public view returns (uint256) {
- return sectionInfoList[_position].minted;
- }
- /**
- @dev set the number of burned in structure of SectionInfo
- @param _newBurned number of burned
- */
- function setSectionBurned(uint256 _newBurned) public auth {
- require(_newBurned <= sectionInfoList[_burnSectionPosition].minted, "SetSectionBurned: burned number not right.");
- sectionInfoList[_burnSectionPosition].burned = _newBurned;
- }
- /**
- @dev the number of burned in structure of SectionInfo
- */
- function sectionBurned() public view returns (uint256) {
- return sectionInfoList[_burnSectionPosition].burned;
- }
- /**
- @dev clear collateral token info in structure of SectionInfo
- */
- function burnSectionMoveon() public auth {
- uint _p = _burnSectionPosition;
- require(sectionInfoList[_p].minted == sectionInfoList[_p].burned, "BurnSectionMoveon: not ready for move on.");
- _burnSectionPosition += 1;
- }
- function tokenPool(address token) public view returns (uint256) {
- return collateralQueue[token].amount;
- }
- function setTokenPool(address token, uint256 amount) public auth {
- collateralQueue[token].amount = amount;
- }
- function balanceOfTokens(address token, address owner) public view returns (uint256) {
- return collateralQueue[token].balanceOf[owner];
- }
- function setBalanceOfTokens(address token, address owner, uint256 amount) public auth {
- collateralQueue[token].balanceOf[owner] = amount;
- }
- function headOfQueue(address token) public view returns (address, uint, uint) {
- ColQueue.ColItem storage _head = collateralQueue[token].data[collateralQueue[token].head];
- return (_head.depositor, _head.total, _head.balance);
- }
- function pushCollateralQueue(address token, address depositor, uint256 total) public auth {
- if(collateralQueue[token].seed == 0) {
- collateralQueue[token] = ColQueue.ColList(0, 0, 0, 0, 0);
- }
- ColQueue.push(collateralQueue[token], depositor, total);
- }
- event idxLog(uint idx, uint pre, uint nex);
- function loopIdxF(address token) public {
- uint idx = ColQueue.getHeadIdx(collateralQueue[token]);
- uint size = collateralQueue[token].size;
- uint prev = ColQueue.getPrevbyIdx(collateralQueue[token], idx);
- uint next = ColQueue.getNextbyIdx(collateralQueue[token], idx);
- int i = 1;
- emit idxLog(idx, prev, next);
- while (i++ < int(size)) {
- idx = ColQueue.getNextbyIdx(collateralQueue[token], idx);
- prev = ColQueue.getPrevbyIdx(collateralQueue[token], idx);
- next = ColQueue.getNextbyIdx(collateralQueue[token], idx);
- emit idxLog(idx, prev, next);
- }
- }
- function loopIdxB(address token) public {
- uint idx = ColQueue.getLastIdx(collateralQueue[token]);
- uint size = collateralQueue[token].size;
- uint prev = ColQueue.getPrevbyIdx(collateralQueue[token], idx);
- uint next = ColQueue.getNextbyIdx(collateralQueue[token], idx);
- int i = 1;
- emit idxLog(idx, prev, next);
- while (i++ < int(size)) {
- idx = ColQueue.getPrevbyIdx(collateralQueue[token], idx);
- prev = ColQueue.getPrevbyIdx(collateralQueue[token], idx);
- next = ColQueue.getNextbyIdx(collateralQueue[token], idx);
- emit idxLog(idx, prev, next);
- }
- }
- function popCollateralQueue(address token, uint256 length) public auth {
- for(uint i = 0; i < length; i++) {
- ColQueue.pop(collateralQueue[token]);
- }
- }
- function takeOffCollateralQueue(address token, address depositor, uint256 amount) public auth {
- ColQueue.withdraw(collateralQueue[token], depositor, amount);
- }
- function getCollateralQueue(address token, uint consume) public view returns (uint, address[] memory, uint256[] memory) {
- return ColQueue.getCollateralQueue(collateralQueue[token], consume);
- }
- function updateCollateralQueue(address token, address depositor, uint256 balance) public auth {
- uint ihead = collateralQueue[token].head;
- require(depositor == collateralQueue[token].data[ihead].depositor, "UpdateCollateralQueue: Not the same depositor");
- ColQueue.updateBalance(collateralQueue[token], ihead, balance);
- }
- function setTotalMinted(uint256 _amount) public auth {
- _totalMinted = _amount;
- }
- function setTotalBurned(uint256 _amount) public auth {
- _totalBurned = _amount;
- }
- function getCollateralQueueLength(address _token) public view returns (uint256) {
- return collateralQueue[_token].size;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement