Created
March 4, 2018 12:21
-
-
Save jlind0/bace0517c61da5ea6b682df995d48294 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.4.18; | |
import "./QuickSort.sol"; | |
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); | |
CollateralizedLoanLedger 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(CollateralizedLoanLedger _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 CollateralizedLoanLedger { | |
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 CollateralizedLoanLedger(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 DutchCollateralizedLoanAuction { | |
address public payee; | |
uint public startDate; | |
uint public endDate; | |
uint public maxCoins; | |
Collateral[] public colletaral; | |
Bid[] activeBids; | |
function DutchCollateralizedLoanAuction(address _payee, uint _auctionLength) public { | |
payee = _payee; | |
startDate = now; | |
endDate = startDate + _auctionLength * 1 days; | |
} | |
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(); | |
i++; | |
} | |
while (i < activeBids.length && totalAllocated < _maxCoins * _bid); | |
return i; | |
} | |
function executeBidRequest(Bid newBid, uint _maxCoins, uint _bid) private returns (uint) { | |
uint i = getHighestAffectedBid(_maxCoins, _bid); | |
uint j = 0; | |
uint totalAllocated = 0; | |
uint totalCoins = 0; | |
while (j < i && (activeBids[0].activeCoins()*activeBids[0].bid()) < _maxCoins * _bid - totalAllocated) { | |
Bid bid = activeBids[0]; | |
totalAllocated += bid.activeCoins() * _bid; | |
totalCoins += bid.activeCoins(); | |
bid.adjustActiveCoins(0); | |
delete activeBids[0]; | |
j++; | |
} | |
bool isPartial = totalAllocated < _maxCoins*_bid && activeBids.length > 0; | |
if (isPartial) { | |
Bid kbid = activeBids[0]; | |
uint k = kbid.activeCoins(); | |
while (k <= kbid.minCoins() && k * kbid.bid() < _maxCoins * _bid - totalAllocated) { | |
k--; | |
} | |
totalCoins += kbid.activeCoins() - k; | |
totalAllocated += kbid.activeCoins() - k; | |
bid.adjustActiveCoins(k); | |
} | |
allocateBid(newBid, totalAllocated, isPartial, _maxCoins, _bid); | |
return totalAllocated; | |
} | |
function allocateBid(Bid newBid, uint totalAllocated, bool isPartial, uint _maxCoins, uint _bid) 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 < _maxCoins*_bid) | |
msg.sender.transfer(_maxCoins*_bid - totalAllocated); | |
} | |
function placeBid(uint _maxCoins, uint _minCoins, uint _bid) public payable returns (Bid) { | |
assert(msg.value == _maxCoins * _bid); | |
Bid newBid = new Bid(_maxCoins, _minCoins, _bid, this); | |
uint totalAllocated = executeBidRequest(newBid, _maxCoins, _bid); | |
if (totalAllocated > 0) { | |
return newBid; | |
} else { | |
assert(false); | |
} | |
} | |
} | |
contract Bid { | |
uint public maxCoins; | |
uint public minCoins; | |
uint public bid; | |
uint public activeCoins; | |
uint public finalizedCoins; | |
DutchCollateralizedLoanAuction public auction; | |
event ActiveCoinsChanged(uint activeCoins); | |
event CoinsFinalized(uint finalizedCoins); | |
function Bid(uint _maxCoins, uint _minCoins, uint _bid, DutchCollateralizedLoanAuction _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; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment