Augur Constant Product
contract AugurConstantProduct { | |
IAugurMarket market = 0x0;// TODO | |
IErc20 dai = 0x0; // TODO | |
uint256 numTicks; | |
function addLiquidity(uint256 amountInAttodai) { | |
uint256 poolBalanceBefore = poolBalance(); | |
dai.transferFrom(msg.sender, this, amountInAttodai); | |
market.buyCompleteSets(amountInAttodai); | |
uint256 poolBalanceAfter = poolBalance(); | |
mint(msg.sender, (poolBalanceAfter - poolBalanceBefore) / poolBalanceAfter); | |
} | |
function enterPosition(uint256 amountInAttodai, bool buyYes) { | |
dai.transferFrom(msg.sender, this, amountInAttodai); | |
uint256 numInvalidAttoshares = amountInAttodai / numTicks; | |
// give invalid shares equal to DAI deposited as invalid insurance | |
market.transfer(INVALID, msg.sender, numInvalidAttoshares); | |
// technically, the pool is selling complete sets to the caller so we treat the pools balance as though it is lower than it actually is for calculations since numInvalidAttoshares of YES and NO are technically owned by the user at this point | |
uint256 yesBalance = market.balanceOf(YES, this) - numInvalidAttoshares; | |
uint256 noBalance = market.balanceOf(NO, this) - numInvalidAttoshares; | |
uint256 constantProduct = yesBalance * noBalance | |
// calculate and transfer an appropriate amount of YES or NO to the user (depending on which they bought) | |
if (buyYes) { | |
market.transfer(YES, msg.sender, yesBalance - constantProduct / (noBalance + numInvalidAttoshares)); | |
} else { | |
market.transfer(NO, msg.sender, noBalance - constantProduct / (yesBalance + numInvalidAttoshares)) | |
} | |
} | |
function exitPosition(uint256 numInvalidAttoshares, bool sellYes) { | |
market.transferFrom(INVAILD, msg.sender, this, numInvalidAttoshares); | |
uint256 yesBalance = market.balanceOf(YES, this); | |
uint256 noBalance = market.balanceOf(NO, this); | |
uint256 constantProduct = yesBalance * noBalance | |
if (sellYes) { | |
uint256 noDesired = numInvalidAttoshares | |
uint256 yesRequiredToSwapToNoDesired = constantProduct / (noBalance - noDesired) - yesBalance; | |
uint256 totalYesRequired = yesRequiredToSwapToNoDesired + numInvalidAttoshares; | |
market.transferFrom(YES, msg.sender, this, totalYesRequired); | |
} else { | |
uint256 yesDesired = numInvalidAttoshares | |
uint256 noRequiredToSwapToYesDesired = constantProduct / (yesBalance - yesDesired) - noBalance; | |
uint256 totalNoRequired = noRequiredToSwapToYesDesired + numInvalidAttoshares; | |
market.transferFrom(NO, msg.sender, this, totalNoRequired); | |
} | |
// TODO: support selling complete sets if the pool is short on DAI | |
dai.transfer(msg.sender, numInvalidAttoshares * numTicks); | |
} | |
function swap(uint256 numAttoshares, bool buyYes) { | |
uint256 yesBalance = market.balanceOf(YES, this); | |
uint256 noBalance = market.balanceOf(NO, this); | |
uint256 constantProduct = yesBalance * noBalance | |
if (buyYes) { | |
market.transferFrom(YES, msg.sender, this, numAttoshares); | |
market.transfer(NO, msg.sender, noBalance - constantProduct / (yesBalance + numAttoshares)); | |
} else { | |
market.transferFrom(NO, msg.sender, this, numAttoshares); | |
market.transfer(YES, msg.sender, yesBalance - constantProduct / (noBalance + numAttoshares)); | |
} | |
} | |
function poolBalance() view returns (uint256) { | |
uint256 numInvalid = market.balanceOf(INVALID, this); | |
uint256 attodaiBalance = dai.balanceOf(this); | |
uint256 invalidInAttodai = numInvalid / numTicks; | |
return attodaiBalance + invalidInAttodai | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment