Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- pragma solidity ^0.4.18;
- contract Collateral {
- address public owner;
- string public description;
- string public title;
- string public url;
- uint public estimatedValue;
- uint public collateralizedDate;
- uint public liquidationPrice;
- uint public liquidationDate;
- event Liquidated(uint price);
- Ledger ledger;
- function Collateral(address _owner, string _description, string _title, string _url, uint _estimatedValue) public {
- owner = _owner;
- description = _description;
- title = _title;
- url = _url;
- estimatedValue = _estimatedValue;
- collateralizedDate = now;
- }
- function setLedger(Ledger _ledger) public {
- assert(msg.sender == owner);
- ledger = _ledger;
- }
- function liquidate(uint price) public {
- assert(msg.sender == owner);
- price = price;
- liquidationPrice = price;
- liquidationDate = now;
- Liquidated(price);
- ledger.distribute(price);
- }
- }
- contract Ledger {
- struct LedgerEntry {
- CollateralizedDebtObligation creditor;
- uint payment;
- uint date;
- }
- address owner;
- mapping(address => Collateral) public collateral;
- mapping(address => CollateralizedDebtObligation) creditors;
- address[] creditorMap;
- address[] collateralMap;
- LedgerEntry[] public ledger;
- function Ledger(address _owner) public {
- owner = _owner;
- }
- function addCollateral(Collateral _collateral) public {
- assert(msg.sender == owner);
- collateral[address(_collateral)] = _collateral;
- _collateral.setLedger(this);
- collateralMap.push(address(_collateral));
- }
- function distribute(uint payment) public {
- assert(msg.sender == owner);
- uint totalShares = 0;
- for (uint i = 0; i < creditorMap.length; i++) {
- totalShares += creditors[creditorMap[i]].loan();
- }
- for (uint j = 0; j < creditorMap.length; j++) {
- CollateralizedDebtObligation cdo = creditors[creditorMap[i]];
- uint dist = (cdo.loan()*payment)/totalShares;
- address(cdo).transfer(dist);
- ledger.push(LedgerEntry({
- creditor: cdo,
- payment: dist,
- date: now
- }));
- }
- }
- }
- contract BidWrapper {
- Bid public bid;
- uint public activeCoins;
- function BidWrapper(Bid _bid) public {
- bid = _bid;
- activeCoins = bid.activeCoins();
- }
- function setActiveCoin(uint coin) public {
- activeCoins = coin;
- }
- }
- contract DutchAuctionBidExecutor {
- BidWrapper[] activeBids;
- BidWrapper[] affectedBids;
- DutchCollateralizedAuction auction;
- uint maxCoins;
- function DutchAuctionBidExecutor(Bid[] _activeBids, uint _maxCoins, DutchCollateralizedAuction _auction) public {
- maxCoins = _maxCoins;
- auction = _auction;
- for (uint i = 0; i < _activeBids.length; i++) {
- activeBids.push(new BidWrapper(_activeBids[i]));
- }
- }
- function totalCoinsAvailable() private returns (uint) {
- uint totalCoinAvailable = maxCoins;
- for (uint n = 0; n < activeBids.length; n++) {
- totalCoinAvailable -= activeBids[n].activeCoins();
- }
- return totalCoinAvailable;
- }
- function getHighestAffectedBid(uint _maxCoins, uint _bid) private returns (uint) {
- uint i = 0;
- uint totalAllocated = 0;
- do {
- totalAllocated = activeBids[i].activeCoins()*activeBids[i].bid().bid();
- i++;
- }
- while (i < activeBids.length && totalAllocated < _maxCoins * _bid);
- return i;
- }
- function executeBidRequest(Bid newBid) public returns (uint) {
- assert(msg.sender == address(auction));
- uint totalAllocated = 0;
- uint totalCoins = 0;
- uint totalCoinAvailable = totalCoinsAvailable();
- bool isPartial = false;
- if (totalCoinAvailable == 0) {
- uint i = getHighestAffectedBid(newBid.maxCoins(), newBid.bid());
- uint j = 0;
- while (j < i && (activeBids[0].activeCoins()*activeBids[0].bid().bid()) < newBid.maxCoins() * newBid.bid() - totalAllocated) {
- BidWrapper wbid = activeBids[0];
- totalAllocated += wbid.activeCoins() * newBid.bid();
- totalCoins += wbid.activeCoins();
- wbid.setActiveCoin(0);
- affectedBids.push(wbid);
- delete activeBids[0];
- j++;
- }
- isPartial = totalAllocated < newBid.maxCoins()*newBid.bid() && activeBids.length > 0;
- if (isPartial) {
- BidWrapper kbid = activeBids[0];
- uint k = kbid.activeCoins();
- while (k <= kbid.bid().minCoins() && k * kbid.bid().bid() < newBid.maxCoins() * newBid.bid() - totalAllocated) {
- k--;
- }
- totalCoins += kbid.activeCoins() - k;
- totalAllocated += (kbid.activeCoins() - k) * newBid.bid();
- kbid.setActiveCoin(k);
- affectedBids.push(kbid);
- }
- } else {
- if (totalCoinAvailable > newBid.maxCoins()) {
- totalCoins = newBid.maxCoins();
- } else {
- totalCoins = totalCoinAvailable;
- }
- }
- if (totalCoins < newBid.minCoins()) {
- assert(false);
- }
- BidWrapper wrapNew = new BidWrapper(newBid);
- auction.adjustActiveCoins(wrapNew);
- allocateBid(wrapNew, totalAllocated, isPartial);
- for (uint m = 0; m < affectedBids.length; m++) {
- auction.adjustActiveCoins(affectedBids[m]);
- }
- return activeBids.length;
- }
- function getActiveBid(uint index) public returns (Bid) {
- assert(msg.sender == address(auction));
- assert(index < activeBids.length);
- return activeBids[index].bid();
- }
- function allocateBid(BidWrapper newBid, uint totalAllocated, bool isPartial) private {
- if (activeBids.length > 0) {
- activeBids.push(activeBids[activeBids.length - 1]);
- uint i = 0;
- if (isPartial) {
- i = 1;
- }
- uint len = activeBids.length;
- for (i; i < len; i++) {
- activeBids[i + 1] = activeBids[i];
- }
- if (isPartial) {
- activeBids[1] = newBid;
- } else {
- activeBids[0] = newBid;
- }
- }
- else
- activeBids.push(newBid);
- if (totalAllocated < newBid.bid().maxCoins()*newBid.bid().bid())
- msg.sender.transfer(newBid.bid().maxCoins()*newBid.bid().bid() - totalAllocated);
- }
- function destroy() public {
- assert(msg.sender == address(auction));
- selfdestruct(auction);
- }
- }
- contract DutchCollateralizedAuction {
- address public payee;
- uint public startDate;
- uint public endDate;
- uint public maxCoins;
- Collateral[] public colletaral;
- Bid[] activeBids;
- mapping(address => Bid) bids;
- address[] bidMap;
- function DutchCollateralizedAuction(address _payee, uint _auctionLength) public {
- payee = _payee;
- startDate = now;
- endDate = startDate + _auctionLength * 1 days;
- }
- function adjustActiveCoins(BidWrapper bid) public {
- bid.bid().adjustActiveCoins(bid.activeCoins());
- }
- function placeBid(uint _maxCoins, uint _minCoins, uint _bid) public payable returns (Bid) {
- assert(_maxCoins >= _minCoins);
- assert(msg.value == _maxCoins * _bid);
- assert(bids[msg.sender] != address(0));
- Bid newBid = new Bid(_maxCoins, _minCoins, _bid, this);
- DutchAuctionBidExecutor exec = new DutchAuctionBidExecutor(activeBids, maxCoins, this);
- uint newActiveBids = exec.executeBidRequest(newBid);
- if (newBid.activeCoins() > 0) {
- delete activeBids;
- for (uint i = 0; i < newActiveBids; i++) {
- activeBids.push(exec.getActiveBid(i));
- }
- bids[msg.sender] = newBid;
- bidMap.push(msg.sender);
- return newBid;
- } else {
- assert(false);
- }
- }
- }
- contract Bid {
- uint public maxCoins;
- uint public minCoins;
- uint public bid;
- uint public activeCoins;
- uint public finalizedCoins;
- DutchCollateralizedAuction public auction;
- event ActiveCoinsChanged(uint activeCoins);
- event CoinsFinalized(uint finalizedCoins);
- function Bid(uint _maxCoins, uint _minCoins, uint _bid, DutchCollateralizedAuction _auction) public payable {
- maxCoins = _maxCoins;
- minCoins = _minCoins;
- bid = _bid;
- auction = _auction;
- }
- function adjustActiveCoins(uint coins) public {
- assert(msg.sender == address(auction));
- finalizedCoins = coins;
- ActiveCoinsChanged(coins);
- }
- }
- contract CollateralizedDebtObligation {
- address public debtor;
- uint public loan;
- function CollateralizedDebtObligation(address _debtor, uint _loan) public payable {
- debtor = _debtor;
- _loan = loan;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement